blob: c90cbe82c971c4c266caf716c8cb38b2ecd397f9 [file] [log] [blame]
Rick Dean536ba022009-07-24 23:57:27 -05001#include <Python.h>
2#define crypto_MODULE
3#include "crypto.h"
4
5
6static X509_REVOKED * X509_REVOKED_dup(X509_REVOKED *orig)
7{
8 X509_REVOKED *dupe = NULL;
9
10 dupe = X509_REVOKED_new();
11 if(dupe == NULL)
12 return NULL;
13 if(orig->serialNumber)
14 {
15 dupe->serialNumber = M_ASN1_INTEGER_dup(orig->serialNumber);
16 }
17 if(orig->revocationDate)
18 {
19 dupe->revocationDate = M_ASN1_INTEGER_dup(orig->revocationDate);
20 }
21 if(orig->extensions)
22 {
23 STACK_OF(X509_EXTENSION) *sk = NULL;
24 X509_EXTENSION * ext;
25 int j;
26
27 sk = sk_X509_EXTENSION_new_null();
28 for(j = 0; j < sk_X509_EXTENSION_num(orig->extensions); j++) {
29 ext = sk_X509_EXTENSION_value(orig->extensions, j);
30 ext = X509_EXTENSION_dup(ext);
31 sk_X509_EXTENSION_push(sk, ext);
32 }
33 dupe->extensions = sk;
34 }
35 dupe->sequence = orig->sequence;
36 return dupe;
37}
38
39static char crypto_CRL_get_revoked_doc[] = "\n\
40Return revoked portion of the CRL structure (by value\n\
41not reference).\n\
42\n\
43@return: A tuple of Revoked objects.\n\
44";
45static PyObject *
46crypto_CRL_get_revoked(crypto_CRLObj *self, PyObject *args)
47{
48 int j, num_rev;
49 X509_REVOKED *r = NULL;
50 PyObject *obj = NULL, *rev_obj;
51
52 if (!PyArg_ParseTuple(args, ":get_revoked"))
53 return NULL;
54
55 num_rev = sk_X509_REVOKED_num(self->crl->crl->revoked);
56 if(num_rev < 0)
57 {
58 Py_INCREF(Py_None);
59 return Py_None;
60 }
61 if ((obj = PyTuple_New(num_rev)) == NULL)
62 return NULL;
63
64 for(j = 0; j < num_rev; j++)
65 {
66 r = sk_X509_REVOKED_value(self->crl->crl->revoked, j);
67 r = X509_REVOKED_dup(r);
68 if( r == NULL )
69 goto error;
70 rev_obj = (PyObject *) crypto_Revoked_New(r);
71 if( rev_obj == NULL )
72 goto error;
73 r = NULL; /* it's now owned by rev_obj */
74 PyTuple_SET_ITEM(obj, j, rev_obj);
75 }
76 return obj;
77
78 error:
79 if(r)
80 X509_REVOKED_free(r);
81 Py_XDECREF(obj);
82 return NULL;
83}
84
85static char crypto_CRL_add_revoked_doc[] = "\n\
86Add a revoked (by value not reference) to the CRL structure\n\
87\n\
88@param cert: The new revoked.\n\
89@type cert: L{X509}\n\
90@return: None\n\
91";
92static PyObject *
93crypto_CRL_add_revoked(crypto_CRLObj *self, PyObject *args, PyObject *keywds)
94{
95 crypto_RevokedObj * rev_obj = NULL;
96 static char *kwlist[] = {"revoked", NULL};
97 X509_REVOKED * dup;
98
99 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!:add_revoked",
100 kwlist, &crypto_Revoked_Type, &rev_obj))
101 return NULL;
102
103 dup = X509_REVOKED_dup( rev_obj->revoked );
104 if(dup == NULL)
105 return NULL;
106 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\
113Export a CRL as a string\n\
114\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 *
122crypto_CRL_export(crypto_CRLObj *self, PyObject *args, PyObject *keywds)
123{
124 int ret, buf_len, type = X509_FILETYPE_PEM, days = 100;
125 char *temp;
126 BIO *bio;
127 PyObject *buffer;
128 crypto_PKeyObj *key;
129 ASN1_TIME *tmptm;
130 crypto_X509Obj *x509;
131 static char *kwlist[] = {"cert", "key", "type", "days", NULL};
132
133 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!O!|ii:dump_crl", kwlist,
134 &crypto_X509_Type, &x509,
135 &crypto_PKey_Type, &key, &type, &days))
136 return NULL;
137
138 bio=BIO_new(BIO_s_mem());
139 tmptm = ASN1_TIME_new();
140 if (!tmptm)
141 return 0;
142 X509_gmtime_adj(tmptm,0);
143 X509_CRL_set_lastUpdate(self->crl, tmptm);
144 X509_gmtime_adj(tmptm,days*24*60*60);
145 X509_CRL_set_nextUpdate(self->crl, tmptm);
146 ASN1_TIME_free(tmptm);
147 X509_CRL_set_issuer_name(self->crl, X509_get_subject_name(x509->x509));
148 X509_CRL_sign(self->crl, key->pkey, EVP_md5());
149 switch (type)
150 {
151 case X509_FILETYPE_PEM:
152 ret = PEM_write_bio_X509_CRL(bio, self->crl);
153 break;
154
155 case X509_FILETYPE_ASN1:
156 ret = (int) i2d_X509_CRL_bio(bio, self->crl);
157 break;
158
159 case X509_FILETYPE_TEXT:
160 ret = X509_CRL_print(bio, self->crl);
161 break;
162
163 default:
164 PyErr_SetString(PyExc_ValueError,
165 "type argument must be FILETYPE_PEM or FILETYPE_ASN1");
166 return NULL;
167 };
168 if( ! ret )
169 {
170 exception_from_error_queue(crypto_Error);
171 BIO_free(bio);
172 return NULL;
173 }
174 buf_len = BIO_get_mem_data(bio, &temp);
175 buffer = PyString_FromStringAndSize(temp, buf_len);
176 BIO_free(bio);
177 return buffer;
178}
179
180crypto_CRLObj *
181crypto_CRL_New(X509_CRL *crl)
182{
183 crypto_CRLObj *self;
184
185 self = PyObject_New(crypto_CRLObj, &crypto_CRL_Type);
186 if (self==NULL)
187 return NULL;
188 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 }
201static PyMethodDef crypto_CRL_methods[] =
202{
203 ADD_KW_METHOD(add_revoked),
204 ADD_METHOD(get_revoked),
205 ADD_KW_METHOD(export),
206 { NULL, NULL }
207};
208#undef ADD_METHOD
209
210
211static PyObject *
212crypto_CRL_getattr(crypto_CRLObj *self, char *name)
213{
214 return Py_FindMethod(crypto_CRL_methods, (PyObject *)self, name);
215}
216
217static void
218crypto_CRL_dealloc(crypto_CRLObj *self)
219{
220 X509_CRL_free(self->crl);
221 self->crl = NULL;
222
223 PyObject_Del(self);
224}
225
226static char crypto_CRL_doc[] = "\n\
227CRL() -> CRL instance\n\
228\n\
229Create a new empty CRL object.\n\
230\n\
231@returns: The CRL object\n\
232";
233
234static PyObject* crypto_CRL_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) {
235 if (!PyArg_ParseTuple(args, ":CRL")) {
236 return NULL;
237 }
238
239 return (PyObject *)crypto_CRL_New(X509_CRL_new());
240}
241
242PyTypeObject crypto_CRL_Type = {
243 PyObject_HEAD_INIT(NULL)
244 0,
245 "CRL",
246 sizeof(crypto_CRLObj),
247 0,
248 (destructor)crypto_CRL_dealloc,
249 NULL, /* print */
250 (getattrfunc)crypto_CRL_getattr,
251 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) {
285 if(PyType_Ready(&crypto_CRL_Type) < 0) {
286 return 0;
287 }
288
289 if (PyModule_AddObject(module, "CRL", (PyObject *)&crypto_CRL_Type) != 0) {
290 return 0;
291 }
292 return 1;
293}
294