blob: 2bf04c0227b9c7d53be8e962493f8a3f1738006f [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";
46static crypto_PKCS12Obj *
47crypto_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
67 Py_INCREF(self);
68 return self;
69}
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 -050076//static PyObject *
77static crypto_PKeyObj *
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050078crypto_PKCS12_get_privatekey(crypto_PKCS12Obj *self, PyObject *args)
79{
80 if (!PyArg_ParseTuple(args, ":get_privatekey"))
81 return NULL;
82
83 Py_INCREF(self->key);
Rick Dean864e15e2009-07-17 15:21:23 -050084 return (crypto_PKeyObj *) self->key;
Rick Dean623ee362009-07-17 12:22:16 -050085}
86
87static char crypto_PKCS12_set_privatekey_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -050088Replace or set the certificate portion of the PKCS12 structure\n\
Rick Dean623ee362009-07-17 12:22:16 -050089\n\
Rick Deane182f482009-07-17 14:49:48 -050090@param pkey: The new private key.\n\
91@type pkey: L{PKey}\n\
92@return: None\n\
Rick Dean623ee362009-07-17 12:22:16 -050093";
94static crypto_PKCS12Obj *
95crypto_PKCS12_set_privatekey(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
96{
97 PyObject *pkey = NULL;
98 static char *kwlist[] = {"pkey", NULL};
99
100 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_privatekey",
101 kwlist, &pkey))
102 return NULL;
103
104 if (pkey != Py_None && ! PyObject_IsInstance(pkey, (PyObject *) &crypto_PKey_Type)) {
105 PyErr_SetString(PyExc_TypeError, "pkey must be type X509 or None");
106 return NULL;
107 }
108
109 Py_INCREF(pkey); /* Make consistent before calling Py_DECREF() */
110 if(self->key) {
111 Py_DECREF(self->key);
112 }
113 self->key = pkey;
114
115 Py_INCREF(self);
116 return self;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500117}
118
119static char crypto_PKCS12_get_ca_certificates_doc[] = "\n\
120Return CA certificates within of the PKCS12 object\n\
121\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400122@return: A newly created tuple containing the CA certificates in the chain,\n\
123 if any are present, or None if no CA certificates are present.\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500124";
125static PyObject *
126crypto_PKCS12_get_ca_certificates(crypto_PKCS12Obj *self, PyObject *args)
127{
128 if (!PyArg_ParseTuple(args, ":get_ca_certificates"))
129 return NULL;
130
131 Py_INCREF(self->cacerts);
132 return self->cacerts;
133}
134
Rick Dean623ee362009-07-17 12:22:16 -0500135static char crypto_PKCS12_set_ca_certificates_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -0500136Replace or set the CA certificates withing the PKCS12 object.\n\
Rick Dean623ee362009-07-17 12:22:16 -0500137\n\
Rick Deane182f482009-07-17 14:49:48 -0500138@param cacerts: The new CA certificates.\n\
139@type cacerts: Sequence of L{X509}\n\
140@return: None\n\
Rick Dean623ee362009-07-17 12:22:16 -0500141";
142static crypto_PKCS12Obj *
143crypto_PKCS12_set_ca_certificates(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
144{
145 PyObject *cacerts;
146 static char *kwlist[] = {"cacerts", NULL};
Rick Dean864e15e2009-07-17 15:21:23 -0500147 int i; /* Py_ssize_t for Python 2.5+ */
Rick Dean623ee362009-07-17 12:22:16 -0500148
149 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_ca_certificates",
150 kwlist, &cacerts))
151 return NULL;
152 if (cacerts == Py_None) {
153 /* We are good. */
154 } else if (PySequence_Check(cacerts)) { /* is iterable */
155 for(i = 0;i < PySequence_Length(cacerts);i++) { /* For each CA cert */
156 PyObject *obj;
157 obj = PySequence_GetItem(cacerts, i);
158 if (PyObject_Type(obj) != (PyObject *) &crypto_X509_Type) {
159 Py_DECREF(obj);
160 PyErr_SetString(PyExc_TypeError, "cacerts iterable must only contain X509Type");
161 return NULL;
162 }
163 Py_DECREF(obj);
164 }
165 } else {
166 PyErr_SetString(PyExc_TypeError, "cacerts must be an iterable or None");
167 return NULL;
168 }
169
170 Py_INCREF(cacerts); /* Make consistent before calling Py_DECREF() */
171 if(self->cacerts) {
172 Py_DECREF(self->cacerts);
173 }
174 self->cacerts = cacerts;
175
176 Py_INCREF(self);
177 return self;
178}
179
180static char crypto_PKCS12_export_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -0500181export([passphrase=None][, friendly_name=None][, iter=2048][, maciter=1]\n\
182Dump a PKCS12 object as a string. See also \"man PKCS12_create\".\n\
Rick Dean623ee362009-07-17 12:22:16 -0500183\n\
Rick Deane182f482009-07-17 14:49:48 -0500184@param passphrase: used to encrypt the PKCS12\n\
185@type passphrase: L{str}\n\
186@param friendly_name: A descriptive comment\n\
187@type friendly_name: L{str}\n\
188@param iter: How many times to repeat the encryption\n\
189@type iter: L{int}\n\
190@param maciter: How many times to repeat the MAC\n\
191@type maciter: L{int}\n\
192@return: The string containing the PKCS12\n\
Rick Dean623ee362009-07-17 12:22:16 -0500193";
Rick Dean623ee362009-07-17 12:22:16 -0500194static PyObject *
195crypto_PKCS12_export(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
196{
197 int buf_len;
198 PyObject *buffer;
199 char *temp, *passphrase = NULL, *friendly_name = NULL;
200 BIO *bio;
201 PKCS12 *p12;
202 EVP_PKEY *pkey = NULL;
203 STACK_OF(X509) *cacerts = NULL;
204 X509 *x509 = NULL;
Rick Deane182f482009-07-17 14:49:48 -0500205 int iter = 0; /* defaults to PKCS12_DEFAULT_ITER */
Rick Dean623ee362009-07-17 12:22:16 -0500206 int maciter = 0;
207 static char *kwlist[] = {"passphrase", "friendly_name", "iter", "maciter", NULL};
208
209 if (!PyArg_ParseTupleAndKeywords(args, keywds, "|zzii:export",
210 kwlist, &passphrase, &friendly_name, &iter, &maciter))
211 return NULL;
212
213 if (self->key && self->key != Py_None) {
214 pkey = ((crypto_PKeyObj*) self->key)->pkey;
215 }
216 if (self->cert && self->cert != Py_None) {
217 x509 = ((crypto_X509Obj*) self->cert)->x509;
218 }
219 cacerts = sk_X509_new_null();
220 if (self->cacerts && self->cacerts != Py_None) {
Rick Dean864e15e2009-07-17 15:21:23 -0500221 int i; /* Py_ssize_t for Python 2.5+ */
Rick Dean623ee362009-07-17 12:22:16 -0500222 PyObject *obj;
223 for(i = 0;i < PySequence_Length(self->cacerts);i++) { /* For each CA cert */
224 obj = PySequence_GetItem(self->cacerts, i);
225 /* assert(PyObject_IsInstance(obj, (PyObject *) &crypto_X509_Type )); */
226 sk_X509_push(cacerts, (( crypto_X509Obj* ) obj)->x509);
227 Py_DECREF(obj);
228 }
229 }
230
231 p12 = PKCS12_create(passphrase, friendly_name, pkey, x509, cacerts,
232 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
233 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
234 iter, maciter, 0);
235 if( p12 == NULL ) {
236 exception_from_error_queue(crypto_Error);
237 return NULL;
238 }
239 bio = BIO_new(BIO_s_mem());
240 i2d_PKCS12_bio(bio, p12);
241 buf_len = BIO_get_mem_data(bio, &temp);
242 buffer = PyString_FromStringAndSize(temp, buf_len);
243 BIO_free(bio);
244 return buffer;
245}
246
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500247/*
248 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
249 * { 'name', (PyCFunction)crypto_PKCS12_name, METH_VARARGS, crypto_PKCS12_name_doc }
250 * for convenience
251 */
252#define ADD_METHOD(name) \
253 { #name, (PyCFunction)crypto_PKCS12_##name, METH_VARARGS, crypto_PKCS12_##name##_doc }
Rick Dean623ee362009-07-17 12:22:16 -0500254#define ADD_KW_METHOD(name) \
255 { #name, (PyCFunction)crypto_PKCS12_##name, METH_VARARGS | METH_KEYWORDS, crypto_PKCS12_##name##_doc }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500256static PyMethodDef crypto_PKCS12_methods[] =
257{
258 ADD_METHOD(get_certificate),
Rick Dean623ee362009-07-17 12:22:16 -0500259 ADD_KW_METHOD(set_certificate),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500260 ADD_METHOD(get_privatekey),
Rick Dean623ee362009-07-17 12:22:16 -0500261 ADD_KW_METHOD(set_privatekey),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500262 ADD_METHOD(get_ca_certificates),
Rick Dean623ee362009-07-17 12:22:16 -0500263 ADD_KW_METHOD(set_ca_certificates),
264 ADD_KW_METHOD(export),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500265 { NULL, NULL }
266};
267#undef ADD_METHOD
268
269/*
270 * Constructor for PKCS12 objects, never called by Python code directly.
271 * The strategy for this object is to create all the Python objects
272 * corresponding to the cert/key/CA certs right away
273 *
274 * Arguments: p12 - A "real" PKCS12 object
275 * passphrase - Passphrase to use when decrypting the PKCS12 object
276 * Returns: The newly created PKCS12 object
277 */
278crypto_PKCS12Obj *
279crypto_PKCS12_New(PKCS12 *p12, char *passphrase)
280{
281 crypto_PKCS12Obj *self;
282 PyObject *cacertobj = NULL;
283
284 X509 *cert = NULL;
285 EVP_PKEY *pkey = NULL;
286 STACK_OF(X509) *cacerts = NULL;
287
288 int i, cacert_count = 0;
289
290 /* allocate space for the CA cert stack */
291 cacerts = sk_X509_new_null();
292
293 /* parse the PKCS12 lump */
Rick Dean623ee362009-07-17 12:22:16 -0500294 if (p12 && !(cacerts && PKCS12_parse(p12, passphrase, &pkey, &cert, &cacerts)))
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500295 {
Rick Deand369c932009-07-08 11:48:33 -0500296 exception_from_error_queue(crypto_Error);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500297 return NULL;
298 }
299
300 if (!(self = PyObject_GC_New(crypto_PKCS12Obj, &crypto_PKCS12_Type)))
301 return NULL;
302
303 self->cert = NULL;
304 self->key = NULL;
305 Py_INCREF(Py_None);
306 self->cacerts = Py_None;
307
Rick Dean623ee362009-07-17 12:22:16 -0500308 if (cert == NULL) {
309 Py_INCREF(Py_None);
310 self->cert = Py_None;
311 } else {
312 if ((self->cert = (PyObject *)crypto_X509_New(cert, 1)) == NULL)
313 goto error;
314 }
315 if (pkey == NULL) {
316 Py_INCREF(Py_None);
317 self->key = Py_None;
318 } else {
319 if ((self->key = (PyObject *)crypto_PKey_New(pkey, 1)) == NULL)
320 goto error;
321 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500322
323 /* Make a tuple for the CA certs */
324 cacert_count = sk_X509_num(cacerts);
325 if (cacert_count > 0)
326 {
327 Py_DECREF(self->cacerts);
328 if ((self->cacerts = PyTuple_New(cacert_count)) == NULL)
329 goto error;
330
331 for (i = 0; i < cacert_count; i++)
332 {
333 cert = sk_X509_value(cacerts, i);
334 if ((cacertobj = (PyObject *)crypto_X509_New(cert, 1)) == NULL)
335 goto error;
336 PyTuple_SET_ITEM(self->cacerts, i, cacertobj);
337 }
338 }
339
340 sk_X509_free(cacerts); /* don't free the certs, just the stack */
341 PyObject_GC_Track(self);
342
343 return self;
344error:
345 crypto_PKCS12_dealloc(self);
346 return NULL;
347}
348
Rick Deancbeaca02009-07-17 12:50:12 -0500349static char crypto_PKCS12_doc[] = "\n\
350PKCS12() -> PKCS12 instance\n\
351\n\
Rick Deane182f482009-07-17 14:49:48 -0500352Create a new empty PKCS12 object.\n\
Rick Deancbeaca02009-07-17 12:50:12 -0500353\n\
354@returns: The PKCS12 object\n\
355";
356static PyObject *
357crypto_PKCS12_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
358{
359 if (!PyArg_ParseTuple(args, ":PKCS12")) {
360 return NULL;
361 }
362
363 return (PyObject *)crypto_PKCS12_New(NULL, NULL);
364}
365
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500366/*
367 * Find attribute
368 *
369 * Arguments: self - The PKCS12 object
370 * name - The attribute name
371 * Returns: A Python object for the attribute, or NULL if something went
372 * wrong
373 */
374static PyObject *
375crypto_PKCS12_getattr(crypto_PKCS12Obj *self, char *name)
376{
377 return Py_FindMethod(crypto_PKCS12_methods, (PyObject *)self, name);
378}
379
380/*
381 * Call the visitproc on all contained objects.
382 *
383 * Arguments: self - The PKCS12 object
384 * visit - Function to call
385 * arg - Extra argument to visit
386 * Returns: 0 if all goes well, otherwise the return code from the first
387 * call that gave non-zero result.
388 */
389static int
390crypto_PKCS12_traverse(crypto_PKCS12Obj *self, visitproc visit, void *arg)
391{
392 int ret = 0;
393
394 if (ret == 0 && self->cert != NULL)
395 ret = visit(self->cert, arg);
396 if (ret == 0 && self->key != NULL)
397 ret = visit(self->key, arg);
398 if (ret == 0 && self->cacerts != NULL)
399 ret = visit(self->cacerts, arg);
400 return ret;
401}
402
403/*
404 * Decref all contained objects and zero the pointers.
405 *
406 * Arguments: self - The PKCS12 object
407 * Returns: Always 0.
408 */
409static int
410crypto_PKCS12_clear(crypto_PKCS12Obj *self)
411{
412 Py_XDECREF(self->cert);
413 self->cert = NULL;
414 Py_XDECREF(self->key);
415 self->key = NULL;
416 Py_XDECREF(self->cacerts);
417 self->cacerts = NULL;
418 return 0;
419}
420
421/*
422 * Deallocate the memory used by the PKCS12 object
423 *
424 * Arguments: self - The PKCS12 object
425 * Returns: None
426 */
427static void
428crypto_PKCS12_dealloc(crypto_PKCS12Obj *self)
429{
430 PyObject_GC_UnTrack(self);
431 crypto_PKCS12_clear(self);
432 PyObject_GC_Del(self);
433}
434
435PyTypeObject crypto_PKCS12_Type = {
436 PyObject_HEAD_INIT(NULL)
437 0,
438 "PKCS12",
439 sizeof(crypto_PKCS12Obj),
440 0,
441 (destructor)crypto_PKCS12_dealloc,
442 NULL, /* print */
443 (getattrfunc)crypto_PKCS12_getattr,
444 NULL, /* setattr */
445 NULL, /* compare */
446 NULL, /* repr */
447 NULL, /* as_number */
448 NULL, /* as_sequence */
449 NULL, /* as_mapping */
450 NULL, /* hash */
451 NULL, /* call */
452 NULL, /* str */
453 NULL, /* getattro */
454 NULL, /* setattro */
455 NULL, /* as_buffer */
456 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
Rick Deancbeaca02009-07-17 12:50:12 -0500457 crypto_PKCS12_doc,
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500458 (traverseproc)crypto_PKCS12_traverse,
459 (inquiry)crypto_PKCS12_clear,
Rick Deancbeaca02009-07-17 12:50:12 -0500460 NULL, /* tp_richcompare */
461 0, /* tp_weaklistoffset */
462 NULL, /* tp_iter */
463 NULL, /* tp_iternext */
464 crypto_PKCS12_methods, /* tp_methods */
465 NULL, /* tp_members */
466 NULL, /* tp_getset */
467 NULL, /* tp_base */
468 NULL, /* tp_dict */
469 NULL, /* tp_descr_get */
470 NULL, /* tp_descr_set */
471 0, /* tp_dictoffset */
472 NULL, /* tp_init */
473 NULL, /* tp_alloc */
474 crypto_PKCS12_new, /* tp_new */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500475};
476
477/*
478 * Initialize the PKCS12 part of the crypto sub module
479 *
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400480 * Arguments: module - The crypto module
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500481 * Returns: None
482 */
483int
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400484init_crypto_pkcs12(PyObject *module) {
485 if (PyType_Ready(&crypto_PKCS12_Type) < 0) {
486 return 0;
487 }
488
Rick Deancbeaca02009-07-17 12:50:12 -0500489 if (PyModule_AddObject(module, "PKCS12", (PyObject *)&crypto_PKCS12_Type) != 0) {
490 return 0;
491 }
492
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400493 if (PyModule_AddObject(module, "PKCS12Type", (PyObject *)&crypto_PKCS12_Type) != 0) {
494 return 0;
495 }
496
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500497 return 1;
498}
499