blob: 81d6074015e714614e087ed351f49a164bf0fe1b [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);
Jean-Paul Calderoned0a98762009-07-25 21:23:01 -040023static int crypto_PKCS12_clear(crypto_PKCS12Obj *self);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050024
25static char crypto_PKCS12_get_certificate_doc[] = "\n\
26Return certificate portion of the PKCS12 structure\n\
27\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -040028@return: X509 object containing the certificate\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050029";
30static PyObject *
31crypto_PKCS12_get_certificate(crypto_PKCS12Obj *self, PyObject *args)
32{
33 if (!PyArg_ParseTuple(args, ":get_certificate"))
34 return NULL;
35
36 Py_INCREF(self->cert);
37 return self->cert;
38}
39
Rick Dean623ee362009-07-17 12:22:16 -050040static char crypto_PKCS12_set_certificate_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -050041Replace the certificate portion of the PKCS12 structure\n\
Rick Dean623ee362009-07-17 12:22:16 -050042\n\
Rick Deane182f482009-07-17 14:49:48 -050043@param cert: The new certificate.\n\
Jean-Paul Calderonebade3132009-07-24 21:27:13 -040044@type cert: L{X509} or L{NoneType}\n\
Rick Dean379917c2009-07-21 11:37:41 -050045@return: None\n\
Rick Dean623ee362009-07-17 12:22:16 -050046";
Rick Dean38a05c82009-07-18 01:41:30 -050047static PyObject *
Jean-Paul Calderonebade3132009-07-24 21:27:13 -040048crypto_PKCS12_set_certificate(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds) {
Rick Dean623ee362009-07-17 12:22:16 -050049 PyObject *cert = NULL;
50 static char *kwlist[] = {"cert", NULL};
51
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -040052 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_certificate",
Rick Dean623ee362009-07-17 12:22:16 -050053 kwlist, &cert))
54 return NULL;
55
Jean-Paul Calderonebade3132009-07-24 21:27:13 -040056 if (cert != Py_None && ! crypto_X509_Check(cert)) {
Rick Dean623ee362009-07-17 12:22:16 -050057 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() */
Rick Dean585cd9e2009-07-18 14:58:11 -050062 Py_DECREF(self->cert);
Rick Dean623ee362009-07-17 12:22:16 -050063 self->cert = cert;
64
Rick Dean38a05c82009-07-18 01:41:30 -050065 Py_INCREF(Py_None);
66 return Py_None;
Rick Dean623ee362009-07-17 12:22:16 -050067}
68
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050069static char crypto_PKCS12_get_privatekey_doc[] = "\n\
70Return private key portion of the PKCS12 structure\n\
71\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -040072@returns: PKey object containing the private key\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050073";
Rick Dean623ee362009-07-17 12:22:16 -050074static crypto_PKeyObj *
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050075crypto_PKCS12_get_privatekey(crypto_PKCS12Obj *self, PyObject *args)
76{
77 if (!PyArg_ParseTuple(args, ":get_privatekey"))
78 return NULL;
79
80 Py_INCREF(self->key);
Rick Dean864e15e2009-07-17 15:21:23 -050081 return (crypto_PKeyObj *) self->key;
Rick Dean623ee362009-07-17 12:22:16 -050082}
83
84static char crypto_PKCS12_set_privatekey_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -050085Replace or set the certificate portion of the PKCS12 structure\n\
Rick Dean623ee362009-07-17 12:22:16 -050086\n\
Rick Deane182f482009-07-17 14:49:48 -050087@param pkey: The new private key.\n\
88@type pkey: L{PKey}\n\
89@return: None\n\
Rick Dean623ee362009-07-17 12:22:16 -050090";
Rick Dean38a05c82009-07-18 01:41:30 -050091static PyObject *
Jean-Paul Calderoned8665432009-07-24 21:28:52 -040092crypto_PKCS12_set_privatekey(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds) {
Rick Dean623ee362009-07-17 12:22:16 -050093 PyObject *pkey = NULL;
94 static char *kwlist[] = {"pkey", NULL};
95
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -040096 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_privatekey",
Rick Dean623ee362009-07-17 12:22:16 -050097 kwlist, &pkey))
98 return NULL;
99
Jean-Paul Calderoned8665432009-07-24 21:28:52 -0400100 if (pkey != Py_None && ! crypto_PKey_Check(pkey)) {
Rick Dean623ee362009-07-17 12:22:16 -0500101 PyErr_SetString(PyExc_TypeError, "pkey must be type X509 or None");
102 return NULL;
103 }
104
105 Py_INCREF(pkey); /* Make consistent before calling Py_DECREF() */
Rick Dean585cd9e2009-07-18 14:58:11 -0500106 Py_DECREF(self->key);
Rick Dean623ee362009-07-17 12:22:16 -0500107 self->key = pkey;
108
Rick Dean38a05c82009-07-18 01:41:30 -0500109 Py_INCREF(Py_None);
110 return Py_None;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500111}
112
113static char crypto_PKCS12_get_ca_certificates_doc[] = "\n\
114Return CA certificates within of the PKCS12 object\n\
115\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400116@return: A newly created tuple containing the CA certificates in the chain,\n\
117 if any are present, or None if no CA certificates are present.\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500118";
119static PyObject *
120crypto_PKCS12_get_ca_certificates(crypto_PKCS12Obj *self, PyObject *args)
121{
122 if (!PyArg_ParseTuple(args, ":get_ca_certificates"))
123 return NULL;
124
125 Py_INCREF(self->cacerts);
126 return self->cacerts;
127}
128
Rick Dean623ee362009-07-17 12:22:16 -0500129static char crypto_PKCS12_set_ca_certificates_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -0500130Replace or set the CA certificates withing the PKCS12 object.\n\
Rick Dean623ee362009-07-17 12:22:16 -0500131\n\
Rick Deane182f482009-07-17 14:49:48 -0500132@param cacerts: The new CA certificates.\n\
Jean-Paul Calderoned8665432009-07-24 21:28:52 -0400133@type cacerts: Iterable of L{X509} or L{NoneType}\n\
Rick Deane182f482009-07-17 14:49:48 -0500134@return: None\n\
Rick Dean623ee362009-07-17 12:22:16 -0500135";
Rick Dean38a05c82009-07-18 01:41:30 -0500136static PyObject *
Rick Dean623ee362009-07-17 12:22:16 -0500137crypto_PKCS12_set_ca_certificates(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
138{
Jean-Paul Calderone499fa1d2009-07-24 21:15:30 -0400139 PyObject *obj;
Rick Dean623ee362009-07-17 12:22:16 -0500140 PyObject *cacerts;
141 static char *kwlist[] = {"cacerts", NULL};
Rick Dean25bcc1f2009-07-20 11:53:13 -0500142 int i, len; /* Py_ssize_t for Python 2.5+ */
Rick Dean623ee362009-07-17 12:22:16 -0500143
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400144 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_ca_certificates",
Rick Dean623ee362009-07-17 12:22:16 -0500145 kwlist, &cacerts))
146 return NULL;
147 if (cacerts == Py_None) {
Rick Deane84d1462009-07-24 09:27:01 -0500148 Py_INCREF(cacerts);
Jean-Paul Calderone206c2272009-07-24 21:22:38 -0400149 } else {
150 /* It's iterable */
Rick Deane84d1462009-07-24 09:27:01 -0500151 cacerts = PySequence_Tuple(cacerts);
Jean-Paul Calderone206c2272009-07-24 21:22:38 -0400152 if (cacerts == NULL) {
Rick Deane84d1462009-07-24 09:27:01 -0500153 return NULL;
154 }
Jean-Paul Calderone206c2272009-07-24 21:22:38 -0400155 len = PyTuple_Size(cacerts);
156
Rick Dean48305252009-07-18 15:28:38 -0500157 /* Check is's a simple list filled only with X509 objects. */
Jean-Paul Calderone206c2272009-07-24 21:22:38 -0400158 for (i = 0; i < len; i++) {
Jean-Paul Calderone4c6b72e2009-07-24 21:18:51 -0400159 obj = PyTuple_GetItem(cacerts, i);
Jean-Paul Calderonefed4d152009-07-24 21:23:57 -0400160 if (!crypto_X509_Check(obj)) {
Rick Deane84d1462009-07-24 09:27:01 -0500161 Py_DECREF(cacerts);
Rick Deane84d1462009-07-24 09:27:01 -0500162 PyErr_SetString(PyExc_TypeError, "iterable must only contain X509Type");
Rick Dean623ee362009-07-17 12:22:16 -0500163 return NULL;
164 }
Rick Dean623ee362009-07-17 12:22:16 -0500165 }
Rick Dean623ee362009-07-17 12:22:16 -0500166 }
167
Rick Dean585cd9e2009-07-18 14:58:11 -0500168 Py_DECREF(self->cacerts);
Rick Dean623ee362009-07-17 12:22:16 -0500169 self->cacerts = cacerts;
170
Rick Dean38a05c82009-07-18 01:41:30 -0500171 Py_INCREF(Py_None);
172 return Py_None;
Rick Dean623ee362009-07-17 12:22:16 -0500173}
174
Rick Dean42d69e12009-07-20 11:36:08 -0500175static char crypto_PKCS12_get_friendlyname_doc[] = "\n\
176Return friendly name portion of the PKCS12 structure\n\
177\n\
178@returns: String containing the friendlyname\n\
179";
Rick Dean99251c22009-07-24 09:32:46 -0500180static PyObject *
Jean-Paul Calderone4a45cbc2009-07-24 21:41:12 -0400181crypto_PKCS12_get_friendlyname(crypto_PKCS12Obj *self, PyObject *args) {
Rick Dean42d69e12009-07-20 11:36:08 -0500182 if (!PyArg_ParseTuple(args, ":get_friendlyname"))
183 return NULL;
184
185 Py_INCREF(self->friendlyname);
Rick Dean99251c22009-07-24 09:32:46 -0500186 return (PyObject *) self->friendlyname;
Rick Dean42d69e12009-07-20 11:36:08 -0500187}
188
189static char crypto_PKCS12_set_friendlyname_doc[] = "\n\
190Replace or set the certificate portion of the PKCS12 structure\n\
191\n\
192@param name: The new friendly name.\n\
193@type name: L{str}\n\
194@return: None\n\
195";
196static PyObject *
Jean-Paul Calderone4a45cbc2009-07-24 21:41:12 -0400197crypto_PKCS12_set_friendlyname(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds) {
Rick Dean42d69e12009-07-20 11:36:08 -0500198 PyObject *name = NULL;
199 static char *kwlist[] = {"name", NULL};
200
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400201 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_friendlyname",
Rick Dean42d69e12009-07-20 11:36:08 -0500202 kwlist, &name))
203 return NULL;
204
Jean-Paul Calderone2f6c66f2010-08-11 19:53:43 -0400205 if (name != Py_None && ! PyBytes_CheckExact(name)) {
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400206 PyErr_SetString(PyExc_TypeError, "name must be a byte string or None");
Rick Dean42d69e12009-07-20 11:36:08 -0500207 return NULL;
208 }
209
210 Py_INCREF(name); /* Make consistent before calling Py_DECREF() */
211 Py_DECREF(self->friendlyname);
212 self->friendlyname = name;
213
214 Py_INCREF(Py_None);
215 return Py_None;
216}
217
Rick Dean623ee362009-07-17 12:22:16 -0500218static char crypto_PKCS12_export_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -0500219export([passphrase=None][, friendly_name=None][, iter=2048][, maciter=1]\n\
220Dump a PKCS12 object as a string. See also \"man PKCS12_create\".\n\
Rick Dean623ee362009-07-17 12:22:16 -0500221\n\
Rick Deane182f482009-07-17 14:49:48 -0500222@param passphrase: used to encrypt the PKCS12\n\
223@type passphrase: L{str}\n\
Rick Deane182f482009-07-17 14:49:48 -0500224@param iter: How many times to repeat the encryption\n\
225@type iter: L{int}\n\
226@param maciter: How many times to repeat the MAC\n\
227@type maciter: L{int}\n\
228@return: The string containing the PKCS12\n\
Rick Dean623ee362009-07-17 12:22:16 -0500229";
Rick Dean623ee362009-07-17 12:22:16 -0500230static PyObject *
Jean-Paul Calderone4a45cbc2009-07-24 21:41:12 -0400231crypto_PKCS12_export(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds) {
232 int i; /* Py_ssize_t for Python 2.5+ */
233 PyObject *obj;
Rick Dean623ee362009-07-17 12:22:16 -0500234 int buf_len;
235 PyObject *buffer;
236 char *temp, *passphrase = NULL, *friendly_name = NULL;
237 BIO *bio;
238 PKCS12 *p12;
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400239 EVP_PKEY *pkey = NULL;
Rick Dean623ee362009-07-17 12:22:16 -0500240 STACK_OF(X509) *cacerts = NULL;
241 X509 *x509 = NULL;
Rick Deane182f482009-07-17 14:49:48 -0500242 int iter = 0; /* defaults to PKCS12_DEFAULT_ITER */
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400243 int maciter = 0;
Rick Dean42d69e12009-07-20 11:36:08 -0500244 static char *kwlist[] = {"passphrase", "iter", "maciter", NULL};
Rick Dean623ee362009-07-17 12:22:16 -0500245
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400246 if (!PyArg_ParseTupleAndKeywords(args, keywds, "|zii:export",
Rick Dean42d69e12009-07-20 11:36:08 -0500247 kwlist, &passphrase, &iter, &maciter))
Rick Dean623ee362009-07-17 12:22:16 -0500248 return NULL;
249
Rick Dean585cd9e2009-07-18 14:58:11 -0500250 if (self->key != Py_None) {
Rick Dean623ee362009-07-17 12:22:16 -0500251 pkey = ((crypto_PKeyObj*) self->key)->pkey;
252 }
Rick Dean585cd9e2009-07-18 14:58:11 -0500253 if (self->cert != Py_None) {
Rick Dean623ee362009-07-17 12:22:16 -0500254 x509 = ((crypto_X509Obj*) self->cert)->x509;
255 }
Rick Dean585cd9e2009-07-18 14:58:11 -0500256 if (self->cacerts != Py_None) {
Rick Dean8fefeb02009-07-24 10:56:29 -0500257 cacerts = sk_X509_new_null();
Jean-Paul Calderone4a45cbc2009-07-24 21:41:12 -0400258 for (i = 0; i < PyTuple_Size(self->cacerts); i++) { /* For each CA cert */
Rick Dean623ee362009-07-17 12:22:16 -0500259 obj = PySequence_GetItem(self->cacerts, i);
260 /* assert(PyObject_IsInstance(obj, (PyObject *) &crypto_X509_Type )); */
261 sk_X509_push(cacerts, (( crypto_X509Obj* ) obj)->x509);
262 Py_DECREF(obj);
263 }
264 }
Rick Dean42d69e12009-07-20 11:36:08 -0500265 if (self->friendlyname != Py_None) {
Jean-Paul Calderone2f6c66f2010-08-11 19:53:43 -0400266 friendly_name = PyBytes_AsString(self->friendlyname);
Rick Dean42d69e12009-07-20 11:36:08 -0500267 }
Rick Dean623ee362009-07-17 12:22:16 -0500268
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400269 p12 = PKCS12_create(passphrase, friendly_name, pkey, x509, cacerts,
Rick Dean623ee362009-07-17 12:22:16 -0500270 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
271 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
272 iter, maciter, 0);
Rick Dean8fefeb02009-07-24 10:56:29 -0500273 sk_X509_free(cacerts); /* NULL safe. Free just the container. */
Jean-Paul Calderone4a45cbc2009-07-24 21:41:12 -0400274 if (p12 == NULL) {
Rick Dean623ee362009-07-17 12:22:16 -0500275 exception_from_error_queue(crypto_Error);
276 return NULL;
277 }
278 bio = BIO_new(BIO_s_mem());
279 i2d_PKCS12_bio(bio, p12);
280 buf_len = BIO_get_mem_data(bio, &temp);
Jean-Paul Calderone2f6c66f2010-08-11 19:53:43 -0400281 buffer = PyBytes_FromStringAndSize(temp, buf_len);
Rick Dean623ee362009-07-17 12:22:16 -0500282 BIO_free(bio);
283 return buffer;
284}
285
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500286/*
287 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
288 * { 'name', (PyCFunction)crypto_PKCS12_name, METH_VARARGS, crypto_PKCS12_name_doc }
289 * for convenience
290 */
291#define ADD_METHOD(name) \
292 { #name, (PyCFunction)crypto_PKCS12_##name, METH_VARARGS, crypto_PKCS12_##name##_doc }
Rick Dean623ee362009-07-17 12:22:16 -0500293#define ADD_KW_METHOD(name) \
294 { #name, (PyCFunction)crypto_PKCS12_##name, METH_VARARGS | METH_KEYWORDS, crypto_PKCS12_##name##_doc }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500295static PyMethodDef crypto_PKCS12_methods[] =
296{
297 ADD_METHOD(get_certificate),
Rick Dean623ee362009-07-17 12:22:16 -0500298 ADD_KW_METHOD(set_certificate),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500299 ADD_METHOD(get_privatekey),
Rick Dean623ee362009-07-17 12:22:16 -0500300 ADD_KW_METHOD(set_privatekey),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500301 ADD_METHOD(get_ca_certificates),
Rick Dean623ee362009-07-17 12:22:16 -0500302 ADD_KW_METHOD(set_ca_certificates),
Rick Dean42d69e12009-07-20 11:36:08 -0500303 ADD_METHOD(get_friendlyname),
304 ADD_KW_METHOD(set_friendlyname),
Rick Dean623ee362009-07-17 12:22:16 -0500305 ADD_KW_METHOD(export),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500306 { NULL, NULL }
307};
308#undef ADD_METHOD
309
310/*
311 * Constructor for PKCS12 objects, never called by Python code directly.
312 * The strategy for this object is to create all the Python objects
313 * corresponding to the cert/key/CA certs right away
314 *
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400315 * Arguments: p12 - A "real" PKCS12 object or NULL
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500316 * passphrase - Passphrase to use when decrypting the PKCS12 object
317 * Returns: The newly created PKCS12 object
318 */
319crypto_PKCS12Obj *
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400320crypto_PKCS12_New(PKCS12 *p12, char *passphrase) {
Jean-Paul Calderonee58415f2009-07-24 21:12:45 -0400321 crypto_PKCS12Obj *self = NULL;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500322 PyObject *cacertobj = NULL;
323
Jean-Paul Calderoneb96d13e2009-07-25 11:33:22 -0400324 unsigned char *alias_str;
325 int alias_len;
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400326
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500327 X509 *cert = NULL;
328 EVP_PKEY *pkey = NULL;
329 STACK_OF(X509) *cacerts = NULL;
330
331 int i, cacert_count = 0;
332
333 /* allocate space for the CA cert stack */
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400334 if((cacerts = sk_X509_new_null()) == NULL) {
Rick Deanaace5e92009-07-24 10:44:49 -0500335 goto error; /* out of memory? */
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400336 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500337
338 /* parse the PKCS12 lump */
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400339 if (p12 && !PKCS12_parse(p12, passphrase, &pkey, &cert, &cacerts)) {
Jean-Paul Calderone7426ed82009-07-25 21:19:23 -0400340 /*
341 * If PKCS12_parse fails, and it allocated cacerts, it seems to free
342 * cacerts, but not re-NULL the pointer. Zounds! Make sure it is
343 * re-set to NULL here, else we'll have a double-free below.
344 */
345 cacerts = NULL;
Rick Deand369c932009-07-08 11:48:33 -0500346 exception_from_error_queue(crypto_Error);
Rick Deanee568302009-07-24 09:56:29 -0500347 goto error;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500348 }
349
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400350 if (!(self = PyObject_GC_New(crypto_PKCS12Obj, &crypto_PKCS12_Type))) {
Rick Deanee568302009-07-24 09:56:29 -0500351 goto error;
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400352 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500353
Rick Dean8fefeb02009-07-24 10:56:29 -0500354 /* client certificate and friendlyName */
Rick Dean623ee362009-07-17 12:22:16 -0500355 if (cert == NULL) {
356 Py_INCREF(Py_None);
357 self->cert = Py_None;
Rick Dean42d69e12009-07-20 11:36:08 -0500358 Py_INCREF(Py_None);
359 self->friendlyname = Py_None;
Rick Dean623ee362009-07-17 12:22:16 -0500360 } else {
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400361 if ((self->cert = (PyObject *)crypto_X509_New(cert, 1)) == NULL) {
Rick Dean623ee362009-07-17 12:22:16 -0500362 goto error;
Jean-Paul Calderone32eb0312009-07-25 11:15:55 -0400363 }
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400364
Rick Dean42d69e12009-07-20 11:36:08 -0500365 /* Now we need to extract the friendlyName of the PKCS12
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400366 * that was stored by PKCS_parse() in the alias of the
Rick Dean42d69e12009-07-20 11:36:08 -0500367 * certificate. */
Jean-Paul Calderoneb96d13e2009-07-25 11:33:22 -0400368 alias_str = X509_alias_get0(cert, &alias_len);
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400369 if (alias_str) {
Jean-Paul Calderone40dd0992010-08-22 17:52:07 -0400370 self->friendlyname = Py_BuildValue(BYTESTRING_FMT "#", alias_str, alias_len);
Jean-Paul Calderoneadd7bf02010-08-22 17:38:30 -0400371 if (!self->friendlyname) {
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400372 /*
373 * XXX Untested
374 */
375 goto error;
376 }
Rick Dean42d69e12009-07-20 11:36:08 -0500377 /* success */
378 } else {
379 Py_INCREF(Py_None);
380 self->friendlyname = Py_None;
381 }
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400382 }
Rick Dean8fefeb02009-07-24 10:56:29 -0500383
384 /* private key */
Rick Dean623ee362009-07-17 12:22:16 -0500385 if (pkey == NULL) {
386 Py_INCREF(Py_None);
387 self->key = Py_None;
388 } else {
389 if ((self->key = (PyObject *)crypto_PKey_New(pkey, 1)) == NULL)
390 goto error;
391 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500392
Rick Dean8fefeb02009-07-24 10:56:29 -0500393 /* CA certs */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500394 cacert_count = sk_X509_num(cacerts);
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400395 if (cacert_count <= 0) {
Rick Deanaace5e92009-07-24 10:44:49 -0500396 Py_INCREF(Py_None);
397 self->cacerts = Py_None;
398 } else {
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400399 if ((self->cacerts = PyTuple_New(cacert_count)) == NULL) {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500400 goto error;
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400401 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500402
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400403 for (i = 0; i < cacert_count; i++) {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500404 cert = sk_X509_value(cacerts, i);
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400405 if ((cacertobj = (PyObject *)crypto_X509_New(cert, 1)) == NULL) {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500406 goto error;
Jean-Paul Calderone304866b2009-07-25 12:03:55 -0400407 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500408 PyTuple_SET_ITEM(self->cacerts, i, cacertobj);
409 }
410 }
411
Rick Dean8fefeb02009-07-24 10:56:29 -0500412 sk_X509_free(cacerts); /* Don't free the certs, just the container. */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500413 PyObject_GC_Track(self);
414
415 return self;
Rick Deanee568302009-07-24 09:56:29 -0500416
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500417error:
Rick Dean8fefeb02009-07-24 10:56:29 -0500418 sk_X509_free(cacerts); /* NULL safe. Free just the container. */
Jean-Paul Calderoned0a98762009-07-25 21:23:01 -0400419 if (self) {
420 crypto_PKCS12_clear(self);
421 PyObject_GC_Del(self);
422 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500423 return NULL;
424}
425
Rick Deancbeaca02009-07-17 12:50:12 -0500426static char crypto_PKCS12_doc[] = "\n\
427PKCS12() -> PKCS12 instance\n\
428\n\
Rick Deane182f482009-07-17 14:49:48 -0500429Create a new empty PKCS12 object.\n\
Rick Deancbeaca02009-07-17 12:50:12 -0500430\n\
431@returns: The PKCS12 object\n\
432";
433static PyObject *
Jean-Paul Calderoneb1a3af12009-07-25 12:21:18 -0400434crypto_PKCS12_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) {
Rick Deancbeaca02009-07-17 12:50:12 -0500435 if (!PyArg_ParseTuple(args, ":PKCS12")) {
436 return NULL;
437 }
438
439 return (PyObject *)crypto_PKCS12_New(NULL, NULL);
440}
441
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500442/*
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500443 * Call the visitproc on all contained objects.
444 *
445 * Arguments: self - The PKCS12 object
446 * visit - Function to call
447 * arg - Extra argument to visit
448 * Returns: 0 if all goes well, otherwise the return code from the first
449 * call that gave non-zero result.
450 */
451static int
452crypto_PKCS12_traverse(crypto_PKCS12Obj *self, visitproc visit, void *arg)
453{
454 int ret = 0;
455
456 if (ret == 0 && self->cert != NULL)
457 ret = visit(self->cert, arg);
458 if (ret == 0 && self->key != NULL)
459 ret = visit(self->key, arg);
460 if (ret == 0 && self->cacerts != NULL)
461 ret = visit(self->cacerts, arg);
Rick Dean42d69e12009-07-20 11:36:08 -0500462 if (ret == 0 && self->friendlyname != NULL)
463 ret = visit(self->friendlyname, arg);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500464 return ret;
465}
466
467/*
468 * Decref all contained objects and zero the pointers.
469 *
470 * Arguments: self - The PKCS12 object
471 * Returns: Always 0.
472 */
473static int
474crypto_PKCS12_clear(crypto_PKCS12Obj *self)
475{
476 Py_XDECREF(self->cert);
477 self->cert = NULL;
478 Py_XDECREF(self->key);
479 self->key = NULL;
480 Py_XDECREF(self->cacerts);
481 self->cacerts = NULL;
Rick Dean42d69e12009-07-20 11:36:08 -0500482 Py_XDECREF(self->friendlyname);
483 self->friendlyname = NULL;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500484 return 0;
485}
486
487/*
488 * Deallocate the memory used by the PKCS12 object
489 *
490 * Arguments: self - The PKCS12 object
491 * Returns: None
492 */
493static void
494crypto_PKCS12_dealloc(crypto_PKCS12Obj *self)
495{
496 PyObject_GC_UnTrack(self);
497 crypto_PKCS12_clear(self);
498 PyObject_GC_Del(self);
499}
500
501PyTypeObject crypto_PKCS12_Type = {
Jean-Paul Calderone3fe7f672010-08-11 23:55:10 -0400502 PyOpenSSL_HEAD_INIT(&PyType_Type, 0)
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500503 "PKCS12",
504 sizeof(crypto_PKCS12Obj),
505 0,
506 (destructor)crypto_PKCS12_dealloc,
507 NULL, /* print */
Jean-Paul Calderone2f6c66f2010-08-11 19:53:43 -0400508 NULL, /* getattr */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500509 NULL, /* setattr */
510 NULL, /* compare */
511 NULL, /* repr */
512 NULL, /* as_number */
513 NULL, /* as_sequence */
514 NULL, /* as_mapping */
515 NULL, /* hash */
516 NULL, /* call */
517 NULL, /* str */
518 NULL, /* getattro */
519 NULL, /* setattro */
520 NULL, /* as_buffer */
521 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400522 crypto_PKCS12_doc,
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500523 (traverseproc)crypto_PKCS12_traverse,
524 (inquiry)crypto_PKCS12_clear,
Rick Deancbeaca02009-07-17 12:50:12 -0500525 NULL, /* tp_richcompare */
526 0, /* tp_weaklistoffset */
527 NULL, /* tp_iter */
528 NULL, /* tp_iternext */
529 crypto_PKCS12_methods, /* tp_methods */
530 NULL, /* tp_members */
531 NULL, /* tp_getset */
532 NULL, /* tp_base */
533 NULL, /* tp_dict */
534 NULL, /* tp_descr_get */
535 NULL, /* tp_descr_set */
536 0, /* tp_dictoffset */
537 NULL, /* tp_init */
538 NULL, /* tp_alloc */
539 crypto_PKCS12_new, /* tp_new */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500540};
541
542/*
543 * Initialize the PKCS12 part of the crypto sub module
544 *
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400545 * Arguments: module - The crypto module
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500546 * Returns: None
547 */
548int
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400549init_crypto_pkcs12(PyObject *module) {
550 if (PyType_Ready(&crypto_PKCS12_Type) < 0) {
551 return 0;
552 }
553
Rick Deancbeaca02009-07-17 12:50:12 -0500554 if (PyModule_AddObject(module, "PKCS12", (PyObject *)&crypto_PKCS12_Type) != 0) {
555 return 0;
556 }
557
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400558 if (PyModule_AddObject(module, "PKCS12Type", (PyObject *)&crypto_PKCS12_Type) != 0) {
559 return 0;
560 }
561
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500562 return 1;
563}