blob: 614a6061aa65df4970d99d06f9c2e5313003e37b [file] [log] [blame]
Rick Dean536ba022009-07-24 23:57:27 -05001#include <Python.h>
2#define crypto_MODULE
3#include "crypto.h"
4
5
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -04006static X509_REVOKED * X509_REVOKED_dup(X509_REVOKED *orig) {
Rick Dean536ba022009-07-24 23:57:27 -05007 X509_REVOKED *dupe = NULL;
8
9 dupe = X509_REVOKED_new();
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040010 if (dupe == NULL) {
Rick Dean536ba022009-07-24 23:57:27 -050011 return NULL;
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040012 }
13 if (orig->serialNumber) {
Rick Dean536ba022009-07-24 23:57:27 -050014 dupe->serialNumber = M_ASN1_INTEGER_dup(orig->serialNumber);
15 }
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040016 if (orig->revocationDate) {
Rick Dean536ba022009-07-24 23:57:27 -050017 dupe->revocationDate = M_ASN1_INTEGER_dup(orig->revocationDate);
18 }
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040019 if (orig->extensions) {
Rick Dean536ba022009-07-24 23:57:27 -050020 STACK_OF(X509_EXTENSION) *sk = NULL;
21 X509_EXTENSION * ext;
22 int j;
23
24 sk = sk_X509_EXTENSION_new_null();
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040025 for (j = 0; j < sk_X509_EXTENSION_num(orig->extensions); j++) {
26 ext = sk_X509_EXTENSION_value(orig->extensions, j);
27 ext = X509_EXTENSION_dup(ext);
28 sk_X509_EXTENSION_push(sk, ext);
Rick Dean536ba022009-07-24 23:57:27 -050029 }
30 dupe->extensions = sk;
31 }
32 dupe->sequence = orig->sequence;
33 return dupe;
34}
35
36static char crypto_CRL_get_revoked_doc[] = "\n\
37Return revoked portion of the CRL structure (by value\n\
38not reference).\n\
39\n\
Jonathan Ballet78b92a22011-07-16 08:07:26 +090040:return: A tuple of Revoked objects.\n\
Rick Dean536ba022009-07-24 23:57:27 -050041";
42static PyObject *
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040043crypto_CRL_get_revoked(crypto_CRLObj *self, PyObject *args) {
Rick Dean536ba022009-07-24 23:57:27 -050044 int j, num_rev;
45 X509_REVOKED *r = NULL;
46 PyObject *obj = NULL, *rev_obj;
47
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040048 if (!PyArg_ParseTuple(args, ":get_revoked")) {
Rick Dean536ba022009-07-24 23:57:27 -050049 return NULL;
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040050 }
Rick Dean536ba022009-07-24 23:57:27 -050051
52 num_rev = sk_X509_REVOKED_num(self->crl->crl->revoked);
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040053 if (num_rev < 0) {
Rick Dean536ba022009-07-24 23:57:27 -050054 Py_INCREF(Py_None);
55 return Py_None;
56 }
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040057 if ((obj = PyTuple_New(num_rev)) == NULL) {
Rick Dean536ba022009-07-24 23:57:27 -050058 return NULL;
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040059 }
Rick Dean536ba022009-07-24 23:57:27 -050060
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040061 for (j = 0; j < num_rev; j++) {
62 r = sk_X509_REVOKED_value(self->crl->crl->revoked, j);
63 r = X509_REVOKED_dup(r);
64 if (r == NULL ) {
65 goto error;
66 }
67 rev_obj = (PyObject *) crypto_Revoked_New(r);
68 if (rev_obj == NULL) {
69 goto error;
70 }
71 r = NULL; /* it's now owned by rev_obj */
72 PyTuple_SET_ITEM(obj, j, rev_obj);
Rick Dean536ba022009-07-24 23:57:27 -050073 }
74 return obj;
75
76 error:
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040077 if (r) {
78 X509_REVOKED_free(r);
79 }
Rick Dean536ba022009-07-24 23:57:27 -050080 Py_XDECREF(obj);
81 return NULL;
82}
83
84static char crypto_CRL_add_revoked_doc[] = "\n\
85Add a revoked (by value not reference) to the CRL structure\n\
86\n\
Jonathan Ballet78b92a22011-07-16 08:07:26 +090087:param cert: The new revoked.\n\
Jonathan Ballet648875f2011-07-16 14:14:58 +090088:type cert: :class:`X509`\n\
Jonathan Ballet78b92a22011-07-16 08:07:26 +090089:return: None\n\
Rick Dean536ba022009-07-24 23:57:27 -050090";
91static PyObject *
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040092crypto_CRL_add_revoked(crypto_CRLObj *self, PyObject *args, PyObject *keywds) {
Rick Dean536ba022009-07-24 23:57:27 -050093 crypto_RevokedObj * rev_obj = NULL;
94 static char *kwlist[] = {"revoked", NULL};
95 X509_REVOKED * dup;
96
97 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!:add_revoked",
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040098 kwlist, &crypto_Revoked_Type, &rev_obj)) {
Rick Dean536ba022009-07-24 23:57:27 -050099 return NULL;
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400100 }
Rick Dean536ba022009-07-24 23:57:27 -0500101
102 dup = X509_REVOKED_dup( rev_obj->revoked );
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400103 if (dup == NULL) {
Rick Dean536ba022009-07-24 23:57:27 -0500104 return NULL;
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400105 }
Rick Dean536ba022009-07-24 23:57:27 -0500106 X509_CRL_add0_revoked(self->crl, dup);
107
108 Py_INCREF(Py_None);
109 return Py_None;
110}
111
112static char crypto_CRL_export_doc[] = "\n\
Jean-Paul Calderone58887472010-01-30 13:12:35 -0500113export(cert, key[, type[, days]]) -> export a CRL as a string\n\
Rick Dean536ba022009-07-24 23:57:27 -0500114\n\
Jonathan Ballet78b92a22011-07-16 08:07:26 +0900115:param cert: Used to sign CRL.\n\
Jonathan Ballet648875f2011-07-16 14:14:58 +0900116:type cert: :class:`X509`\n\
Jonathan Ballet78b92a22011-07-16 08:07:26 +0900117:param key: Used to sign CRL.\n\
Jonathan Ballet648875f2011-07-16 14:14:58 +0900118:type key: :class:`PKey`\n\
119:param type: The export format, either :py:data:`FILETYPE_PEM`, :py:data:`FILETYPE_ASN1`, or :py:data:`FILETYPE_TEXT`.\n\
Jonathan Ballet78b92a22011-07-16 08:07:26 +0900120:param days: The number of days until the next update of this CRL.\n\
Jonathan Ballet648875f2011-07-16 14:14:58 +0900121:type days: :py:data:`int`\n\
122:return: :py:data:`str`\n\
Rick Dean536ba022009-07-24 23:57:27 -0500123";
124static PyObject *
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400125crypto_CRL_export(crypto_CRLObj *self, PyObject *args, PyObject *keywds) {
126 int ret, buf_len, type = X509_FILETYPE_PEM, days = 100;
127 char *temp;
128 BIO *bio;
129 PyObject *buffer;
130 crypto_PKeyObj *key;
131 ASN1_TIME *tmptm;
132 crypto_X509Obj *x509;
133 static char *kwlist[] = {"cert", "key", "type", "days", NULL};
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -0400134
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400135 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!O!|ii:dump_crl", kwlist,
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -0400136 &crypto_X509_Type, &x509,
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400137 &crypto_PKey_Type, &key, &type, &days)) {
138 return NULL;
139 }
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -0400140
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400141 bio = BIO_new(BIO_s_mem());
142 tmptm = ASN1_TIME_new();
143 if (!tmptm) {
144 return 0;
145 }
146 X509_gmtime_adj(tmptm,0);
147 X509_CRL_set_lastUpdate(self->crl, tmptm);
148 X509_gmtime_adj(tmptm,days*24*60*60);
149 X509_CRL_set_nextUpdate(self->crl, tmptm);
150 ASN1_TIME_free(tmptm);
151 X509_CRL_set_issuer_name(self->crl, X509_get_subject_name(x509->x509));
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -0400152
153 if (!X509_CRL_sign(self->crl, key->pkey, EVP_md5())) {
154 exception_from_error_queue(crypto_Error);
155 BIO_free(bio);
156 return NULL;
157 }
158
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400159 switch (type) {
160 case X509_FILETYPE_PEM:
161 ret = PEM_write_bio_X509_CRL(bio, self->crl);
162 break;
Rick Dean536ba022009-07-24 23:57:27 -0500163
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400164 case X509_FILETYPE_ASN1:
165 ret = (int) i2d_X509_CRL_bio(bio, self->crl);
166 break;
Rick Dean536ba022009-07-24 23:57:27 -0500167
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400168 case X509_FILETYPE_TEXT:
169 ret = X509_CRL_print(bio, self->crl);
170 break;
Rick Dean536ba022009-07-24 23:57:27 -0500171
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400172 default:
173 PyErr_SetString(
174 PyExc_ValueError,
175 "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or FILETYPE_TEXT");
Rick Dean536ba022009-07-24 23:57:27 -0500176 return NULL;
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400177 }
178 if (!ret) {
179 exception_from_error_queue(crypto_Error);
180 BIO_free(bio);
181 return NULL;
182 }
183 buf_len = BIO_get_mem_data(bio, &temp);
Jean-Paul Calderone2f6c66f2010-08-11 19:53:43 -0400184 buffer = PyBytes_FromStringAndSize(temp, buf_len);
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400185 BIO_free(bio);
186 return buffer;
Rick Dean536ba022009-07-24 23:57:27 -0500187}
188
189crypto_CRLObj *
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400190crypto_CRL_New(X509_CRL *crl) {
Rick Dean536ba022009-07-24 23:57:27 -0500191 crypto_CRLObj *self;
192
193 self = PyObject_New(crypto_CRLObj, &crypto_CRL_Type);
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400194 if (self == NULL) {
195 return NULL;
196 }
Rick Dean536ba022009-07-24 23:57:27 -0500197 self->crl = crl;
198 return self;
199}
200
201/*
202 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
203 * { 'name', (PyCFunction)crypto_CRL_name, METH_VARARGS, crypto_CRL_name_doc }
204 * for convenience
205 */
206#define ADD_METHOD(name) \
207 { #name, (PyCFunction)crypto_CRL_##name, METH_VARARGS, crypto_CRL_##name##_doc }
208#define ADD_KW_METHOD(name) \
209 { #name, (PyCFunction)crypto_CRL_##name, METH_VARARGS | METH_KEYWORDS, crypto_CRL_##name##_doc }
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400210static PyMethodDef crypto_CRL_methods[] = {
Rick Dean536ba022009-07-24 23:57:27 -0500211 ADD_KW_METHOD(add_revoked),
212 ADD_METHOD(get_revoked),
213 ADD_KW_METHOD(export),
214 { NULL, NULL }
215};
216#undef ADD_METHOD
217
218
Rick Dean536ba022009-07-24 23:57:27 -0500219static void
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400220crypto_CRL_dealloc(crypto_CRLObj *self) {
Rick Dean536ba022009-07-24 23:57:27 -0500221 X509_CRL_free(self->crl);
222 self->crl = NULL;
223
224 PyObject_Del(self);
225}
226
227static char crypto_CRL_doc[] = "\n\
228CRL() -> CRL instance\n\
229\n\
230Create a new empty CRL object.\n\
231\n\
Jonathan Ballet78b92a22011-07-16 08:07:26 +0900232:returns: The CRL object\n\
Rick Dean536ba022009-07-24 23:57:27 -0500233";
234
235static PyObject* crypto_CRL_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) {
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400236 if (!PyArg_ParseTuple(args, ":CRL")) {
237 return NULL;
238 }
239
240 return (PyObject *)crypto_CRL_New(X509_CRL_new());
Rick Dean536ba022009-07-24 23:57:27 -0500241}
242
243PyTypeObject crypto_CRL_Type = {
Jean-Paul Calderone3fe7f672010-08-11 23:55:10 -0400244 PyOpenSSL_HEAD_INIT(&PyType_Type, 0)
Rick Dean536ba022009-07-24 23:57:27 -0500245 "CRL",
246 sizeof(crypto_CRLObj),
247 0,
248 (destructor)crypto_CRL_dealloc,
249 NULL, /* print */
Jean-Paul Calderone2f6c66f2010-08-11 19:53:43 -0400250 NULL, /* getattr */
Rick Dean536ba022009-07-24 23:57:27 -0500251 NULL, /* setattr */
252 NULL, /* compare */
253 NULL, /* repr */
254 NULL, /* as_number */
255 NULL, /* as_sequence */
256 NULL, /* as_mapping */
257 NULL, /* hash */
258 NULL, /* call */
259 NULL, /* str */
260 NULL, /* getattro */
261 NULL, /* setattro */
262 NULL, /* as_buffer */
263 Py_TPFLAGS_DEFAULT,
264 crypto_CRL_doc, /* doc */
265 NULL, /* traverse */
266 NULL, /* clear */
267 NULL, /* tp_richcompare */
268 0, /* tp_weaklistoffset */
269 NULL, /* tp_iter */
270 NULL, /* tp_iternext */
271 crypto_CRL_methods, /* tp_methods */
272 NULL, /* tp_members */
273 NULL, /* tp_getset */
274 NULL, /* tp_base */
275 NULL, /* tp_dict */
276 NULL, /* tp_descr_get */
277 NULL, /* tp_descr_set */
278 0, /* tp_dictoffset */
279 NULL, /* tp_init */
280 NULL, /* tp_alloc */
281 crypto_CRL_new, /* tp_new */
282};
283
284int init_crypto_crl(PyObject *module) {
Jean-Paul Calderoneaed23582011-03-12 22:45:02 -0500285 if (PyType_Ready(&crypto_CRL_Type) < 0) {
286 return 0;
287 }
Rick Dean536ba022009-07-24 23:57:27 -0500288
Jean-Paul Calderoneaed23582011-03-12 22:45:02 -0500289 /* PyModule_AddObject steals a reference.
290 */
291 Py_INCREF((PyObject *)&crypto_CRL_Type);
292 if (PyModule_AddObject(module, "CRL", (PyObject *)&crypto_CRL_Type) != 0) {
293 return 0;
294 }
295 return 1;
Rick Dean536ba022009-07-24 23:57:27 -0500296}