blob: 3f56d8350feea380c8f37636e240823cd240796f [file] [log] [blame]
Rick Dean536ba022009-07-24 23:57:27 -05001#include <Python.h>
2#define crypto_MODULE
3#include "crypto.h"
4
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -04005static X509_REVOKED * X509_REVOKED_dup(X509_REVOKED *orig) {
Rick Dean536ba022009-07-24 23:57:27 -05006 X509_REVOKED *dupe = NULL;
7
8 dupe = X509_REVOKED_new();
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -04009 if (dupe == NULL) {
Rick Dean536ba022009-07-24 23:57:27 -050010 return NULL;
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040011 }
12 if (orig->serialNumber) {
Rick Dean536ba022009-07-24 23:57:27 -050013 dupe->serialNumber = M_ASN1_INTEGER_dup(orig->serialNumber);
14 }
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040015 if (orig->revocationDate) {
Rick Dean536ba022009-07-24 23:57:27 -050016 dupe->revocationDate = M_ASN1_INTEGER_dup(orig->revocationDate);
17 }
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040018 if (orig->extensions) {
Rick Dean536ba022009-07-24 23:57:27 -050019 STACK_OF(X509_EXTENSION) *sk = NULL;
20 X509_EXTENSION * ext;
21 int j;
22
23 sk = sk_X509_EXTENSION_new_null();
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040024 for (j = 0; j < sk_X509_EXTENSION_num(orig->extensions); j++) {
25 ext = sk_X509_EXTENSION_value(orig->extensions, j);
26 ext = X509_EXTENSION_dup(ext);
27 sk_X509_EXTENSION_push(sk, ext);
Rick Dean536ba022009-07-24 23:57:27 -050028 }
29 dupe->extensions = sk;
30 }
31 dupe->sequence = orig->sequence;
32 return dupe;
33}
34
35static char crypto_CRL_get_revoked_doc[] = "\n\
36Return revoked portion of the CRL structure (by value\n\
37not reference).\n\
38\n\
Jonathan Ballet78b92a22011-07-16 08:07:26 +090039:return: A tuple of Revoked objects.\n\
Rick Dean536ba022009-07-24 23:57:27 -050040";
41static PyObject *
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040042crypto_CRL_get_revoked(crypto_CRLObj *self, PyObject *args) {
Rick Dean536ba022009-07-24 23:57:27 -050043 int j, num_rev;
44 X509_REVOKED *r = NULL;
45 PyObject *obj = NULL, *rev_obj;
46
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040047 if (!PyArg_ParseTuple(args, ":get_revoked")) {
Rick Dean536ba022009-07-24 23:57:27 -050048 return NULL;
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040049 }
Rick Dean536ba022009-07-24 23:57:27 -050050
51 num_rev = sk_X509_REVOKED_num(self->crl->crl->revoked);
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040052 if (num_rev < 0) {
Rick Dean536ba022009-07-24 23:57:27 -050053 Py_INCREF(Py_None);
54 return Py_None;
55 }
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040056 if ((obj = PyTuple_New(num_rev)) == NULL) {
Rick Dean536ba022009-07-24 23:57:27 -050057 return NULL;
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040058 }
Rick Dean536ba022009-07-24 23:57:27 -050059
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040060 for (j = 0; j < num_rev; j++) {
61 r = sk_X509_REVOKED_value(self->crl->crl->revoked, j);
62 r = X509_REVOKED_dup(r);
63 if (r == NULL ) {
64 goto error;
65 }
66 rev_obj = (PyObject *) crypto_Revoked_New(r);
67 if (rev_obj == NULL) {
68 goto error;
69 }
70 r = NULL; /* it's now owned by rev_obj */
71 PyTuple_SET_ITEM(obj, j, rev_obj);
Rick Dean536ba022009-07-24 23:57:27 -050072 }
73 return obj;
74
75 error:
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040076 if (r) {
77 X509_REVOKED_free(r);
78 }
Rick Dean536ba022009-07-24 23:57:27 -050079 Py_XDECREF(obj);
80 return NULL;
81}
82
83static char crypto_CRL_add_revoked_doc[] = "\n\
84Add a revoked (by value not reference) to the CRL structure\n\
85\n\
Jonathan Ballet78b92a22011-07-16 08:07:26 +090086:param cert: The new revoked.\n\
Jonathan Ballet648875f2011-07-16 14:14:58 +090087:type cert: :class:`X509`\n\
Jonathan Ballet78b92a22011-07-16 08:07:26 +090088:return: None\n\
Rick Dean536ba022009-07-24 23:57:27 -050089";
90static PyObject *
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040091crypto_CRL_add_revoked(crypto_CRLObj *self, PyObject *args, PyObject *keywds) {
Rick Dean536ba022009-07-24 23:57:27 -050092 crypto_RevokedObj * rev_obj = NULL;
93 static char *kwlist[] = {"revoked", NULL};
94 X509_REVOKED * dup;
95
96 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!:add_revoked",
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040097 kwlist, &crypto_Revoked_Type, &rev_obj)) {
Rick Dean536ba022009-07-24 23:57:27 -050098 return NULL;
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -040099 }
Rick Dean536ba022009-07-24 23:57:27 -0500100
101 dup = X509_REVOKED_dup( rev_obj->revoked );
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400102 if (dup == NULL) {
Rick Dean536ba022009-07-24 23:57:27 -0500103 return NULL;
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400104 }
Rick Dean536ba022009-07-24 23:57:27 -0500105 X509_CRL_add0_revoked(self->crl, dup);
106
107 Py_INCREF(Py_None);
108 return Py_None;
109}
110
111static char crypto_CRL_export_doc[] = "\n\
Jean-Paul Calderone58887472010-01-30 13:12:35 -0500112export(cert, key[, type[, days]]) -> export a CRL as a string\n\
Rick Dean536ba022009-07-24 23:57:27 -0500113\n\
Jonathan Ballet78b92a22011-07-16 08:07:26 +0900114:param cert: Used to sign CRL.\n\
Jonathan Ballet648875f2011-07-16 14:14:58 +0900115:type cert: :class:`X509`\n\
Jonathan Ballet78b92a22011-07-16 08:07:26 +0900116:param key: Used to sign CRL.\n\
Jonathan Ballet648875f2011-07-16 14:14:58 +0900117:type key: :class:`PKey`\n\
118: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 +0900119:param days: The number of days until the next update of this CRL.\n\
Jonathan Ballet648875f2011-07-16 14:14:58 +0900120:type days: :py:data:`int`\n\
121:return: :py:data:`str`\n\
Rick Dean536ba022009-07-24 23:57:27 -0500122";
123static PyObject *
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400124crypto_CRL_export(crypto_CRLObj *self, PyObject *args, PyObject *keywds) {
125 int ret, buf_len, type = X509_FILETYPE_PEM, days = 100;
126 char *temp;
127 BIO *bio;
128 PyObject *buffer;
129 crypto_PKeyObj *key;
130 ASN1_TIME *tmptm;
131 crypto_X509Obj *x509;
132 static char *kwlist[] = {"cert", "key", "type", "days", NULL};
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -0400133
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400134 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!O!|ii:dump_crl", kwlist,
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -0400135 &crypto_X509_Type, &x509,
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400136 &crypto_PKey_Type, &key, &type, &days)) {
137 return NULL;
138 }
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -0400139
Jean-Paul Calderone7e8dab02012-03-09 15:25:48 -0800140
141#if OPENSSL_VERSION_NUMBER >= 0x01000000L
142 /* Older versions of OpenSSL had no problem with trying to export using an
143 * uninitialized key. Newer versions segfault, instead. We can only check
144 * on the new versions, though, because the old versions don't even have the
145 * field that the segfault is triggered by.
Jean-Paul Calderone3f79cea2012-03-09 14:56:35 -0800146 */
147 if (!key->pkey->ameth) {
148 PyErr_SetString(
149 crypto_Error, "Cannot export with an unitialized key");
150 return NULL;
151 }
Jean-Paul Calderone7e8dab02012-03-09 15:25:48 -0800152#endif
Jean-Paul Calderone3f79cea2012-03-09 14:56:35 -0800153
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400154 bio = BIO_new(BIO_s_mem());
155 tmptm = ASN1_TIME_new();
156 if (!tmptm) {
157 return 0;
158 }
159 X509_gmtime_adj(tmptm,0);
160 X509_CRL_set_lastUpdate(self->crl, tmptm);
161 X509_gmtime_adj(tmptm,days*24*60*60);
162 X509_CRL_set_nextUpdate(self->crl, tmptm);
163 ASN1_TIME_free(tmptm);
164 X509_CRL_set_issuer_name(self->crl, X509_get_subject_name(x509->x509));
Jean-Paul Calderonec7293bc2011-09-13 15:24:38 -0400165
166 if (!X509_CRL_sign(self->crl, key->pkey, EVP_md5())) {
167 exception_from_error_queue(crypto_Error);
168 BIO_free(bio);
169 return NULL;
170 }
171
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400172 switch (type) {
173 case X509_FILETYPE_PEM:
174 ret = PEM_write_bio_X509_CRL(bio, self->crl);
175 break;
Rick Dean536ba022009-07-24 23:57:27 -0500176
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400177 case X509_FILETYPE_ASN1:
178 ret = (int) i2d_X509_CRL_bio(bio, self->crl);
179 break;
Rick Dean536ba022009-07-24 23:57:27 -0500180
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400181 case X509_FILETYPE_TEXT:
182 ret = X509_CRL_print(bio, self->crl);
183 break;
Rick Dean536ba022009-07-24 23:57:27 -0500184
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400185 default:
186 PyErr_SetString(
187 PyExc_ValueError,
188 "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or FILETYPE_TEXT");
Rick Dean536ba022009-07-24 23:57:27 -0500189 return NULL;
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400190 }
191 if (!ret) {
192 exception_from_error_queue(crypto_Error);
193 BIO_free(bio);
194 return NULL;
195 }
196 buf_len = BIO_get_mem_data(bio, &temp);
Jean-Paul Calderone2f6c66f2010-08-11 19:53:43 -0400197 buffer = PyBytes_FromStringAndSize(temp, buf_len);
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400198 BIO_free(bio);
199 return buffer;
Rick Dean536ba022009-07-24 23:57:27 -0500200}
201
202crypto_CRLObj *
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400203crypto_CRL_New(X509_CRL *crl) {
Rick Dean536ba022009-07-24 23:57:27 -0500204 crypto_CRLObj *self;
205
206 self = PyObject_New(crypto_CRLObj, &crypto_CRL_Type);
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400207 if (self == NULL) {
208 return NULL;
209 }
Rick Dean536ba022009-07-24 23:57:27 -0500210 self->crl = crl;
211 return self;
212}
213
214/*
215 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
216 * { 'name', (PyCFunction)crypto_CRL_name, METH_VARARGS, crypto_CRL_name_doc }
217 * for convenience
218 */
219#define ADD_METHOD(name) \
220 { #name, (PyCFunction)crypto_CRL_##name, METH_VARARGS, crypto_CRL_##name##_doc }
221#define ADD_KW_METHOD(name) \
222 { #name, (PyCFunction)crypto_CRL_##name, METH_VARARGS | METH_KEYWORDS, crypto_CRL_##name##_doc }
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400223static PyMethodDef crypto_CRL_methods[] = {
Rick Dean536ba022009-07-24 23:57:27 -0500224 ADD_KW_METHOD(add_revoked),
225 ADD_METHOD(get_revoked),
226 ADD_KW_METHOD(export),
227 { NULL, NULL }
228};
229#undef ADD_METHOD
230
231
Rick Dean536ba022009-07-24 23:57:27 -0500232static void
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400233crypto_CRL_dealloc(crypto_CRLObj *self) {
Rick Dean536ba022009-07-24 23:57:27 -0500234 X509_CRL_free(self->crl);
235 self->crl = NULL;
236
237 PyObject_Del(self);
238}
239
240static char crypto_CRL_doc[] = "\n\
241CRL() -> CRL instance\n\
242\n\
243Create a new empty CRL object.\n\
244\n\
Jonathan Ballet78b92a22011-07-16 08:07:26 +0900245:returns: The CRL object\n\
Rick Dean536ba022009-07-24 23:57:27 -0500246";
247
248static PyObject* crypto_CRL_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) {
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400249 if (!PyArg_ParseTuple(args, ":CRL")) {
250 return NULL;
251 }
252
253 return (PyObject *)crypto_CRL_New(X509_CRL_new());
Rick Dean536ba022009-07-24 23:57:27 -0500254}
255
256PyTypeObject crypto_CRL_Type = {
Jean-Paul Calderone3fe7f672010-08-11 23:55:10 -0400257 PyOpenSSL_HEAD_INIT(&PyType_Type, 0)
Rick Dean536ba022009-07-24 23:57:27 -0500258 "CRL",
259 sizeof(crypto_CRLObj),
260 0,
261 (destructor)crypto_CRL_dealloc,
262 NULL, /* print */
Jean-Paul Calderone2f6c66f2010-08-11 19:53:43 -0400263 NULL, /* getattr */
Rick Dean536ba022009-07-24 23:57:27 -0500264 NULL, /* setattr */
265 NULL, /* compare */
266 NULL, /* repr */
267 NULL, /* as_number */
268 NULL, /* as_sequence */
269 NULL, /* as_mapping */
270 NULL, /* hash */
271 NULL, /* call */
272 NULL, /* str */
273 NULL, /* getattro */
274 NULL, /* setattro */
275 NULL, /* as_buffer */
276 Py_TPFLAGS_DEFAULT,
277 crypto_CRL_doc, /* doc */
278 NULL, /* traverse */
279 NULL, /* clear */
280 NULL, /* tp_richcompare */
281 0, /* tp_weaklistoffset */
282 NULL, /* tp_iter */
283 NULL, /* tp_iternext */
284 crypto_CRL_methods, /* tp_methods */
285 NULL, /* tp_members */
286 NULL, /* tp_getset */
287 NULL, /* tp_base */
288 NULL, /* tp_dict */
289 NULL, /* tp_descr_get */
290 NULL, /* tp_descr_set */
291 0, /* tp_dictoffset */
292 NULL, /* tp_init */
293 NULL, /* tp_alloc */
294 crypto_CRL_new, /* tp_new */
295};
296
297int init_crypto_crl(PyObject *module) {
Jean-Paul Calderoneaed23582011-03-12 22:45:02 -0500298 if (PyType_Ready(&crypto_CRL_Type) < 0) {
299 return 0;
300 }
Rick Dean536ba022009-07-24 23:57:27 -0500301
Jean-Paul Calderoneaed23582011-03-12 22:45:02 -0500302 /* PyModule_AddObject steals a reference.
303 */
304 Py_INCREF((PyObject *)&crypto_CRL_Type);
305 if (PyModule_AddObject(module, "CRL", (PyObject *)&crypto_CRL_Type) != 0) {
306 return 0;
307 }
308 return 1;
Rick Dean536ba022009-07-24 23:57:27 -0500309}