blob: f93b3c03cf6894d24054c60b09333f9b9b871af5 [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\
43@type cert: L{X509}\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 *
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
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 Calderonee7901d72009-07-24 18:21:26 -040056 if (cert != Py_None && ! PyObject_IsInstance(cert, (PyObject *) &crypto_X509_Type)) {
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 *
Rick Dean623ee362009-07-17 12:22:16 -050092crypto_PKCS12_set_privatekey(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
93{
94 PyObject *pkey = NULL;
95 static char *kwlist[] = {"pkey", NULL};
96
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -040097 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_privatekey",
Rick Dean623ee362009-07-17 12:22:16 -050098 kwlist, &pkey))
99 return NULL;
100
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400101 if (pkey != Py_None && ! PyObject_IsInstance(pkey, (PyObject *) &crypto_PKey_Type)) {
Rick Dean623ee362009-07-17 12:22:16 -0500102 PyErr_SetString(PyExc_TypeError, "pkey must be type X509 or None");
103 return NULL;
104 }
105
106 Py_INCREF(pkey); /* Make consistent before calling Py_DECREF() */
Rick Dean585cd9e2009-07-18 14:58:11 -0500107 Py_DECREF(self->key);
Rick Dean623ee362009-07-17 12:22:16 -0500108 self->key = pkey;
109
Rick Dean38a05c82009-07-18 01:41:30 -0500110 Py_INCREF(Py_None);
111 return Py_None;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500112}
113
114static char crypto_PKCS12_get_ca_certificates_doc[] = "\n\
115Return CA certificates within of the PKCS12 object\n\
116\n\
Jean-Paul Calderone54bcc832009-05-27 14:06:48 -0400117@return: A newly created tuple containing the CA certificates in the chain,\n\
118 if any are present, or None if no CA certificates are present.\n\
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500119";
120static PyObject *
121crypto_PKCS12_get_ca_certificates(crypto_PKCS12Obj *self, PyObject *args)
122{
123 if (!PyArg_ParseTuple(args, ":get_ca_certificates"))
124 return NULL;
125
126 Py_INCREF(self->cacerts);
127 return self->cacerts;
128}
129
Rick Dean623ee362009-07-17 12:22:16 -0500130static char crypto_PKCS12_set_ca_certificates_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -0500131Replace or set the CA certificates withing the PKCS12 object.\n\
Rick Dean623ee362009-07-17 12:22:16 -0500132\n\
Rick Deane182f482009-07-17 14:49:48 -0500133@param cacerts: The new CA certificates.\n\
134@type cacerts: Sequence of L{X509}\n\
135@return: None\n\
Rick Dean623ee362009-07-17 12:22:16 -0500136";
Rick Dean38a05c82009-07-18 01:41:30 -0500137static PyObject *
Rick Dean623ee362009-07-17 12:22:16 -0500138crypto_PKCS12_set_ca_certificates(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
139{
Jean-Paul Calderone499fa1d2009-07-24 21:15:30 -0400140 PyObject *obj;
Rick Dean623ee362009-07-17 12:22:16 -0500141 PyObject *cacerts;
142 static char *kwlist[] = {"cacerts", NULL};
Rick Dean25bcc1f2009-07-20 11:53:13 -0500143 int i, len; /* Py_ssize_t for Python 2.5+ */
Rick Dean623ee362009-07-17 12:22:16 -0500144
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400145 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_ca_certificates",
Rick Dean623ee362009-07-17 12:22:16 -0500146 kwlist, &cacerts))
147 return NULL;
148 if (cacerts == Py_None) {
Rick Deane84d1462009-07-24 09:27:01 -0500149 Py_INCREF(cacerts);
Rick Dean25bcc1f2009-07-20 11:53:13 -0500150 } else if ((len = PySequence_Length(cacerts)) >= 0) { /* is iterable */
Rick Deane84d1462009-07-24 09:27:01 -0500151 cacerts = PySequence_Tuple(cacerts);
152 if(cacerts == NULL) {
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400153 PyErr_SetString(PyExc_TypeError, "untupleable" /* failed to convert cacerts to a tuple */);
Rick Deane84d1462009-07-24 09:27:01 -0500154 return NULL;
155 }
Rick Dean48305252009-07-18 15:28:38 -0500156 /* Check is's a simple list filled only with X509 objects. */
Rick Dean25bcc1f2009-07-20 11:53:13 -0500157 for(i = 0;i < len;i++) { /* For each CA cert */
Rick Dean623ee362009-07-17 12:22:16 -0500158 obj = PySequence_GetItem(cacerts, i);
Rick Dean25bcc1f2009-07-20 11:53:13 -0500159 if(obj == NULL) {
160 break;
161 }
Rick Dean623ee362009-07-17 12:22:16 -0500162 if (PyObject_Type(obj) != (PyObject *) &crypto_X509_Type) {
Rick Deane84d1462009-07-24 09:27:01 -0500163 Py_DECREF(cacerts);
Rick Dean623ee362009-07-17 12:22:16 -0500164 Py_DECREF(obj);
Rick Deane84d1462009-07-24 09:27:01 -0500165 PyErr_SetString(PyExc_TypeError, "iterable must only contain X509Type");
Rick Dean623ee362009-07-17 12:22:16 -0500166 return NULL;
167 }
168 Py_DECREF(obj);
169 }
170 } else {
Rick Deane84d1462009-07-24 09:27:01 -0500171 PyErr_SetString(PyExc_TypeError, "must be iterable or None");
Rick Dean623ee362009-07-17 12:22:16 -0500172 return NULL;
173 }
174
Rick Dean585cd9e2009-07-18 14:58:11 -0500175 Py_DECREF(self->cacerts);
Rick Dean623ee362009-07-17 12:22:16 -0500176 self->cacerts = cacerts;
177
Rick Dean38a05c82009-07-18 01:41:30 -0500178 Py_INCREF(Py_None);
179 return Py_None;
Rick Dean623ee362009-07-17 12:22:16 -0500180}
181
Rick Dean42d69e12009-07-20 11:36:08 -0500182static char crypto_PKCS12_get_friendlyname_doc[] = "\n\
183Return friendly name portion of the PKCS12 structure\n\
184\n\
185@returns: String containing the friendlyname\n\
186";
Rick Dean99251c22009-07-24 09:32:46 -0500187static PyObject *
Rick Dean42d69e12009-07-20 11:36:08 -0500188crypto_PKCS12_get_friendlyname(crypto_PKCS12Obj *self, PyObject *args)
189{
190 if (!PyArg_ParseTuple(args, ":get_friendlyname"))
191 return NULL;
192
193 Py_INCREF(self->friendlyname);
Rick Dean99251c22009-07-24 09:32:46 -0500194 return (PyObject *) self->friendlyname;
Rick Dean42d69e12009-07-20 11:36:08 -0500195}
196
197static char crypto_PKCS12_set_friendlyname_doc[] = "\n\
198Replace or set the certificate portion of the PKCS12 structure\n\
199\n\
200@param name: The new friendly name.\n\
201@type name: L{str}\n\
202@return: None\n\
203";
204static PyObject *
205crypto_PKCS12_set_friendlyname(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
206{
207 PyObject *name = NULL;
208 static char *kwlist[] = {"name", NULL};
209
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400210 if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_friendlyname",
Rick Dean42d69e12009-07-20 11:36:08 -0500211 kwlist, &name))
212 return NULL;
213
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400214 if (name != Py_None && ! PyString_CheckExact(name)) {
Rick Dean37273112009-07-24 09:38:17 -0500215 PyErr_SetString(PyExc_TypeError, "name must be a str or None");
Rick Dean42d69e12009-07-20 11:36:08 -0500216 return NULL;
217 }
218
219 Py_INCREF(name); /* Make consistent before calling Py_DECREF() */
220 Py_DECREF(self->friendlyname);
221 self->friendlyname = name;
222
223 Py_INCREF(Py_None);
224 return Py_None;
225}
226
Rick Dean623ee362009-07-17 12:22:16 -0500227static char crypto_PKCS12_export_doc[] = "\n\
Rick Deane182f482009-07-17 14:49:48 -0500228export([passphrase=None][, friendly_name=None][, iter=2048][, maciter=1]\n\
229Dump a PKCS12 object as a string. See also \"man PKCS12_create\".\n\
Rick Dean623ee362009-07-17 12:22:16 -0500230\n\
Rick Deane182f482009-07-17 14:49:48 -0500231@param passphrase: used to encrypt the PKCS12\n\
232@type passphrase: L{str}\n\
Rick Deane182f482009-07-17 14:49:48 -0500233@param iter: How many times to repeat the encryption\n\
234@type iter: L{int}\n\
235@param maciter: How many times to repeat the MAC\n\
236@type maciter: L{int}\n\
237@return: The string containing the PKCS12\n\
Rick Dean623ee362009-07-17 12:22:16 -0500238";
Rick Dean623ee362009-07-17 12:22:16 -0500239static PyObject *
240crypto_PKCS12_export(crypto_PKCS12Obj *self, PyObject *args, PyObject *keywds)
241{
242 int buf_len;
243 PyObject *buffer;
244 char *temp, *passphrase = NULL, *friendly_name = NULL;
245 BIO *bio;
246 PKCS12 *p12;
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400247 EVP_PKEY *pkey = NULL;
Rick Dean623ee362009-07-17 12:22:16 -0500248 STACK_OF(X509) *cacerts = NULL;
249 X509 *x509 = NULL;
Rick Deane182f482009-07-17 14:49:48 -0500250 int iter = 0; /* defaults to PKCS12_DEFAULT_ITER */
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400251 int maciter = 0;
Rick Dean42d69e12009-07-20 11:36:08 -0500252 static char *kwlist[] = {"passphrase", "iter", "maciter", NULL};
Rick Dean623ee362009-07-17 12:22:16 -0500253
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400254 if (!PyArg_ParseTupleAndKeywords(args, keywds, "|zii:export",
Rick Dean42d69e12009-07-20 11:36:08 -0500255 kwlist, &passphrase, &iter, &maciter))
Rick Dean623ee362009-07-17 12:22:16 -0500256 return NULL;
257
Rick Dean585cd9e2009-07-18 14:58:11 -0500258 if (self->key != Py_None) {
Rick Dean623ee362009-07-17 12:22:16 -0500259 pkey = ((crypto_PKeyObj*) self->key)->pkey;
260 }
Rick Dean585cd9e2009-07-18 14:58:11 -0500261 if (self->cert != Py_None) {
Rick Dean623ee362009-07-17 12:22:16 -0500262 x509 = ((crypto_X509Obj*) self->cert)->x509;
263 }
Rick Dean585cd9e2009-07-18 14:58:11 -0500264 if (self->cacerts != Py_None) {
Rick Dean864e15e2009-07-17 15:21:23 -0500265 int i; /* Py_ssize_t for Python 2.5+ */
Rick Dean623ee362009-07-17 12:22:16 -0500266 PyObject *obj;
Rick Dean8fefeb02009-07-24 10:56:29 -0500267 cacerts = sk_X509_new_null();
Rick Dean623ee362009-07-17 12:22:16 -0500268 for(i = 0;i < PySequence_Length(self->cacerts);i++) { /* For each CA cert */
269 obj = PySequence_GetItem(self->cacerts, i);
270 /* assert(PyObject_IsInstance(obj, (PyObject *) &crypto_X509_Type )); */
271 sk_X509_push(cacerts, (( crypto_X509Obj* ) obj)->x509);
272 Py_DECREF(obj);
273 }
274 }
Rick Dean42d69e12009-07-20 11:36:08 -0500275 if (self->friendlyname != Py_None) {
276 friendly_name = PyString_AsString(self->friendlyname);
277 }
Rick Dean623ee362009-07-17 12:22:16 -0500278
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400279 p12 = PKCS12_create(passphrase, friendly_name, pkey, x509, cacerts,
Rick Dean623ee362009-07-17 12:22:16 -0500280 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
281 NID_pbe_WithSHA1And3_Key_TripleDES_CBC,
282 iter, maciter, 0);
Rick Dean8fefeb02009-07-24 10:56:29 -0500283 sk_X509_free(cacerts); /* NULL safe. Free just the container. */
Rick Dean623ee362009-07-17 12:22:16 -0500284 if( p12 == NULL ) {
285 exception_from_error_queue(crypto_Error);
286 return NULL;
287 }
288 bio = BIO_new(BIO_s_mem());
289 i2d_PKCS12_bio(bio, p12);
290 buf_len = BIO_get_mem_data(bio, &temp);
291 buffer = PyString_FromStringAndSize(temp, buf_len);
292 BIO_free(bio);
293 return buffer;
294}
295
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500296/*
297 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
298 * { 'name', (PyCFunction)crypto_PKCS12_name, METH_VARARGS, crypto_PKCS12_name_doc }
299 * for convenience
300 */
301#define ADD_METHOD(name) \
302 { #name, (PyCFunction)crypto_PKCS12_##name, METH_VARARGS, crypto_PKCS12_##name##_doc }
Rick Dean623ee362009-07-17 12:22:16 -0500303#define ADD_KW_METHOD(name) \
304 { #name, (PyCFunction)crypto_PKCS12_##name, METH_VARARGS | METH_KEYWORDS, crypto_PKCS12_##name##_doc }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500305static PyMethodDef crypto_PKCS12_methods[] =
306{
307 ADD_METHOD(get_certificate),
Rick Dean623ee362009-07-17 12:22:16 -0500308 ADD_KW_METHOD(set_certificate),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500309 ADD_METHOD(get_privatekey),
Rick Dean623ee362009-07-17 12:22:16 -0500310 ADD_KW_METHOD(set_privatekey),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500311 ADD_METHOD(get_ca_certificates),
Rick Dean623ee362009-07-17 12:22:16 -0500312 ADD_KW_METHOD(set_ca_certificates),
Rick Dean42d69e12009-07-20 11:36:08 -0500313 ADD_METHOD(get_friendlyname),
314 ADD_KW_METHOD(set_friendlyname),
Rick Dean623ee362009-07-17 12:22:16 -0500315 ADD_KW_METHOD(export),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500316 { NULL, NULL }
317};
318#undef ADD_METHOD
319
320/*
321 * Constructor for PKCS12 objects, never called by Python code directly.
322 * The strategy for this object is to create all the Python objects
323 * corresponding to the cert/key/CA certs right away
324 *
325 * Arguments: p12 - A "real" PKCS12 object
326 * passphrase - Passphrase to use when decrypting the PKCS12 object
327 * Returns: The newly created PKCS12 object
328 */
329crypto_PKCS12Obj *
330crypto_PKCS12_New(PKCS12 *p12, char *passphrase)
331{
Jean-Paul Calderonee58415f2009-07-24 21:12:45 -0400332 crypto_PKCS12Obj *self = NULL;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500333 PyObject *cacertobj = NULL;
334
335 X509 *cert = NULL;
336 EVP_PKEY *pkey = NULL;
337 STACK_OF(X509) *cacerts = NULL;
338
339 int i, cacert_count = 0;
340
341 /* allocate space for the CA cert stack */
Rick Deanaace5e92009-07-24 10:44:49 -0500342 if((cacerts = sk_X509_new_null()) == NULL)
343 goto error; /* out of memory? */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500344
345 /* parse the PKCS12 lump */
Rick Deanaace5e92009-07-24 10:44:49 -0500346 if (p12 && !PKCS12_parse(p12, passphrase, &pkey, &cert, &cacerts))
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500347 {
Rick Deand369c932009-07-08 11:48:33 -0500348 exception_from_error_queue(crypto_Error);
Rick Deanee568302009-07-24 09:56:29 -0500349 goto error;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500350 }
351
352 if (!(self = PyObject_GC_New(crypto_PKCS12Obj, &crypto_PKCS12_Type)))
Rick Deanee568302009-07-24 09:56:29 -0500353 goto error;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500354
Rick Dean8fefeb02009-07-24 10:56:29 -0500355 /* client certificate and friendlyName */
Rick Dean623ee362009-07-17 12:22:16 -0500356 if (cert == NULL) {
357 Py_INCREF(Py_None);
358 self->cert = Py_None;
Rick Dean42d69e12009-07-20 11:36:08 -0500359 Py_INCREF(Py_None);
360 self->friendlyname = Py_None;
Rick Dean623ee362009-07-17 12:22:16 -0500361 } else {
Rick Dean42d69e12009-07-20 11:36:08 -0500362 unsigned char *alstr;
363 int allen;
Rick Dean623ee362009-07-17 12:22:16 -0500364 if ((self->cert = (PyObject *)crypto_X509_New(cert, 1)) == NULL)
365 goto error;
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400366
Rick Dean42d69e12009-07-20 11:36:08 -0500367 /* Now we need to extract the friendlyName of the PKCS12
368 * that was stored by PKCS_pasrse() in the alias of the
369 * certificate. */
370 alstr = X509_alias_get0(cert, &allen);
371 if (alstr && (self->friendlyname = Py_BuildValue("s#", alstr, allen))){
372 /* success */
373 } else {
374 Py_INCREF(Py_None);
375 self->friendlyname = Py_None;
376 }
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400377 }
Rick Dean8fefeb02009-07-24 10:56:29 -0500378
379 /* private key */
Rick Dean623ee362009-07-17 12:22:16 -0500380 if (pkey == NULL) {
381 Py_INCREF(Py_None);
382 self->key = Py_None;
383 } else {
384 if ((self->key = (PyObject *)crypto_PKey_New(pkey, 1)) == NULL)
385 goto error;
386 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500387
Rick Dean8fefeb02009-07-24 10:56:29 -0500388 /* CA certs */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500389 cacert_count = sk_X509_num(cacerts);
Rick Deanaace5e92009-07-24 10:44:49 -0500390 if (cacert_count <= 0)
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500391 {
Rick Deanaace5e92009-07-24 10:44:49 -0500392 Py_INCREF(Py_None);
393 self->cacerts = Py_None;
394 } else {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500395 if ((self->cacerts = PyTuple_New(cacert_count)) == NULL)
396 goto error;
397
398 for (i = 0; i < cacert_count; i++)
399 {
400 cert = sk_X509_value(cacerts, i);
401 if ((cacertobj = (PyObject *)crypto_X509_New(cert, 1)) == NULL)
402 goto error;
403 PyTuple_SET_ITEM(self->cacerts, i, cacertobj);
404 }
405 }
406
Rick Dean8fefeb02009-07-24 10:56:29 -0500407 sk_X509_free(cacerts); /* Don't free the certs, just the container. */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500408 PyObject_GC_Track(self);
409
410 return self;
Rick Deanee568302009-07-24 09:56:29 -0500411
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500412error:
Rick Dean8fefeb02009-07-24 10:56:29 -0500413 sk_X509_free(cacerts); /* NULL safe. Free just the container. */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500414 crypto_PKCS12_dealloc(self);
415 return NULL;
416}
417
Rick Deancbeaca02009-07-17 12:50:12 -0500418static char crypto_PKCS12_doc[] = "\n\
419PKCS12() -> PKCS12 instance\n\
420\n\
Rick Deane182f482009-07-17 14:49:48 -0500421Create a new empty PKCS12 object.\n\
Rick Deancbeaca02009-07-17 12:50:12 -0500422\n\
423@returns: The PKCS12 object\n\
424";
425static PyObject *
426crypto_PKCS12_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs)
427{
428 if (!PyArg_ParseTuple(args, ":PKCS12")) {
429 return NULL;
430 }
431
432 return (PyObject *)crypto_PKCS12_New(NULL, NULL);
433}
434
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500435/*
436 * Find attribute
437 *
438 * Arguments: self - The PKCS12 object
439 * name - The attribute name
440 * Returns: A Python object for the attribute, or NULL if something went
441 * wrong
442 */
443static PyObject *
444crypto_PKCS12_getattr(crypto_PKCS12Obj *self, char *name)
445{
446 return Py_FindMethod(crypto_PKCS12_methods, (PyObject *)self, name);
447}
448
449/*
450 * Call the visitproc on all contained objects.
451 *
452 * Arguments: self - The PKCS12 object
453 * visit - Function to call
454 * arg - Extra argument to visit
455 * Returns: 0 if all goes well, otherwise the return code from the first
456 * call that gave non-zero result.
457 */
458static int
459crypto_PKCS12_traverse(crypto_PKCS12Obj *self, visitproc visit, void *arg)
460{
461 int ret = 0;
462
463 if (ret == 0 && self->cert != NULL)
464 ret = visit(self->cert, arg);
465 if (ret == 0 && self->key != NULL)
466 ret = visit(self->key, arg);
467 if (ret == 0 && self->cacerts != NULL)
468 ret = visit(self->cacerts, arg);
Rick Dean42d69e12009-07-20 11:36:08 -0500469 if (ret == 0 && self->friendlyname != NULL)
470 ret = visit(self->friendlyname, arg);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500471 return ret;
472}
473
474/*
475 * Decref all contained objects and zero the pointers.
476 *
477 * Arguments: self - The PKCS12 object
478 * Returns: Always 0.
479 */
480static int
481crypto_PKCS12_clear(crypto_PKCS12Obj *self)
482{
483 Py_XDECREF(self->cert);
484 self->cert = NULL;
485 Py_XDECREF(self->key);
486 self->key = NULL;
487 Py_XDECREF(self->cacerts);
488 self->cacerts = NULL;
Rick Dean42d69e12009-07-20 11:36:08 -0500489 Py_XDECREF(self->friendlyname);
490 self->friendlyname = NULL;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500491 return 0;
492}
493
494/*
495 * Deallocate the memory used by the PKCS12 object
496 *
497 * Arguments: self - The PKCS12 object
498 * Returns: None
499 */
500static void
501crypto_PKCS12_dealloc(crypto_PKCS12Obj *self)
502{
503 PyObject_GC_UnTrack(self);
504 crypto_PKCS12_clear(self);
505 PyObject_GC_Del(self);
506}
507
508PyTypeObject crypto_PKCS12_Type = {
509 PyObject_HEAD_INIT(NULL)
510 0,
511 "PKCS12",
512 sizeof(crypto_PKCS12Obj),
513 0,
514 (destructor)crypto_PKCS12_dealloc,
515 NULL, /* print */
516 (getattrfunc)crypto_PKCS12_getattr,
517 NULL, /* setattr */
518 NULL, /* compare */
519 NULL, /* repr */
520 NULL, /* as_number */
521 NULL, /* as_sequence */
522 NULL, /* as_mapping */
523 NULL, /* hash */
524 NULL, /* call */
525 NULL, /* str */
526 NULL, /* getattro */
527 NULL, /* setattro */
528 NULL, /* as_buffer */
529 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
Jean-Paul Calderonee7901d72009-07-24 18:21:26 -0400530 crypto_PKCS12_doc,
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500531 (traverseproc)crypto_PKCS12_traverse,
532 (inquiry)crypto_PKCS12_clear,
Rick Deancbeaca02009-07-17 12:50:12 -0500533 NULL, /* tp_richcompare */
534 0, /* tp_weaklistoffset */
535 NULL, /* tp_iter */
536 NULL, /* tp_iternext */
537 crypto_PKCS12_methods, /* tp_methods */
538 NULL, /* tp_members */
539 NULL, /* tp_getset */
540 NULL, /* tp_base */
541 NULL, /* tp_dict */
542 NULL, /* tp_descr_get */
543 NULL, /* tp_descr_set */
544 0, /* tp_dictoffset */
545 NULL, /* tp_init */
546 NULL, /* tp_alloc */
547 crypto_PKCS12_new, /* tp_new */
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500548};
549
550/*
551 * Initialize the PKCS12 part of the crypto sub module
552 *
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400553 * Arguments: module - The crypto module
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500554 * Returns: None
555 */
556int
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400557init_crypto_pkcs12(PyObject *module) {
558 if (PyType_Ready(&crypto_PKCS12_Type) < 0) {
559 return 0;
560 }
561
Rick Deancbeaca02009-07-17 12:50:12 -0500562 if (PyModule_AddObject(module, "PKCS12", (PyObject *)&crypto_PKCS12_Type) != 0) {
563 return 0;
564 }
565
Jean-Paul Calderonedc138fa2009-06-27 14:32:07 -0400566 if (PyModule_AddObject(module, "PKCS12Type", (PyObject *)&crypto_PKCS12_Type) != 0) {
567 return 0;
568 }
569
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500570 return 1;
571}