Initial import to Tizen
[profile/ivi/python-pyOpenSSL.git] / OpenSSL / crypto / crl.c
1 #include <Python.h>
2 #define crypto_MODULE
3 #include "crypto.h"
4
5
6 static X509_REVOKED * X509_REVOKED_dup(X509_REVOKED *orig) {
7     X509_REVOKED *dupe = NULL;
8
9     dupe = X509_REVOKED_new();
10     if (dupe == NULL) {
11         return NULL;
12     }
13     if (orig->serialNumber) {
14         dupe->serialNumber = M_ASN1_INTEGER_dup(orig->serialNumber); 
15     }
16     if (orig->revocationDate) {
17         dupe->revocationDate = M_ASN1_INTEGER_dup(orig->revocationDate); 
18     }
19     if (orig->extensions) {
20         STACK_OF(X509_EXTENSION) *sk = NULL;
21         X509_EXTENSION * ext;
22         int j;
23
24         sk = sk_X509_EXTENSION_new_null();
25         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);
29         }
30         dupe->extensions = sk;
31     }
32     dupe->sequence = orig->sequence;
33     return dupe;
34 }
35
36 static char crypto_CRL_get_revoked_doc[] = "\n\
37 Return revoked portion of the CRL structure (by value\n\
38 not reference).\n\
39 \n\
40 @return: A tuple of Revoked objects.\n\
41 ";
42 static PyObject *
43 crypto_CRL_get_revoked(crypto_CRLObj *self, PyObject *args) {
44     int j, num_rev;
45     X509_REVOKED *r = NULL;
46     PyObject *obj = NULL, *rev_obj;
47
48     if (!PyArg_ParseTuple(args, ":get_revoked")) {
49         return NULL;
50     }
51
52     num_rev = sk_X509_REVOKED_num(self->crl->crl->revoked);
53     if (num_rev < 0) {
54         Py_INCREF(Py_None);
55         return Py_None;
56     }
57     if ((obj = PyTuple_New(num_rev)) == NULL) {
58         return NULL;
59     }
60
61     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);
73     }
74     return obj;
75
76  error:
77     if (r) {
78         X509_REVOKED_free(r);
79     }
80     Py_XDECREF(obj);
81     return NULL;
82 }
83
84 static char crypto_CRL_add_revoked_doc[] = "\n\
85 Add 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 ";
91 static PyObject *
92 crypto_CRL_add_revoked(crypto_CRLObj *self, PyObject *args, PyObject *keywds) {
93     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", 
98         kwlist, &crypto_Revoked_Type, &rev_obj)) {
99         return NULL;
100     }
101
102     dup = X509_REVOKED_dup( rev_obj->revoked );
103     if (dup == NULL) {
104         return NULL;
105     }
106     X509_CRL_add0_revoked(self->crl, dup);
107
108     Py_INCREF(Py_None);
109     return Py_None;
110 }
111
112 static char crypto_CRL_export_doc[] = "\n\
113 export(cert, key[, type[, days]]) -> export 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 @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\
123 ";
124 static PyObject *
125 crypto_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};
134     
135     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     }
140     
141     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;
157
158         case X509_FILETYPE_ASN1:
159             ret = (int) i2d_X509_CRL_bio(bio, self->crl);
160             break;
161
162         case X509_FILETYPE_TEXT:
163             ret = X509_CRL_print(bio, self->crl);
164             break;
165
166         default:
167             PyErr_SetString(
168                 PyExc_ValueError,
169                 "type argument must be FILETYPE_PEM, FILETYPE_ASN1, or FILETYPE_TEXT");
170             return NULL;
171     }
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);
178     buffer = PyBytes_FromStringAndSize(temp, buf_len);
179     BIO_free(bio);
180     return buffer;
181 }
182
183 crypto_CRLObj *
184 crypto_CRL_New(X509_CRL *crl) {
185     crypto_CRLObj *self;
186
187     self = PyObject_New(crypto_CRLObj, &crypto_CRL_Type);
188     if (self == NULL) {
189         return NULL;
190     }
191     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 }
204 static PyMethodDef crypto_CRL_methods[] = {
205     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
213 static void
214 crypto_CRL_dealloc(crypto_CRLObj *self) {
215     X509_CRL_free(self->crl);
216     self->crl = NULL;
217
218     PyObject_Del(self);
219 }
220
221 static char crypto_CRL_doc[] = "\n\
222 CRL() -> CRL instance\n\
223 \n\
224 Create a new empty CRL object.\n\
225 \n\
226 @returns: The CRL object\n\
227 ";
228
229 static PyObject* crypto_CRL_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) {
230     if (!PyArg_ParseTuple(args, ":CRL")) {
231         return NULL;
232     }
233     
234     return (PyObject *)crypto_CRL_New(X509_CRL_new());
235 }
236
237 PyTypeObject crypto_CRL_Type = {
238     PyOpenSSL_HEAD_INIT(&PyType_Type, 0)
239     "CRL",
240     sizeof(crypto_CRLObj),
241     0,
242     (destructor)crypto_CRL_dealloc,
243     NULL, /* print */
244     NULL, /* getattr */
245     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
278 int init_crypto_crl(PyObject *module) {
279        if (PyType_Ready(&crypto_CRL_Type) < 0) {
280                   return 0;
281        }
282
283        if (PyModule_AddObject(module, "CRL", (PyObject *)&crypto_CRL_Type) != 0) {
284                   return 0;
285        }
286        return 1;
287 }