blob: e5854d9a715a1b6fa9bb0b5af95b9addcb1a1bd0 [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\
Rick Deane182f482009-07-17 14:49:48 -050040Replace the certificate portion of the PKCS12 structure\n\
Rick Dean623ee362009-07-17 12:22:16 -050041\n\
Rick Deane182f482009-07-17 14:49:48 -050042@param cert: The new certificate.\n\
43@type cert: L{X509}\n\
44@return: X509 object containing the certificate\n\
Rick Dean623ee362009-07-17 12:22:16 -050045";
Rick Dean38a05c82009-07-18 01:41:30 -050046static PyObject *
Rick Dean623ee362009-07-17 12:22:16 -050047crypto_PKCS12_set_certificate(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
48{
49 PyObject *cert = NULL;
50 static char *kwlist[] = {"cert", NULL};
51
52 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_certificate",
53 kwlist, &cert))
54 return NULL;
55
56 if (cert != Py_None && ! PyObject_IsInstance(cert, (PyObject *) &crypto_X509_Type)) {
57 PyErr_SetString(PyExc_TypeError, "cert must be type X509 or None");
58 return NULL;
59 }
60
61 Py_INCREF(cert); /* Make consistent before calling Py_DECREF() */
62 if(self->cert) {
63 Py_DECREF(self->cert);
64 }
65 self->cert = cert;
66
Rick Dean38a05c82009-07-18 01:41:30 -050067 Py_INCREF(Py_None);
68 return Py_None;
Rick Dean623ee362009-07-17 12:22:16 -050069}
70
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050071static char crypto_PKCS12_get_privatekey_doc[] = "\n\
72Return private key portion of the PKCS12 structure\n\
73\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -040074@returns: PKey object containing the private key\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050075";
Rick Dean623ee362009-07-17 12:22:16 -050076static crypto_PKeyObj *
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050077crypto_PKCS12_get_privatekey(crypto_PKCS12Obj *self, PyObject *args)
78{
79 if (!PyArg_ParseTuple(args, ":get_privatekey"))
80 return NULL;
81
82 Py_INCREF(self->key);
Rick Dean864e15e2009-07-17 15:21:23 -050083 return (crypto_PKeyObj *) self->key;
Rick Dean623ee362009-07-17 12:22:16 -050084}
85
86static char crypto_PKCS12_set_privatekey_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -050087Replace or set the certificate portion of the PKCS12 structure\n\
Rick Dean623ee362009-07-17 12:22:16 -050088\n\
Rick Deane182f482009-07-17 14:49:48 -050089@param pkey: The new private key.\n\
90@type pkey: L{PKey}\n\
91@return: None\n\
Rick Dean623ee362009-07-17 12:22:16 -050092";
Rick Dean38a05c82009-07-18 01:41:30 -050093static PyObject *
Rick Dean623ee362009-07-17 12:22:16 -050094crypto_PKCS12_set_privatekey(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
95{
96 PyObject *pkey = NULL;
97 static char *kwlist[] = {"pkey", NULL};
98
99 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_privatekey",
100 kwlist, &pkey))
101 return NULL;
102
103 if (pkey != Py_None && ! PyObject_IsInstance(pkey, (PyObject *) &crypto_PKey_Type)) {
104 PyErr_SetString(PyExc_TypeError, "pkey must be type X509 or None");
105 return NULL;
106 }
107
108 Py_INCREF(pkey); /* Make consistent before calling Py_DECREF() */
109 if(self->key) {
110 Py_DECREF(self->key);
111 }
112 self->key = pkey;
113
Rick Dean38a05c82009-07-18 01:41:30 -0500114 Py_INCREF(Py_None);
115 return Py_None;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500116}
117
118static char crypto_PKCS12_get_ca_certificates_doc[] = "\n\
119Return CA certificates within of the PKCS12 object\n\
120\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400121@return: A newly created tuple containing the CA certificates in the chain,\n\
122 if any are present, or None if no CA certificates are present.\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500123";
124static PyObject *
125crypto_PKCS12_get_ca_certificates(crypto_PKCS12Obj *self, PyObject *args)
126{
127 if (!PyArg_ParseTuple(args, ":get_ca_certificates"))
128 return NULL;
129
130 Py_INCREF(self->cacerts);
131 return self->cacerts;
132}
133
Rick Dean623ee362009-07-17 12:22:16 -0500134static char crypto_PKCS12_set_ca_certificates_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -0500135Replace or set the CA certificates withing the PKCS12 object.\n\
Rick Dean623ee362009-07-17 12:22:16 -0500136\n\
Rick Deane182f482009-07-17 14:49:48 -0500137@param cacerts: The new CA certificates.\n\
138@type cacerts: Sequence of L{X509}\n\
139@return: None\n\
Rick Dean623ee362009-07-17 12:22:16 -0500140";
Rick Dean38a05c82009-07-18 01:41:30 -0500141static PyObject *
Rick Dean623ee362009-07-17 12:22:16 -0500142crypto_PKCS12_set_ca_certificates(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
143{
144 PyObject *cacerts;
145 static char *kwlist[] = {"cacerts", NULL};
Rick Dean864e15e2009-07-17 15:21:23 -0500146 int i; /* Py_ssize_t for Python 2.5+ */
Rick Dean623ee362009-07-17 12:22:16 -0500147
148 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_ca_certificates",
149 kwlist, &cacerts))
150 return NULL;
151 if (cacerts == Py_None) {
152 /* We are good. */
153 } else if (PySequence_Check(cacerts)) { /* is iterable */
154 for(i = 0;i < PySequence_Length(cacerts);i++) { /* For each CA cert */
155 PyObject *obj;
156 obj = PySequence_GetItem(cacerts, i);
157 if (PyObject_Type(obj) != (PyObject *) &crypto_X509_Type) {
158 Py_DECREF(obj);
159 PyErr_SetString(PyExc_TypeError, "cacerts iterable must only contain X509Type");
160 return NULL;
161 }
162 Py_DECREF(obj);
163 }
164 } else {
165 PyErr_SetString(PyExc_TypeError, "cacerts must be an iterable or None");
166 return NULL;
167 }
168
169 Py_INCREF(cacerts); /* Make consistent before calling Py_DECREF() */
170 if(self->cacerts) {
171 Py_DECREF(self->cacerts);
172 }
173 self->cacerts = cacerts;
174
Rick Dean38a05c82009-07-18 01:41:30 -0500175 Py_INCREF(Py_None);
176 return Py_None;
Rick Dean623ee362009-07-17 12:22:16 -0500177}
178
179static char crypto_PKCS12_export_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -0500180export([passphrase=None][, friendly_name=None][, iter=2048][, maciter=1]\n\
181Dump a PKCS12 object as a string. See also \"man PKCS12_create\".\n\
Rick Dean623ee362009-07-17 12:22:16 -0500182\n\
Rick Deane182f482009-07-17 14:49:48 -0500183@param passphrase: used to encrypt the PKCS12\n\
184@type passphrase: L{str}\n\
185@param friendly_name: A descriptive comment\n\
186@type friendly_name: L{str}\n\
187@param iter: How many times to repeat the encryption\n\
188@type iter: L{int}\n\
189@param maciter: How many times to repeat the MAC\n\
190@type maciter: L{int}\n\
191@return: The string containing the PKCS12\n\
Rick Dean623ee362009-07-17 12:22:16 -0500192";
Rick Dean623ee362009-07-17 12:22:16 -0500193static PyObject *
194crypto_PKCS12_export(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
195{
196 int buf_len;
197 PyObject *buffer;
198 char *temp, *passphrase = NULL, *friendly_name = NULL;
199 BIO *bio;
200 PKCS12 *p12;
201 EVP_PKEY *pkey = NULL;
202 STACK_OF(X509) *cacerts = NULL;
203 X509 *x509 = NULL;
Rick Deane182f482009-07-17 14:49:48 -0500204 int iter = 0; /* defaults to PKCS12_DEFAULT_ITER */
Rick Dean623ee362009-07-17 12:22:16 -0500205 int maciter = 0;
206 static char *kwlist[] = {"passphrase", "friendly_name", "iter", "maciter", NULL};
207
208 if (!PyArg_ParseTupleAndKeywords(args, keywds, "|zzii:export",
209 kwlist, &passphrase, &friendly_name, &iter, &maciter))
210 return NULL;
211
212 if (self->key && self->key != Py_None) {
213 pkey = ((crypto_PKeyObj*) self->key)->pkey;
214 }
215 if (self->cert && self->cert != Py_None) {
216 x509 = ((crypto_X509Obj*) self->cert)->x509;
217 }
218 cacerts = sk_X509_new_null();
219 if (self->cacerts && self->cacerts != Py_None) {
Rick Dean864e15e2009-07-17 15:21:23 -0500220 int i; /* Py_ssize_t for Python 2.5+ */
Rick Dean623ee362009-07-17 12:22:16 -0500221 PyObject *obj;
222 for(i = 0;i < PySequence_Length(self->cacerts);i++) { /* For each CA cert */
223 obj = PySequence_GetItem(self->cacerts, i);
224 /* assert(PyObject_IsInstance(obj, (PyObject *) &crypto_X509_Type )); */
225 sk_X509_push(cacerts, (( crypto_X509Obj* ) obj)->x509);
226 Py_DECREF(obj);
227 }
228 }
229
230 p12 = PKCS12_create(passphrase, friendly_name, pkey, x509, cacerts,
231 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
232 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
233 iter, maciter, 0);
234 if( p12 == NULL ) {
235 exception_from_error_queue(crypto_Error);
236 return NULL;
237 }
238 bio = BIO_new(BIO_s_mem());
239 i2d_PKCS12_bio(bio, p12);
240 buf_len = BIO_get_mem_data(bio, &temp);
241 buffer = PyString_FromStringAndSize(temp, buf_len);
242 BIO_free(bio);
243 return buffer;
244}
245
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500246/*
247 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
248 * { 'name', (PyCFunction)crypto_PKCS12_name, METH_VARARGS, crypto_PKCS12_name_doc }
249 * for convenience
250 */
251#define ADD_METHOD(name) \
252 { #name, (PyCFunction)crypto_PKCS12_##name, METH_VARARGS, crypto_PKCS12_##name##_doc }
Rick Dean623ee362009-07-17 12:22:16 -0500253#define ADD_KW_METHOD(name) \
254 { #name, (PyCFunction)crypto_PKCS12_##name, METH_VARARGS | METH_KEYWORDS, crypto_PKCS12_##name##_doc }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500255static PyMethodDef crypto_PKCS12_methods[] =
256{
257 ADD_METHOD(get_certificate),
Rick Dean623ee362009-07-17 12:22:16 -0500258 ADD_KW_METHOD(set_certificate),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500259 ADD_METHOD(get_privatekey),
Rick Dean623ee362009-07-17 12:22:16 -0500260 ADD_KW_METHOD(set_privatekey),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500261 ADD_METHOD(get_ca_certificates),
Rick Dean623ee362009-07-17 12:22:16 -0500262 ADD_KW_METHOD(set_ca_certificates),
263 ADD_KW_METHOD(export),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500264 { NULL, NULL }
265};
266#undef ADD_METHOD
267
268/*
269 * Constructor for PKCS12 objects, never called by Python code directly.
270 * The strategy for this object is to create all the Python objects
271 * corresponding to the cert/key/CA certs right away
272 *
273 * Arguments: p12 - A "real" PKCS12 object
274 * passphrase - Passphrase to use when decrypting the PKCS12 object
275 * Returns: The newly created PKCS12 object
276 */
277crypto_PKCS12Obj *
278crypto_PKCS12_New(PKCS12 *p12, char *passphrase)
279{
280 crypto_PKCS12Obj *self;
281 PyObject *cacertobj = NULL;
282
283 X509 *cert = NULL;
284 EVP_PKEY *pkey = NULL;
285 STACK_OF(X509) *cacerts = NULL;
286
287 int i, cacert_count = 0;
288
289 /* allocate space for the CA cert stack */
290 cacerts = sk_X509_new_null();
291
292 /* parse the PKCS12 lump */
Rick Dean623ee362009-07-17 12:22:16 -0500293 if (p12 && !(cacerts && PKCS12_parse(p12, passphrase, &pkey, &cert, &cacerts)))
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500294 {
Rick Deand369c932009-07-08 11:48:33 -0500295 exception_from_error_queue(crypto_Error);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500296 return NULL;
297 }
298
299 if (!(self = PyObject_GC_New(crypto_PKCS12Obj, &crypto_PKCS12_Type)))
300 return NULL;
301
302 self->cert = NULL;
303 self->key = NULL;
304 Py_INCREF(Py_None);
305 self->cacerts = Py_None;
306
Rick Dean623ee362009-07-17 12:22:16 -0500307 if (cert == NULL) {
308 Py_INCREF(Py_None);
309 self->cert = Py_None;
310 } else {
311 if ((self->cert = (PyObject *)crypto_X509_New(cert, 1)) == NULL)
312 goto error;
313 }
314 if (pkey == NULL) {
315 Py_INCREF(Py_None);
316 self->key = Py_None;
317 } else {
318 if ((self->key = (PyObject *)crypto_PKey_New(pkey, 1)) == NULL)
319 goto error;
320 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500321
322 /* Make a tuple for the CA certs */
323 cacert_count = sk_X509_num(cacerts);
324 if (cacert_count > 0)
325 {
326 Py_DECREF(self->cacerts);
327 if ((self->cacerts = PyTuple_New(cacert_count)) == NULL)
328 goto error;
329
330 for (i = 0; i < cacert_count; i++)
331 {
332 cert = sk_X509_value(cacerts, i);
333 if ((cacertobj = (PyObject *)crypto_X509_New(cert, 1)) == NULL)
334 goto error;
335 PyTuple_SET_ITEM(self->cacerts, i, cacertobj);
336 }
337 }
338
339 sk_X509_free(cacerts); /* don't free the certs, just the stack */
340 PyObject_GC_Track(self);
341
342 return self;
343error:
344 crypto_PKCS12_dealloc(self);
345 return NULL;
346}
347
Rick Deancbeaca02009-07-17 12:50:12 -0500348static char crypto_PKCS12_doc[] = "\n\
349PKCS12() -> PKCS12 instance\n\
350\n\
Rick Deane182f482009-07-17 14:49:48 -0500351Create a new empty PKCS12 object.\n\
Rick Deancbeaca02009-07-17 12:50:12 -0500352\n\
353@returns: The PKCS12 object\n\
354";
355static PyObject *
356crypto_PKCS12_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
357{
358 if (!PyArg_ParseTuple(args, ":PKCS12")) {
359 return NULL;
360 }
361
362 return (PyObject *)crypto_PKCS12_New(NULL, NULL);
363}
364
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500365/*
366 * Find attribute
367 *
368 * Arguments: self - The PKCS12 object
369 * name - The attribute name
370 * Returns: A Python object for the attribute, or NULL if something went
371 * wrong
372 */
373static PyObject *
374crypto_PKCS12_getattr(crypto_PKCS12Obj *self, char *name)
375{
376 return Py_FindMethod(crypto_PKCS12_methods, (PyObject *)self, name);
377}
378
379/*
380 * Call the visitproc on all contained objects.
381 *
382 * Arguments: self - The PKCS12 object
383 * visit - Function to call
384 * arg - Extra argument to visit
385 * Returns: 0 if all goes well, otherwise the return code from the first
386 * call that gave non-zero result.
387 */
388static int
389crypto_PKCS12_traverse(crypto_PKCS12Obj *self, visitproc visit, void *arg)
390{
391 int ret = 0;
392
393 if (ret == 0 && self->cert != NULL)
394 ret = visit(self->cert, arg);
395 if (ret == 0 && self->key != NULL)
396 ret = visit(self->key, arg);
397 if (ret == 0 && self->cacerts != NULL)
398 ret = visit(self->cacerts, arg);
399 return ret;
400}
401
402/*
403 * Decref all contained objects and zero the pointers.
404 *
405 * Arguments: self - The PKCS12 object
406 * Returns: Always 0.
407 */
408static int
409crypto_PKCS12_clear(crypto_PKCS12Obj *self)
410{
411 Py_XDECREF(self->cert);
412 self->cert = NULL;
413 Py_XDECREF(self->key);
414 self->key = NULL;
415 Py_XDECREF(self->cacerts);
416 self->cacerts = NULL;
417 return 0;
418}
419
420/*
421 * Deallocate the memory used by the PKCS12 object
422 *
423 * Arguments: self - The PKCS12 object
424 * Returns: None
425 */
426static void
427crypto_PKCS12_dealloc(crypto_PKCS12Obj *self)
428{
429 PyObject_GC_UnTrack(self);
430 crypto_PKCS12_clear(self);
431 PyObject_GC_Del(self);
432}
433
434PyTypeObject crypto_PKCS12_Type = {
435 PyObject_HEAD_INIT(NULL)
436 0,
437 "PKCS12",
438 sizeof(crypto_PKCS12Obj),
439 0,
440 (destructor)crypto_PKCS12_dealloc,
441 NULL, /* print */
442 (getattrfunc)crypto_PKCS12_getattr,
443 NULL, /* setattr */
444 NULL, /* compare */
445 NULL, /* repr */
446 NULL, /* as_number */
447 NULL, /* as_sequence */
448 NULL, /* as_mapping */
449 NULL, /* hash */
450 NULL, /* call */
451 NULL, /* str */
452 NULL, /* getattro */
453 NULL, /* setattro */
454 NULL, /* as_buffer */
455 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
Rick Deancbeaca02009-07-17 12:50:12 -0500456 crypto_PKCS12_doc,
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500457 (traverseproc)crypto_PKCS12_traverse,
458 (inquiry)crypto_PKCS12_clear,
Rick Deancbeaca02009-07-17 12:50:12 -0500459 NULL, /* tp_richcompare */
460 0, /* tp_weaklistoffset */
461 NULL, /* tp_iter */
462 NULL, /* tp_iternext */
463 crypto_PKCS12_methods, /* tp_methods */
464 NULL, /* tp_members */
465 NULL, /* tp_getset */
466 NULL, /* tp_base */
467 NULL, /* tp_dict */
468 NULL, /* tp_descr_get */
469 NULL, /* tp_descr_set */
470 0, /* tp_dictoffset */
471 NULL, /* tp_init */
472 NULL, /* tp_alloc */
473 crypto_PKCS12_new, /* tp_new */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500474};
475
476/*
477 * Initialize the PKCS12 part of the crypto sub module
478 *
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400479 * Arguments: module - The crypto module
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500480 * Returns: None
481 */
482int
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400483init_crypto_pkcs12(PyObject *module) {
484 if (PyType_Ready(&crypto_PKCS12_Type) < 0) {
485 return 0;
486 }
487
Rick Deancbeaca02009-07-17 12:50:12 -0500488 if (PyModule_AddObject(module, "PKCS12", (PyObject *)&crypto_PKCS12_Type) != 0) {
489 return 0;
490 }
491
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400492 if (PyModule_AddObject(module, "PKCS12Type", (PyObject *)&crypto_PKCS12_Type) != 0) {
493 return 0;
494 }
495
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500496 return 1;
497}
498