blob: 83691fbb3c4d2709f2356312a77e17101ee55c96 [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\
40@return: A tuple of Revoked objects.\n\
41";
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\
87@param cert: The new revoked.\n\
88@type cert: L{X509}\n\
89@return: None\n\
90";
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\
115@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@return: None\n\
120";
121static PyObject *
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400122crypto_CRL_export(crypto_CRLObj *self, PyObject *args, PyObject *keywds) {
123 int ret, buf_len, type = X509_FILETYPE_PEM, days = 100;
124 char *temp;
125 BIO *bio;
126 PyObject *buffer;
127 crypto_PKeyObj *key;
128 ASN1_TIME *tmptm;
129 crypto_X509Obj *x509;
130 static char *kwlist[] = {"cert", "key", "type", "days", NULL};
Rick Dean536ba022009-07-24 23:57:27 -0500131
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400132 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!O!|ii:dump_crl", kwlist,
133 &crypto_X509_Type, &x509,
134 &crypto_PKey_Type, &key, &type, &days)) {
135 return NULL;
136 }
Rick Dean536ba022009-07-24 23:57:27 -0500137
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400138 bio = BIO_new(BIO_s_mem());
139 tmptm = ASN1_TIME_new();
140 if (!tmptm) {
141 return 0;
142 }
143 X509_gmtime_adj(tmptm,0);
144 X509_CRL_set_lastUpdate(self->crl, tmptm);
145 X509_gmtime_adj(tmptm,days*24*60*60);
146 X509_CRL_set_nextUpdate(self->crl, tmptm);
147 ASN1_TIME_free(tmptm);
148 X509_CRL_set_issuer_name(self->crl, X509_get_subject_name(x509->x509));
149 X509_CRL_sign(self->crl, key->pkey, EVP_md5());
150 switch (type) {
151 case X509_FILETYPE_PEM:
152 ret = PEM_write_bio_X509_CRL(bio, self->crl);
153 break;
Rick Dean536ba022009-07-24 23:57:27 -0500154
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400155 case X509_FILETYPE_ASN1:
156 ret = (int) i2d_X509_CRL_bio(bio, self->crl);
157 break;
Rick Dean536ba022009-07-24 23:57:27 -0500158
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400159 case X509_FILETYPE_TEXT:
160 ret = X509_CRL_print(bio, self->crl);
161 break;
Rick Dean536ba022009-07-24 23:57:27 -0500162
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400163 default:
164 PyErr_SetString(
165 PyExc_ValueError,
166 "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or FILETYPE_TEXT");
Rick Dean536ba022009-07-24 23:57:27 -0500167 return NULL;
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400168 }
169 if (!ret) {
170 exception_from_error_queue(crypto_Error);
171 BIO_free(bio);
172 return NULL;
173 }
174 buf_len = BIO_get_mem_data(bio, &temp);
Jean-Paul Calderone2f6c66f2010-08-11 19:53:43 -0400175 buffer = PyBytes_FromStringAndSize(temp, buf_len);
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400176 BIO_free(bio);
177 return buffer;
Rick Dean536ba022009-07-24 23:57:27 -0500178}
179
180crypto_CRLObj *
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400181crypto_CRL_New(X509_CRL *crl) {
Rick Dean536ba022009-07-24 23:57:27 -0500182 crypto_CRLObj *self;
183
184 self = PyObject_New(crypto_CRLObj, &crypto_CRL_Type);
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400185 if (self == NULL) {
186 return NULL;
187 }
Rick Dean536ba022009-07-24 23:57:27 -0500188 self->crl = crl;
189 return self;
190}
191
192/*
193 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
194 * { 'name', (PyCFunction)crypto_CRL_name, METH_VARARGS, crypto_CRL_name_doc }
195 * for convenience
196 */
197#define ADD_METHOD(name) \
198 { #name, (PyCFunction)crypto_CRL_##name, METH_VARARGS, crypto_CRL_##name##_doc }
199#define ADD_KW_METHOD(name) \
200 { #name, (PyCFunction)crypto_CRL_##name, METH_VARARGS | METH_KEYWORDS, crypto_CRL_##name##_doc }
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400201static PyMethodDef crypto_CRL_methods[] = {
Rick Dean536ba022009-07-24 23:57:27 -0500202 ADD_KW_METHOD(add_revoked),
203 ADD_METHOD(get_revoked),
204 ADD_KW_METHOD(export),
205 { NULL, NULL }
206};
207#undef ADD_METHOD
208
209
Rick Dean536ba022009-07-24 23:57:27 -0500210static void
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400211crypto_CRL_dealloc(crypto_CRLObj *self) {
Rick Dean536ba022009-07-24 23:57:27 -0500212 X509_CRL_free(self->crl);
213 self->crl = NULL;
214
215 PyObject_Del(self);
216}
217
218static char crypto_CRL_doc[] = "\n\
219CRL() -> CRL instance\n\
220\n\
221Create a new empty CRL object.\n\
222\n\
223@returns: The CRL object\n\
224";
225
226static PyObject* crypto_CRL_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) {
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400227 if (!PyArg_ParseTuple(args, ":CRL")) {
228 return NULL;
229 }
230
231 return (PyObject *)crypto_CRL_New(X509_CRL_new());
Rick Dean536ba022009-07-24 23:57:27 -0500232}
233
234PyTypeObject crypto_CRL_Type = {
Jean-Paul Calderone3fe7f672010-08-11 23:55:10 -0400235 PyOpenSSL_HEAD_INIT(&PyType_Type, 0)
Rick Dean536ba022009-07-24 23:57:27 -0500236 "CRL",
237 sizeof(crypto_CRLObj),
238 0,
239 (destructor)crypto_CRL_dealloc,
240 NULL, /* print */
Jean-Paul Calderone2f6c66f2010-08-11 19:53:43 -0400241 NULL, /* getattr */
Rick Dean536ba022009-07-24 23:57:27 -0500242 NULL, /* setattr */
243 NULL, /* compare */
244 NULL, /* repr */
245 NULL, /* as_number */
246 NULL, /* as_sequence */
247 NULL, /* as_mapping */
248 NULL, /* hash */
249 NULL, /* call */
250 NULL, /* str */
251 NULL, /* getattro */
252 NULL, /* setattro */
253 NULL, /* as_buffer */
254 Py_TPFLAGS_DEFAULT,
255 crypto_CRL_doc, /* doc */
256 NULL, /* traverse */
257 NULL, /* clear */
258 NULL, /* tp_richcompare */
259 0, /* tp_weaklistoffset */
260 NULL, /* tp_iter */
261 NULL, /* tp_iternext */
262 crypto_CRL_methods, /* tp_methods */
263 NULL, /* tp_members */
264 NULL, /* tp_getset */
265 NULL, /* tp_base */
266 NULL, /* tp_dict */
267 NULL, /* tp_descr_get */
268 NULL, /* tp_descr_set */
269 0, /* tp_dictoffset */
270 NULL, /* tp_init */
271 NULL, /* tp_alloc */
272 crypto_CRL_new, /* tp_new */
273};
274
275int init_crypto_crl(PyObject *module) {
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400276 if (PyType_Ready(&crypto_CRL_Type) < 0) {
277 return 0;
Rick Dean536ba022009-07-24 23:57:27 -0500278 }
279
280 if (PyModule_AddObject(module, "CRL", (PyObject *)&crypto_CRL_Type) != 0) {
Jean-Paul Calderonec5c21602010-05-24 17:52:20 -0400281 return 0;
Rick Dean536ba022009-07-24 23:57:27 -0500282 }
283 return 1;
284}