blob: 97326f8092c808fcdbb2584347eef1d898d4ddcc [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\
88:type cert: L{X509}\n\
89: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\
116:type cert: L{X509}\n\
117:param key: Used to sign CRL.\n\
118:type key: L{PKey}\n\
119:param type: The export format, either L{FILETYPE_PEM}, L{FILETYPE_ASN1}, or L{FILETYPE_TEXT}.\n\
120:param days: The number of days until the next update of this CRL.\n\
121:type days: L{int}\n\
122:return: L{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};
Rick Dean536ba022009-07-24 23:57:27 -0500134
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400135 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!O!|ii:dump_crl", kwlist,
136 &crypto_X509_Type, &x509,
137 &crypto_PKey_Type, &key, &type, &days)) {
138 return NULL;
139 }
Rick Dean536ba022009-07-24 23:57:27 -0500140
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));
152 X509_CRL_sign(self->crl, key->pkey, EVP_md5());
153 switch (type) {
154 case X509_FILETYPE_PEM:
155 ret = PEM_write_bio_X509_CRL(bio, self->crl);
156 break;
Rick Dean536ba022009-07-24 23:57:27 -0500157
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400158 case X509_FILETYPE_ASN1:
159 ret = (int) i2d_X509_CRL_bio(bio, self->crl);
160 break;
Rick Dean536ba022009-07-24 23:57:27 -0500161
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400162 case X509_FILETYPE_TEXT:
163 ret = X509_CRL_print(bio, self->crl);
164 break;
Rick Dean536ba022009-07-24 23:57:27 -0500165
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400166 default:
167 PyErr_SetString(
168 PyExc_ValueError,
169 "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or FILETYPE_TEXT");
Rick Dean536ba022009-07-24 23:57:27 -0500170 return NULL;
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400171 }
172 if (!ret) {
173 exception_from_error_queue(crypto_Error);
174 BIO_free(bio);
175 return NULL;
176 }
177 buf_len = BIO_get_mem_data(bio, &temp);
Jean-Paul Calderone2f6c66f2010-08-11 19:53:43 -0400178 buffer = PyBytes_FromStringAndSize(temp, buf_len);
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400179 BIO_free(bio);
180 return buffer;
Rick Dean536ba022009-07-24 23:57:27 -0500181}
182
183crypto_CRLObj *
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400184crypto_CRL_New(X509_CRL *crl) {
Rick Dean536ba022009-07-24 23:57:27 -0500185 crypto_CRLObj *self;
186
187 self = PyObject_New(crypto_CRLObj, &crypto_CRL_Type);
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400188 if (self == NULL) {
189 return NULL;
190 }
Rick Dean536ba022009-07-24 23:57:27 -0500191 self->crl = crl;
192 return self;
193}
194
195/*
196 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
197 * { 'name', (PyCFunction)crypto_CRL_name, METH_VARARGS, crypto_CRL_name_doc }
198 * for convenience
199 */
200#define ADD_METHOD(name) \
201 { #name, (PyCFunction)crypto_CRL_##name, METH_VARARGS, crypto_CRL_##name##_doc }
202#define ADD_KW_METHOD(name) \
203 { #name, (PyCFunction)crypto_CRL_##name, METH_VARARGS | METH_KEYWORDS, crypto_CRL_##name##_doc }
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400204static PyMethodDef crypto_CRL_methods[] = {
Rick Dean536ba022009-07-24 23:57:27 -0500205 ADD_KW_METHOD(add_revoked),
206 ADD_METHOD(get_revoked),
207 ADD_KW_METHOD(export),
208 { NULL, NULL }
209};
210#undef ADD_METHOD
211
212
Rick Dean536ba022009-07-24 23:57:27 -0500213static void
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400214crypto_CRL_dealloc(crypto_CRLObj *self) {
Rick Dean536ba022009-07-24 23:57:27 -0500215 X509_CRL_free(self->crl);
216 self->crl = NULL;
217
218 PyObject_Del(self);
219}
220
221static char crypto_CRL_doc[] = "\n\
222CRL() -> CRL instance\n\
223\n\
224Create a new empty CRL object.\n\
225\n\
Jonathan Ballet78b92a22011-07-16 08:07:26 +0900226:returns: The CRL object\n\
Rick Dean536ba022009-07-24 23:57:27 -0500227";
228
229static PyObject* crypto_CRL_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) {
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400230 if (!PyArg_ParseTuple(args, ":CRL")) {
231 return NULL;
232 }
233
234 return (PyObject *)crypto_CRL_New(X509_CRL_new());
Rick Dean536ba022009-07-24 23:57:27 -0500235}
236
237PyTypeObject crypto_CRL_Type = {
Jean-Paul Calderone3fe7f672010-08-11 23:55:10 -0400238 PyOpenSSL_HEAD_INIT(&PyType_Type, 0)
Rick Dean536ba022009-07-24 23:57:27 -0500239 "CRL",
240 sizeof(crypto_CRLObj),
241 0,
242 (destructor)crypto_CRL_dealloc,
243 NULL, /* print */
Jean-Paul Calderone2f6c66f2010-08-11 19:53:43 -0400244 NULL, /* getattr */
Rick Dean536ba022009-07-24 23:57:27 -0500245 NULL, /* setattr */
246 NULL, /* compare */
247 NULL, /* repr */
248 NULL, /* as_number */
249 NULL, /* as_sequence */
250 NULL, /* as_mapping */
251 NULL, /* hash */
252 NULL, /* call */
253 NULL, /* str */
254 NULL, /* getattro */
255 NULL, /* setattro */
256 NULL, /* as_buffer */
257 Py_TPFLAGS_DEFAULT,
258 crypto_CRL_doc, /* doc */
259 NULL, /* traverse */
260 NULL, /* clear */
261 NULL, /* tp_richcompare */
262 0, /* tp_weaklistoffset */
263 NULL, /* tp_iter */
264 NULL, /* tp_iternext */
265 crypto_CRL_methods, /* tp_methods */
266 NULL, /* tp_members */
267 NULL, /* tp_getset */
268 NULL, /* tp_base */
269 NULL, /* tp_dict */
270 NULL, /* tp_descr_get */
271 NULL, /* tp_descr_set */
272 0, /* tp_dictoffset */
273 NULL, /* tp_init */
274 NULL, /* tp_alloc */
275 crypto_CRL_new, /* tp_new */
276};
277
278int init_crypto_crl(PyObject *module) {
Jean-Paul Calderoneaed23582011-03-12 22:45:02 -0500279 if (PyType_Ready(&crypto_CRL_Type) < 0) {
280 return 0;
281 }
Rick Dean536ba022009-07-24 23:57:27 -0500282
Jean-Paul Calderoneaed23582011-03-12 22:45:02 -0500283 /* PyModule_AddObject steals a reference.
284 */
285 Py_INCREF((PyObject *)&crypto_CRL_Type);
286 if (PyModule_AddObject(module, "CRL", (PyObject *)&crypto_CRL_Type) != 0) {
287 return 0;
288 }
289 return 1;
Rick Dean536ba022009-07-24 23:57:27 -0500290}