blob: 2f6f9446607d247f5518f800a7205ee3f0a6e059 [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 *
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -04006 * Certificate transport (PKCS12) handling code,
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05007 * mostly thin wrappers around OpenSSL.
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -04008 * See the file RATIONALE for a short explanation of why
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05009 * 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 Calderonee7901d72009-07-24 18:21:26 -040017/*
18 * PKCS12 is a standard exchange format for digital certificates.
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050019 * 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\
Jean-Paul Calderonebade3132009-07-24 21:27:13 -040043@type cert: L{X509} or L{NoneType}\n\
Rick Dean379917c2009-07-21 11:37:41 -050044@return: None\n\
Rick Dean623ee362009-07-17 12:22:16 -050045";
Rick Dean38a05c82009-07-18 01:41:30 -050046static PyObject *
Jean-Paul Calderonebade3132009-07-24 21:27:13 -040047crypto_PKCS12_set_certificate(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds) {
Rick Dean623ee362009-07-17 12:22:16 -050048 PyObject *cert = NULL;
49 static char *kwlist[] = {"cert", NULL};
50
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -040051 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_certificate",
Rick Dean623ee362009-07-17 12:22:16 -050052 kwlist, &cert))
53 return NULL;
54
Jean-Paul Calderonebade3132009-07-24 21:27:13 -040055 if (cert != Py_None && ! crypto_X509_Check(cert)) {
Rick Dean623ee362009-07-17 12:22:16 -050056 PyErr_SetString(PyExc_TypeError, "cert must be type X509 or None");
57 return NULL;
58 }
59
60 Py_INCREF(cert); /* Make consistent before calling Py_DECREF() */
Rick Dean585cd9e2009-07-18 14:58:11 -050061 Py_DECREF(self->cert);
Rick Dean623ee362009-07-17 12:22:16 -050062 self->cert = cert;
63
Rick Dean38a05c82009-07-18 01:41:30 -050064 Py_INCREF(Py_None);
65 return Py_None;
Rick Dean623ee362009-07-17 12:22:16 -050066}
67
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050068static char crypto_PKCS12_get_privatekey_doc[] = "\n\
69Return private key portion of the PKCS12 structure\n\
70\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -040071@returns: PKey object containing the private key\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050072";
Rick Dean623ee362009-07-17 12:22:16 -050073static crypto_PKeyObj *
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050074crypto_PKCS12_get_privatekey(crypto_PKCS12Obj *self, PyObject *args)
75{
76 if (!PyArg_ParseTuple(args, ":get_privatekey"))
77 return NULL;
78
79 Py_INCREF(self->key);
Rick Dean864e15e2009-07-17 15:21:23 -050080 return (crypto_PKeyObj *) self->key;
Rick Dean623ee362009-07-17 12:22:16 -050081}
82
83static char crypto_PKCS12_set_privatekey_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -050084Replace or set the certificate portion of the PKCS12 structure\n\
Rick Dean623ee362009-07-17 12:22:16 -050085\n\
Rick Deane182f482009-07-17 14:49:48 -050086@param pkey: The new private key.\n\
87@type pkey: L{PKey}\n\
88@return: None\n\
Rick Dean623ee362009-07-17 12:22:16 -050089";
Rick Dean38a05c82009-07-18 01:41:30 -050090static PyObject *
Jean-Paul Calderoned8665432009-07-24 21:28:52 -040091crypto_PKCS12_set_privatekey(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds) {
Rick Dean623ee362009-07-17 12:22:16 -050092 PyObject *pkey = NULL;
93 static char *kwlist[] = {"pkey", NULL};
94
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -040095 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_privatekey",
Rick Dean623ee362009-07-17 12:22:16 -050096 kwlist, &pkey))
97 return NULL;
98
Jean-Paul Calderoned8665432009-07-24 21:28:52 -040099 if (pkey != Py_None && ! crypto_PKey_Check(pkey)) {
Rick Dean623ee362009-07-17 12:22:16 -0500100 PyErr_SetString(PyExc_TypeError, "pkey must be type X509 or None");
101 return NULL;
102 }
103
104 Py_INCREF(pkey); /* Make consistent before calling Py_DECREF() */
Rick Dean585cd9e2009-07-18 14:58:11 -0500105 Py_DECREF(self->key);
Rick Dean623ee362009-07-17 12:22:16 -0500106 self->key = pkey;
107
Rick Dean38a05c82009-07-18 01:41:30 -0500108 Py_INCREF(Py_None);
109 return Py_None;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500110}
111
112static char crypto_PKCS12_get_ca_certificates_doc[] = "\n\
113Return CA certificates within of the PKCS12 object\n\
114\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400115@return: A newly created tuple containing the CA certificates in the chain,\n\
116 if any are present, or None if no CA certificates are present.\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500117";
118static PyObject *
119crypto_PKCS12_get_ca_certificates(crypto_PKCS12Obj *self, PyObject *args)
120{
121 if (!PyArg_ParseTuple(args, ":get_ca_certificates"))
122 return NULL;
123
124 Py_INCREF(self->cacerts);
125 return self->cacerts;
126}
127
Rick Dean623ee362009-07-17 12:22:16 -0500128static char crypto_PKCS12_set_ca_certificates_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -0500129Replace or set the CA certificates withing the PKCS12 object.\n\
Rick Dean623ee362009-07-17 12:22:16 -0500130\n\
Rick Deane182f482009-07-17 14:49:48 -0500131@param cacerts: The new CA certificates.\n\
Jean-Paul Calderoned8665432009-07-24 21:28:52 -0400132@type cacerts: Iterable of L{X509} or L{NoneType}\n\
Rick Deane182f482009-07-17 14:49:48 -0500133@return: None\n\
Rick Dean623ee362009-07-17 12:22:16 -0500134";
Rick Dean38a05c82009-07-18 01:41:30 -0500135static PyObject *
Rick Dean623ee362009-07-17 12:22:16 -0500136crypto_PKCS12_set_ca_certificates(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
137{
Jean-Paul Calderone499fa1d2009-07-24 21:15:30 -0400138 PyObject *obj;
Rick Dean623ee362009-07-17 12:22:16 -0500139 PyObject *cacerts;
140 static char *kwlist[] = {"cacerts", NULL};
Rick Dean25bcc1f2009-07-20 11:53:13 -0500141 int i, len; /* Py_ssize_t for Python 2.5+ */
Rick Dean623ee362009-07-17 12:22:16 -0500142
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400143 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_ca_certificates",
Rick Dean623ee362009-07-17 12:22:16 -0500144 kwlist, &cacerts))
145 return NULL;
146 if (cacerts == Py_None) {
Rick Deane84d1462009-07-24 09:27:01 -0500147 Py_INCREF(cacerts);
Jean-Paul Calderone206c2272009-07-24 21:22:38 -0400148 } else {
149 /* It's iterable */
Rick Deane84d1462009-07-24 09:27:01 -0500150 cacerts = PySequence_Tuple(cacerts);
Jean-Paul Calderone206c2272009-07-24 21:22:38 -0400151 if (cacerts == NULL) {
Rick Deane84d1462009-07-24 09:27:01 -0500152 return NULL;
153 }
Jean-Paul Calderone206c2272009-07-24 21:22:38 -0400154 len = PyTuple_Size(cacerts);
155
Rick Dean48305252009-07-18 15:28:38 -0500156 /* Check is's a simple list filled only with X509 objects. */
Jean-Paul Calderone206c2272009-07-24 21:22:38 -0400157 for (i = 0; i < len; i++) {
Jean-Paul Calderone4c6b72e2009-07-24 21:18:51 -0400158 obj = PyTuple_GetItem(cacerts, i);
Jean-Paul Calderonefed4d152009-07-24 21:23:57 -0400159 if (!crypto_X509_Check(obj)) {
Rick Deane84d1462009-07-24 09:27:01 -0500160 Py_DECREF(cacerts);
Rick Deane84d1462009-07-24 09:27:01 -0500161 PyErr_SetString(PyExc_TypeError, "iterable must only contain X509Type");
Rick Dean623ee362009-07-17 12:22:16 -0500162 return NULL;
163 }
Rick Dean623ee362009-07-17 12:22:16 -0500164 }
Rick Dean623ee362009-07-17 12:22:16 -0500165 }
166
Rick Dean585cd9e2009-07-18 14:58:11 -0500167 Py_DECREF(self->cacerts);
Rick Dean623ee362009-07-17 12:22:16 -0500168 self->cacerts = cacerts;
169
Rick Dean38a05c82009-07-18 01:41:30 -0500170 Py_INCREF(Py_None);
171 return Py_None;
Rick Dean623ee362009-07-17 12:22:16 -0500172}
173
Rick Dean42d69e12009-07-20 11:36:08 -0500174static char crypto_PKCS12_get_friendlyname_doc[] = "\n\
175Return friendly name portion of the PKCS12 structure\n\
176\n\
177@returns: String containing the friendlyname\n\
178";
Rick Dean99251c22009-07-24 09:32:46 -0500179static PyObject *
Jean-Paul Calderone4a45cbc2009-07-24 21:41:12 -0400180crypto_PKCS12_get_friendlyname(crypto_PKCS12Obj *self, PyObject *args) {
Rick Dean42d69e12009-07-20 11:36:08 -0500181 if (!PyArg_ParseTuple(args, ":get_friendlyname"))
182 return NULL;
183
184 Py_INCREF(self->friendlyname);
Rick Dean99251c22009-07-24 09:32:46 -0500185 return (PyObject *) self->friendlyname;
Rick Dean42d69e12009-07-20 11:36:08 -0500186}
187
188static char crypto_PKCS12_set_friendlyname_doc[] = "\n\
189Replace or set the certificate portion of the PKCS12 structure\n\
190\n\
191@param name: The new friendly name.\n\
192@type name: L{str}\n\
193@return: None\n\
194";
195static PyObject *
Jean-Paul Calderone4a45cbc2009-07-24 21:41:12 -0400196crypto_PKCS12_set_friendlyname(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds) {
Rick Dean42d69e12009-07-20 11:36:08 -0500197 PyObject *name = NULL;
198 static char *kwlist[] = {"name", NULL};
199
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400200 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_friendlyname",
Rick Dean42d69e12009-07-20 11:36:08 -0500201 kwlist, &name))
202 return NULL;
203
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400204 if (name != Py_None && ! PyString_CheckExact(name)) {
Rick Dean37273112009-07-24 09:38:17 -0500205 PyErr_SetString(PyExc_TypeError, "name must be a str or None");
Rick Dean42d69e12009-07-20 11:36:08 -0500206 return NULL;
207 }
208
209 Py_INCREF(name); /* Make consistent before calling Py_DECREF() */
210 Py_DECREF(self->friendlyname);
211 self->friendlyname = name;
212
213 Py_INCREF(Py_None);
214 return Py_None;
215}
216
Rick Dean623ee362009-07-17 12:22:16 -0500217static char crypto_PKCS12_export_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -0500218export([passphrase=None][, friendly_name=None][, iter=2048][, maciter=1]\n\
219Dump a PKCS12 object as a string. See also \"man PKCS12_create\".\n\
Rick Dean623ee362009-07-17 12:22:16 -0500220\n\
Rick Deane182f482009-07-17 14:49:48 -0500221@param passphrase: used to encrypt the PKCS12\n\
222@type passphrase: L{str}\n\
Rick Deane182f482009-07-17 14:49:48 -0500223@param iter: How many times to repeat the encryption\n\
224@type iter: L{int}\n\
225@param maciter: How many times to repeat the MAC\n\
226@type maciter: L{int}\n\
227@return: The string containing the PKCS12\n\
Rick Dean623ee362009-07-17 12:22:16 -0500228";
Rick Dean623ee362009-07-17 12:22:16 -0500229static PyObject *
Jean-Paul Calderone4a45cbc2009-07-24 21:41:12 -0400230crypto_PKCS12_export(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds) {
231 int i; /* Py_ssize_t for Python 2.5+ */
232 PyObject *obj;
Rick Dean623ee362009-07-17 12:22:16 -0500233 int buf_len;
234 PyObject *buffer;
235 char *temp, *passphrase = NULL, *friendly_name = NULL;
236 BIO *bio;
237 PKCS12 *p12;
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400238 EVP_PKEY *pkey = NULL;
Rick Dean623ee362009-07-17 12:22:16 -0500239 STACK_OF(X509) *cacerts = NULL;
240 X509 *x509 = NULL;
Rick Deane182f482009-07-17 14:49:48 -0500241 int iter = 0; /* defaults to PKCS12_DEFAULT_ITER */
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400242 int maciter = 0;
Rick Dean42d69e12009-07-20 11:36:08 -0500243 static char *kwlist[] = {"passphrase", "iter", "maciter", NULL};
Rick Dean623ee362009-07-17 12:22:16 -0500244
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400245 if (!PyArg_ParseTupleAndKeywords(args, keywds, "|zii:export",
Rick Dean42d69e12009-07-20 11:36:08 -0500246 kwlist, &passphrase, &iter, &maciter))
Rick Dean623ee362009-07-17 12:22:16 -0500247 return NULL;
248
Rick Dean585cd9e2009-07-18 14:58:11 -0500249 if (self->key != Py_None) {
Rick Dean623ee362009-07-17 12:22:16 -0500250 pkey = ((crypto_PKeyObj*) self->key)->pkey;
251 }
Rick Dean585cd9e2009-07-18 14:58:11 -0500252 if (self->cert != Py_None) {
Rick Dean623ee362009-07-17 12:22:16 -0500253 x509 = ((crypto_X509Obj*) self->cert)->x509;
254 }
Rick Dean585cd9e2009-07-18 14:58:11 -0500255 if (self->cacerts != Py_None) {
Rick Dean8fefeb02009-07-24 10:56:29 -0500256 cacerts = sk_X509_new_null();
Jean-Paul Calderone4a45cbc2009-07-24 21:41:12 -0400257 for (i = 0; i < PyTuple_Size(self->cacerts); i++) { /* For each CA cert */
Rick Dean623ee362009-07-17 12:22:16 -0500258 obj = PySequence_GetItem(self->cacerts, i);
259 /* assert(PyObject_IsInstance(obj, (PyObject *) &crypto_X509_Type )); */
260 sk_X509_push(cacerts, (( crypto_X509Obj* ) obj)->x509);
261 Py_DECREF(obj);
262 }
263 }
Rick Dean42d69e12009-07-20 11:36:08 -0500264 if (self->friendlyname != Py_None) {
265 friendly_name = PyString_AsString(self->friendlyname);
266 }
Rick Dean623ee362009-07-17 12:22:16 -0500267
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400268 p12 = PKCS12_create(passphrase, friendly_name, pkey, x509, cacerts,
Rick Dean623ee362009-07-17 12:22:16 -0500269 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
270 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
271 iter, maciter, 0);
Rick Dean8fefeb02009-07-24 10:56:29 -0500272 sk_X509_free(cacerts); /* NULL safe. Free just the container. */
Jean-Paul Calderone4a45cbc2009-07-24 21:41:12 -0400273 if (p12 == NULL) {
Rick Dean623ee362009-07-17 12:22:16 -0500274 exception_from_error_queue(crypto_Error);
275 return NULL;
276 }
277 bio = BIO_new(BIO_s_mem());
278 i2d_PKCS12_bio(bio, p12);
279 buf_len = BIO_get_mem_data(bio, &temp);
280 buffer = PyString_FromStringAndSize(temp, buf_len);
281 BIO_free(bio);
282 return buffer;
283}
284
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500285/*
286 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
287 * { 'name', (PyCFunction)crypto_PKCS12_name, METH_VARARGS, crypto_PKCS12_name_doc }
288 * for convenience
289 */
290#define ADD_METHOD(name) \
291 { #name, (PyCFunction)crypto_PKCS12_##name, METH_VARARGS, crypto_PKCS12_##name##_doc }
Rick Dean623ee362009-07-17 12:22:16 -0500292#define ADD_KW_METHOD(name) \
293 { #name, (PyCFunction)crypto_PKCS12_##name, METH_VARARGS | METH_KEYWORDS, crypto_PKCS12_##name##_doc }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500294static PyMethodDef crypto_PKCS12_methods[] =
295{
296 ADD_METHOD(get_certificate),
Rick Dean623ee362009-07-17 12:22:16 -0500297 ADD_KW_METHOD(set_certificate),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500298 ADD_METHOD(get_privatekey),
Rick Dean623ee362009-07-17 12:22:16 -0500299 ADD_KW_METHOD(set_privatekey),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500300 ADD_METHOD(get_ca_certificates),
Rick Dean623ee362009-07-17 12:22:16 -0500301 ADD_KW_METHOD(set_ca_certificates),
Rick Dean42d69e12009-07-20 11:36:08 -0500302 ADD_METHOD(get_friendlyname),
303 ADD_KW_METHOD(set_friendlyname),
Rick Dean623ee362009-07-17 12:22:16 -0500304 ADD_KW_METHOD(export),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500305 { NULL, NULL }
306};
307#undef ADD_METHOD
308
309/*
310 * Constructor for PKCS12 objects, never called by Python code directly.
311 * The strategy for this object is to create all the Python objects
312 * corresponding to the cert/key/CA certs right away
313 *
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400314 * Arguments: p12 - A "real" PKCS12 object or NULL
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500315 * passphrase - Passphrase to use when decrypting the PKCS12 object
316 * Returns: The newly created PKCS12 object
317 */
318crypto_PKCS12Obj *
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400319crypto_PKCS12_New(PKCS12 *p12, char *passphrase) {
Jean-Paul Calderonee58415f2009-07-24 21:12:45 -0400320 crypto_PKCS12Obj *self = NULL;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500321 PyObject *cacertobj = NULL;
322
Jean-Paul Calderoneb96d13e2009-07-25 11:33:22 -0400323 unsigned char *alias_str;
324 int alias_len;
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400325
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500326 X509 *cert = NULL;
327 EVP_PKEY *pkey = NULL;
328 STACK_OF(X509) *cacerts = NULL;
329
330 int i, cacert_count = 0;
331
332 /* allocate space for the CA cert stack */
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400333 if((cacerts = sk_X509_new_null()) == NULL) {
Rick Deanaace5e92009-07-24 10:44:49 -0500334 goto error; /* out of memory? */
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400335 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500336
337 /* parse the PKCS12 lump */
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400338 if (p12 && !PKCS12_parse(p12, passphrase, &pkey, &cert, &cacerts)) {
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -0400339 /*
340 * If PKCS12_parse fails, and it allocated cacerts, it seems to free
341 * cacerts, but not re-NULL the pointer. Zounds! Make sure it is
342 * re-set to NULL here, else we'll have a double-free below.
343 */
344 cacerts = NULL;
Rick Deand369c932009-07-08 11:48:33 -0500345 exception_from_error_queue(crypto_Error);
Rick Deanee568302009-07-24 09:56:29 -0500346 goto error;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500347 }
348
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400349 if (!(self = PyObject_GC_New(crypto_PKCS12Obj, &crypto_PKCS12_Type))) {
Rick Deanee568302009-07-24 09:56:29 -0500350 goto error;
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400351 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500352
Rick Dean8fefeb02009-07-24 10:56:29 -0500353 /* client certificate and friendlyName */
Rick Dean623ee362009-07-17 12:22:16 -0500354 if (cert == NULL) {
355 Py_INCREF(Py_None);
356 self->cert = Py_None;
Rick Dean42d69e12009-07-20 11:36:08 -0500357 Py_INCREF(Py_None);
358 self->friendlyname = Py_None;
Rick Dean623ee362009-07-17 12:22:16 -0500359 } else {
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400360 if ((self->cert = (PyObject *)crypto_X509_New(cert, 1)) == NULL) {
Rick Dean623ee362009-07-17 12:22:16 -0500361 goto error;
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400362 }
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400363
Rick Dean42d69e12009-07-20 11:36:08 -0500364 /* Now we need to extract the friendlyName of the PKCS12
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400365 * that was stored by PKCS_parse() in the alias of the
Rick Dean42d69e12009-07-20 11:36:08 -0500366 * certificate. */
Jean-Paul Calderoneb96d13e2009-07-25 11:33:22 -0400367 alias_str = X509_alias_get0(cert, &alias_len);
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400368 if (alias_str) {
369 if (!(self->friendlyname = Py_BuildValue("s#", alias_str, alias_len))) {
370 /*
371 * XXX Untested
372 */
373 goto error;
374 }
Rick Dean42d69e12009-07-20 11:36:08 -0500375 /* success */
376 } else {
377 Py_INCREF(Py_None);
378 self->friendlyname = Py_None;
379 }
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400380 }
Rick Dean8fefeb02009-07-24 10:56:29 -0500381
382 /* private key */
Rick Dean623ee362009-07-17 12:22:16 -0500383 if (pkey == NULL) {
384 Py_INCREF(Py_None);
385 self->key = Py_None;
386 } else {
387 if ((self->key = (PyObject *)crypto_PKey_New(pkey, 1)) == NULL)
388 goto error;
389 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500390
Rick Dean8fefeb02009-07-24 10:56:29 -0500391 /* CA certs */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500392 cacert_count = sk_X509_num(cacerts);
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400393 if (cacert_count <= 0) {
Rick Deanaace5e92009-07-24 10:44:49 -0500394 Py_INCREF(Py_None);
395 self->cacerts = Py_None;
396 } else {
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400397 if ((self->cacerts = PyTuple_New(cacert_count)) == NULL) {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500398 goto error;
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400399 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500400
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400401 for (i = 0; i < cacert_count; i++) {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500402 cert = sk_X509_value(cacerts, i);
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400403 if ((cacertobj = (PyObject *)crypto_X509_New(cert, 1)) == NULL) {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500404 goto error;
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400405 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500406 PyTuple_SET_ITEM(self->cacerts, i, cacertobj);
407 }
408 }
409
Rick Dean8fefeb02009-07-24 10:56:29 -0500410 sk_X509_free(cacerts); /* Don't free the certs, just the container. */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500411 PyObject_GC_Track(self);
412
413 return self;
Rick Deanee568302009-07-24 09:56:29 -0500414
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500415error:
Rick Dean8fefeb02009-07-24 10:56:29 -0500416 sk_X509_free(cacerts); /* NULL safe. Free just the container. */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500417 crypto_PKCS12_dealloc(self);
418 return NULL;
419}
420
Rick Deancbeaca02009-07-17 12:50:12 -0500421static char crypto_PKCS12_doc[] = "\n\
422PKCS12() -> PKCS12 instance\n\
423\n\
Rick Deane182f482009-07-17 14:49:48 -0500424Create a new empty PKCS12 object.\n\
Rick Deancbeaca02009-07-17 12:50:12 -0500425\n\
426@returns: The PKCS12 object\n\
427";
428static PyObject *
Jean-Paul Calderoneb1a3af12009-07-25 12:21:18 -0400429crypto_PKCS12_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) {
Rick Deancbeaca02009-07-17 12:50:12 -0500430 if (!PyArg_ParseTuple(args, ":PKCS12")) {
431 return NULL;
432 }
433
434 return (PyObject *)crypto_PKCS12_New(NULL, NULL);
435}
436
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500437/*
438 * Find attribute
439 *
440 * Arguments: self - The PKCS12 object
441 * name - The attribute name
442 * Returns: A Python object for the attribute, or NULL if something went
443 * wrong
444 */
445static PyObject *
446crypto_PKCS12_getattr(crypto_PKCS12Obj *self, char *name)
447{
448 return Py_FindMethod(crypto_PKCS12_methods, (PyObject *)self, name);
449}
450
451/*
452 * Call the visitproc on all contained objects.
453 *
454 * Arguments: self - The PKCS12 object
455 * visit - Function to call
456 * arg - Extra argument to visit
457 * Returns: 0 if all goes well, otherwise the return code from the first
458 * call that gave non-zero result.
459 */
460static int
461crypto_PKCS12_traverse(crypto_PKCS12Obj *self, visitproc visit, void *arg)
462{
463 int ret = 0;
464
465 if (ret == 0 && self->cert != NULL)
466 ret = visit(self->cert, arg);
467 if (ret == 0 && self->key != NULL)
468 ret = visit(self->key, arg);
469 if (ret == 0 && self->cacerts != NULL)
470 ret = visit(self->cacerts, arg);
Rick Dean42d69e12009-07-20 11:36:08 -0500471 if (ret == 0 && self->friendlyname != NULL)
472 ret = visit(self->friendlyname, arg);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500473 return ret;
474}
475
476/*
477 * Decref all contained objects and zero the pointers.
478 *
479 * Arguments: self - The PKCS12 object
480 * Returns: Always 0.
481 */
482static int
483crypto_PKCS12_clear(crypto_PKCS12Obj *self)
484{
485 Py_XDECREF(self->cert);
486 self->cert = NULL;
487 Py_XDECREF(self->key);
488 self->key = NULL;
489 Py_XDECREF(self->cacerts);
490 self->cacerts = NULL;
Rick Dean42d69e12009-07-20 11:36:08 -0500491 Py_XDECREF(self->friendlyname);
492 self->friendlyname = NULL;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500493 return 0;
494}
495
496/*
497 * Deallocate the memory used by the PKCS12 object
498 *
499 * Arguments: self - The PKCS12 object
500 * Returns: None
501 */
502static void
503crypto_PKCS12_dealloc(crypto_PKCS12Obj *self)
504{
505 PyObject_GC_UnTrack(self);
506 crypto_PKCS12_clear(self);
507 PyObject_GC_Del(self);
508}
509
510PyTypeObject crypto_PKCS12_Type = {
511 PyObject_HEAD_INIT(NULL)
512 0,
513 "PKCS12",
514 sizeof(crypto_PKCS12Obj),
515 0,
516 (destructor)crypto_PKCS12_dealloc,
517 NULL, /* print */
518 (getattrfunc)crypto_PKCS12_getattr,
519 NULL, /* setattr */
520 NULL, /* compare */
521 NULL, /* repr */
522 NULL, /* as_number */
523 NULL, /* as_sequence */
524 NULL, /* as_mapping */
525 NULL, /* hash */
526 NULL, /* call */
527 NULL, /* str */
528 NULL, /* getattro */
529 NULL, /* setattro */
530 NULL, /* as_buffer */
531 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400532 crypto_PKCS12_doc,
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500533 (traverseproc)crypto_PKCS12_traverse,
534 (inquiry)crypto_PKCS12_clear,
Rick Deancbeaca02009-07-17 12:50:12 -0500535 NULL, /* tp_richcompare */
536 0, /* tp_weaklistoffset */
537 NULL, /* tp_iter */
538 NULL, /* tp_iternext */
539 crypto_PKCS12_methods, /* tp_methods */
540 NULL, /* tp_members */
541 NULL, /* tp_getset */
542 NULL, /* tp_base */
543 NULL, /* tp_dict */
544 NULL, /* tp_descr_get */
545 NULL, /* tp_descr_set */
546 0, /* tp_dictoffset */
547 NULL, /* tp_init */
548 NULL, /* tp_alloc */
549 crypto_PKCS12_new, /* tp_new */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500550};
551
552/*
553 * Initialize the PKCS12 part of the crypto sub module
554 *
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400555 * Arguments: module - The crypto module
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500556 * Returns: None
557 */
558int
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400559init_crypto_pkcs12(PyObject *module) {
560 if (PyType_Ready(&crypto_PKCS12_Type) < 0) {
561 return 0;
562 }
563
Rick Deancbeaca02009-07-17 12:50:12 -0500564 if (PyModule_AddObject(module, "PKCS12", (PyObject *)&crypto_PKCS12_Type) != 0) {
565 return 0;
566 }
567
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400568 if (PyModule_AddObject(module, "PKCS12Type", (PyObject *)&crypto_PKCS12_Type) != 0) {
569 return 0;
570 }
571
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500572 return 1;
573}