blob: c5c84b5a546188d248fd83ab2f36f822b90e498a [file] [log] [blame]
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05001/*
2 * pkcs12.c
3 *
4 * Copyright (C) AB Strakt 2001, All rights reserved
5 *
6 * Certificate transport (PKCS12) handling code,
7 * mostly thin wrappers around OpenSSL.
8 * See the file RATIONALE for a short explanation of why
9 * this module was written.
10 *
11 * Reviewed 2001-07-23
12 */
13#include <Python.h>
14#define crypto_MODULE
15#include "crypto.h"
16
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050017/*
18 * PKCS12 is a standard exchange format for digital certificates.
19 * See e.g. the OpenSSL homepage http://www.openssl.org/ for more information
20 */
21
22static void crypto_PKCS12_dealloc(crypto_PKCS12Obj *self);
23
24static char crypto_PKCS12_get_certificate_doc[] = "\n\
25Return certificate portion of the PKCS12 structure\n\
26\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -040027@return: X509 object containing the certificate\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050028";
29static PyObject *
30crypto_PKCS12_get_certificate(crypto_PKCS12Obj *self, PyObject *args)
31{
32 if (!PyArg_ParseTuple(args, ":get_certificate"))
33 return NULL;
34
35 Py_INCREF(self->cert);
36 return self->cert;
37}
38
Rick Dean623ee362009-07-17 12:22:16 -050039static char crypto_PKCS12_set_certificate_doc[] = "\n\
40Replace or set the certificate portion of the PKCS12 structure\n\
41\n\
42Arguments: self - The PKCS12 object\n\
43 args - The Python argument tuple \n\
44 cert - The new certificate\n\
45Returns: self\n\
46";
47static crypto_PKCS12Obj *
48crypto_PKCS12_set_certificate(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
49{
50 PyObject *cert = NULL;
51 static char *kwlist[] = {"cert", NULL};
52
53 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_certificate",
54 kwlist, &cert))
55 return NULL;
56
57 if (cert != Py_None && ! PyObject_IsInstance(cert, (PyObject *) &crypto_X509_Type)) {
58 PyErr_SetString(PyExc_TypeError, "cert must be type X509 or None");
59 return NULL;
60 }
61
62 Py_INCREF(cert); /* Make consistent before calling Py_DECREF() */
63 if(self->cert) {
64 Py_DECREF(self->cert);
65 }
66 self->cert = cert;
67
68 Py_INCREF(self);
69 return self;
70}
71
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050072static char crypto_PKCS12_get_privatekey_doc[] = "\n\
73Return private key portion of the PKCS12 structure\n\
74\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -040075@returns: PKey object containing the private key\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050076";
Rick Dean623ee362009-07-17 12:22:16 -050077//static PyObject *
78static crypto_PKeyObj *
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050079crypto_PKCS12_get_privatekey(crypto_PKCS12Obj *self, PyObject *args)
80{
81 if (!PyArg_ParseTuple(args, ":get_privatekey"))
82 return NULL;
83
84 Py_INCREF(self->key);
Rick Dean623ee362009-07-17 12:22:16 -050085 return (PyObject *) self->key;
86}
87
88static char crypto_PKCS12_set_privatekey_doc[] = "\n\
89Replace or set the privatekey portion of the PKCS12 structure\n\
90\n\
91Arguments: self - The PKCS12 object\n\
92 args - The Python argument tuple \n\
93 pkey - The new private key\n\
94Returns: self\n\
95";
96static crypto_PKCS12Obj *
97crypto_PKCS12_set_privatekey(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
98{
99 PyObject *pkey = NULL;
100 static char *kwlist[] = {"pkey", NULL};
101
102 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_privatekey",
103 kwlist, &pkey))
104 return NULL;
105
106 if (pkey != Py_None && ! PyObject_IsInstance(pkey, (PyObject *) &crypto_PKey_Type)) {
107 PyErr_SetString(PyExc_TypeError, "pkey must be type X509 or None");
108 return NULL;
109 }
110
111 Py_INCREF(pkey); /* Make consistent before calling Py_DECREF() */
112 if(self->key) {
113 Py_DECREF(self->key);
114 }
115 self->key = pkey;
116
117 Py_INCREF(self);
118 return self;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500119}
120
121static char crypto_PKCS12_get_ca_certificates_doc[] = "\n\
122Return CA certificates within of the PKCS12 object\n\
123\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400124@return: A newly created tuple containing the CA certificates in the chain,\n\
125 if any are present, or None if no CA certificates are present.\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500126";
127static PyObject *
128crypto_PKCS12_get_ca_certificates(crypto_PKCS12Obj *self, PyObject *args)
129{
130 if (!PyArg_ParseTuple(args, ":get_ca_certificates"))
131 return NULL;
132
133 Py_INCREF(self->cacerts);
134 return self->cacerts;
135}
136
Rick Dean623ee362009-07-17 12:22:16 -0500137static char crypto_PKCS12_set_ca_certificates_doc[] = "\n\
138Replace or set the ca_certificates portion of the PKCS12 structure\n\
139\n\
140Arguments: self - The PKCS12 object\n\
141 args - The Python argument tuple \n\
142 cacerts - The new ca_certificates\n\
143Returns: self\n\
144";
145static crypto_PKCS12Obj *
146crypto_PKCS12_set_ca_certificates(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
147{
148 PyObject *cacerts;
149 static char *kwlist[] = {"cacerts", NULL};
150 int i;
151
152 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_ca_certificates",
153 kwlist, &cacerts))
154 return NULL;
155 if (cacerts == Py_None) {
156 /* We are good. */
157 } else if (PySequence_Check(cacerts)) { /* is iterable */
158 for(i = 0;i < PySequence_Length(cacerts);i++) { /* For each CA cert */
159 PyObject *obj;
160 obj = PySequence_GetItem(cacerts, i);
161 if (PyObject_Type(obj) != (PyObject *) &crypto_X509_Type) {
162 Py_DECREF(obj);
163 PyErr_SetString(PyExc_TypeError, "cacerts iterable must only contain X509Type");
164 return NULL;
165 }
166 Py_DECREF(obj);
167 }
168 } else {
169 PyErr_SetString(PyExc_TypeError, "cacerts must be an iterable or None");
170 return NULL;
171 }
172
173 Py_INCREF(cacerts); /* Make consistent before calling Py_DECREF() */
174 if(self->cacerts) {
175 Py_DECREF(self->cacerts);
176 }
177 self->cacerts = cacerts;
178
179 Py_INCREF(self);
180 return self;
181}
182
183static char crypto_PKCS12_export_doc[] = "\n\
184Dump a PKCS12 object to a buffer string\n\
185\n\
186Arguments: self - The PKCS12 object\n\
187 args - The Python argument tuple, should be:\n\
188 passphrase - (optional) for encrypting the PKCS12 string\n\
189 using 3DES-CBC\n\
190 friendly_name - stored in the file for display\n\
191 iter - number of iterations to use when encrypting\n\
192 maciter - number of iterations to use when creating the MAC.\n\
193 A special value of -1 means no MAC.\n\
194Returns: The buffer with the dumped pkcs12 in it\n\
195";
196
197static PyObject *
198crypto_PKCS12_export(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
199{
200 int buf_len;
201 PyObject *buffer;
202 char *temp, *passphrase = NULL, *friendly_name = NULL;
203 BIO *bio;
204 PKCS12 *p12;
205 EVP_PKEY *pkey = NULL;
206 STACK_OF(X509) *cacerts = NULL;
207 X509 *x509 = NULL;
208 int iter = PKCS12_DEFAULT_ITER;
209 int maciter = 0;
210 static char *kwlist[] = {"passphrase", "friendly_name", "iter", "maciter", NULL};
211
212 if (!PyArg_ParseTupleAndKeywords(args, keywds, "|zzii:export",
213 kwlist, &passphrase, &friendly_name, &iter, &maciter))
214 return NULL;
215
216 if (self->key && self->key != Py_None) {
217 pkey = ((crypto_PKeyObj*) self->key)->pkey;
218 }
219 if (self->cert && self->cert != Py_None) {
220 x509 = ((crypto_X509Obj*) self->cert)->x509;
221 }
222 cacerts = sk_X509_new_null();
223 if (self->cacerts && self->cacerts != Py_None) {
224 int i;
225 PyObject *obj;
226 for(i = 0;i < PySequence_Length(self->cacerts);i++) { /* For each CA cert */
227 obj = PySequence_GetItem(self->cacerts, i);
228 /* assert(PyObject_IsInstance(obj, (PyObject *) &crypto_X509_Type )); */
229 sk_X509_push(cacerts, (( crypto_X509Obj* ) obj)->x509);
230 Py_DECREF(obj);
231 }
232 }
233
234 p12 = PKCS12_create(passphrase, friendly_name, pkey, x509, cacerts,
235 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
236 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
237 iter, maciter, 0);
238 if( p12 == NULL ) {
239 exception_from_error_queue(crypto_Error);
240 return NULL;
241 }
242 bio = BIO_new(BIO_s_mem());
243 i2d_PKCS12_bio(bio, p12);
244 buf_len = BIO_get_mem_data(bio, &temp);
245 buffer = PyString_FromStringAndSize(temp, buf_len);
246 BIO_free(bio);
247 return buffer;
248}
249
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500250/*
251 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
252 * { 'name', (PyCFunction)crypto_PKCS12_name, METH_VARARGS, crypto_PKCS12_name_doc }
253 * for convenience
254 */
255#define ADD_METHOD(name) \
256 { #name, (PyCFunction)crypto_PKCS12_##name, METH_VARARGS, crypto_PKCS12_##name##_doc }
Rick Dean623ee362009-07-17 12:22:16 -0500257#define ADD_KW_METHOD(name) \
258 { #name, (PyCFunction)crypto_PKCS12_##name, METH_VARARGS | METH_KEYWORDS, crypto_PKCS12_##name##_doc }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500259static PyMethodDef crypto_PKCS12_methods[] =
260{
261 ADD_METHOD(get_certificate),
Rick Dean623ee362009-07-17 12:22:16 -0500262 ADD_KW_METHOD(set_certificate),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500263 ADD_METHOD(get_privatekey),
Rick Dean623ee362009-07-17 12:22:16 -0500264 ADD_KW_METHOD(set_privatekey),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500265 ADD_METHOD(get_ca_certificates),
Rick Dean623ee362009-07-17 12:22:16 -0500266 ADD_KW_METHOD(set_ca_certificates),
267 ADD_KW_METHOD(export),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500268 { NULL, NULL }
269};
270#undef ADD_METHOD
271
272/*
273 * Constructor for PKCS12 objects, never called by Python code directly.
274 * The strategy for this object is to create all the Python objects
275 * corresponding to the cert/key/CA certs right away
276 *
277 * Arguments: p12 - A "real" PKCS12 object
278 * passphrase - Passphrase to use when decrypting the PKCS12 object
279 * Returns: The newly created PKCS12 object
280 */
281crypto_PKCS12Obj *
282crypto_PKCS12_New(PKCS12 *p12, char *passphrase)
283{
284 crypto_PKCS12Obj *self;
285 PyObject *cacertobj = NULL;
286
287 X509 *cert = NULL;
288 EVP_PKEY *pkey = NULL;
289 STACK_OF(X509) *cacerts = NULL;
290
291 int i, cacert_count = 0;
292
293 /* allocate space for the CA cert stack */
294 cacerts = sk_X509_new_null();
295
296 /* parse the PKCS12 lump */
Rick Dean623ee362009-07-17 12:22:16 -0500297 if (p12 && !(cacerts && PKCS12_parse(p12, passphrase, &pkey, &cert, &cacerts)))
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500298 {
Rick Deand369c932009-07-08 11:48:33 -0500299 exception_from_error_queue(crypto_Error);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500300 return NULL;
301 }
302
303 if (!(self = PyObject_GC_New(crypto_PKCS12Obj, &crypto_PKCS12_Type)))
304 return NULL;
305
306 self->cert = NULL;
307 self->key = NULL;
308 Py_INCREF(Py_None);
309 self->cacerts = Py_None;
310
Rick Dean623ee362009-07-17 12:22:16 -0500311 if (cert == NULL) {
312 Py_INCREF(Py_None);
313 self->cert = Py_None;
314 } else {
315 if ((self->cert = (PyObject *)crypto_X509_New(cert, 1)) == NULL)
316 goto error;
317 }
318 if (pkey == NULL) {
319 Py_INCREF(Py_None);
320 self->key = Py_None;
321 } else {
322 if ((self->key = (PyObject *)crypto_PKey_New(pkey, 1)) == NULL)
323 goto error;
324 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500325
326 /* Make a tuple for the CA certs */
327 cacert_count = sk_X509_num(cacerts);
328 if (cacert_count > 0)
329 {
330 Py_DECREF(self->cacerts);
331 if ((self->cacerts = PyTuple_New(cacert_count)) == NULL)
332 goto error;
333
334 for (i = 0; i < cacert_count; i++)
335 {
336 cert = sk_X509_value(cacerts, i);
337 if ((cacertobj = (PyObject *)crypto_X509_New(cert, 1)) == NULL)
338 goto error;
339 PyTuple_SET_ITEM(self->cacerts, i, cacertobj);
340 }
341 }
342
343 sk_X509_free(cacerts); /* don't free the certs, just the stack */
344 PyObject_GC_Track(self);
345
346 return self;
347error:
348 crypto_PKCS12_dealloc(self);
349 return NULL;
350}
351
Rick Deancbeaca02009-07-17 12:50:12 -0500352static char crypto_PKCS12_doc[] = "\n\
353PKCS12() -> PKCS12 instance\n\
354\n\
355Create a new PKCS12 object.\n\
356\n\
357@returns: The PKCS12 object\n\
358";
359static PyObject *
360crypto_PKCS12_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
361{
362 if (!PyArg_ParseTuple(args, ":PKCS12")) {
363 return NULL;
364 }
365
366 return (PyObject *)crypto_PKCS12_New(NULL, NULL);
367}
368
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500369/*
370 * Find attribute
371 *
372 * Arguments: self - The PKCS12 object
373 * name - The attribute name
374 * Returns: A Python object for the attribute, or NULL if something went
375 * wrong
376 */
377static PyObject *
378crypto_PKCS12_getattr(crypto_PKCS12Obj *self, char *name)
379{
380 return Py_FindMethod(crypto_PKCS12_methods, (PyObject *)self, name);
381}
382
383/*
384 * Call the visitproc on all contained objects.
385 *
386 * Arguments: self - The PKCS12 object
387 * visit - Function to call
388 * arg - Extra argument to visit
389 * Returns: 0 if all goes well, otherwise the return code from the first
390 * call that gave non-zero result.
391 */
392static int
393crypto_PKCS12_traverse(crypto_PKCS12Obj *self, visitproc visit, void *arg)
394{
395 int ret = 0;
396
397 if (ret == 0 && self->cert != NULL)
398 ret = visit(self->cert, arg);
399 if (ret == 0 && self->key != NULL)
400 ret = visit(self->key, arg);
401 if (ret == 0 && self->cacerts != NULL)
402 ret = visit(self->cacerts, arg);
403 return ret;
404}
405
406/*
407 * Decref all contained objects and zero the pointers.
408 *
409 * Arguments: self - The PKCS12 object
410 * Returns: Always 0.
411 */
412static int
413crypto_PKCS12_clear(crypto_PKCS12Obj *self)
414{
415 Py_XDECREF(self->cert);
416 self->cert = NULL;
417 Py_XDECREF(self->key);
418 self->key = NULL;
419 Py_XDECREF(self->cacerts);
420 self->cacerts = NULL;
421 return 0;
422}
423
424/*
425 * Deallocate the memory used by the PKCS12 object
426 *
427 * Arguments: self - The PKCS12 object
428 * Returns: None
429 */
430static void
431crypto_PKCS12_dealloc(crypto_PKCS12Obj *self)
432{
433 PyObject_GC_UnTrack(self);
434 crypto_PKCS12_clear(self);
435 PyObject_GC_Del(self);
436}
437
438PyTypeObject crypto_PKCS12_Type = {
439 PyObject_HEAD_INIT(NULL)
440 0,
441 "PKCS12",
442 sizeof(crypto_PKCS12Obj),
443 0,
444 (destructor)crypto_PKCS12_dealloc,
445 NULL, /* print */
446 (getattrfunc)crypto_PKCS12_getattr,
447 NULL, /* setattr */
448 NULL, /* compare */
449 NULL, /* repr */
450 NULL, /* as_number */
451 NULL, /* as_sequence */
452 NULL, /* as_mapping */
453 NULL, /* hash */
454 NULL, /* call */
455 NULL, /* str */
456 NULL, /* getattro */
457 NULL, /* setattro */
458 NULL, /* as_buffer */
459 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
Rick Deancbeaca02009-07-17 12:50:12 -0500460 crypto_PKCS12_doc,
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500461 (traverseproc)crypto_PKCS12_traverse,
462 (inquiry)crypto_PKCS12_clear,
Rick Deancbeaca02009-07-17 12:50:12 -0500463 NULL, /* tp_richcompare */
464 0, /* tp_weaklistoffset */
465 NULL, /* tp_iter */
466 NULL, /* tp_iternext */
467 crypto_PKCS12_methods, /* tp_methods */
468 NULL, /* tp_members */
469 NULL, /* tp_getset */
470 NULL, /* tp_base */
471 NULL, /* tp_dict */
472 NULL, /* tp_descr_get */
473 NULL, /* tp_descr_set */
474 0, /* tp_dictoffset */
475 NULL, /* tp_init */
476 NULL, /* tp_alloc */
477 crypto_PKCS12_new, /* tp_new */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500478};
479
480/*
481 * Initialize the PKCS12 part of the crypto sub module
482 *
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400483 * Arguments: module - The crypto module
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500484 * Returns: None
485 */
486int
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400487init_crypto_pkcs12(PyObject *module) {
488 if (PyType_Ready(&crypto_PKCS12_Type) < 0) {
489 return 0;
490 }
491
Rick Deancbeaca02009-07-17 12:50:12 -0500492 if (PyModule_AddObject(module, "PKCS12", (PyObject *)&crypto_PKCS12_Type) != 0) {
493 return 0;
494 }
495
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400496 if (PyModule_AddObject(module, "PKCS12Type", (PyObject *)&crypto_PKCS12_Type) != 0) {
497 return 0;
498 }
499
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500500 return 1;
501}
502