#include <Python.h>
#define crypto_MODULE
#include "crypto.h"
static char *CVSid = "@(#) $Id: pkcs12.c,v 1.2 2004/09/23 14:25:28 murata Exp $";
static void crypto_PKCS12_dealloc(crypto_PKCS12Obj *self);
static char crypto_PKCS12_get_certificate_doc[] = "\n\
Return certificate portion of the PKCS12 structure\n\
\n\
Arguments: self - The PKCS12 object\n\
args - The Python argument tuple, should be empty\n\
Returns: X509 object containing the certificate\n\
";
static PyObject *
crypto_PKCS12_get_certificate(crypto_PKCS12Obj *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":get_certificate"))
return NULL;
Py_INCREF(self->cert);
return self->cert;
}
static char crypto_PKCS12_get_privatekey_doc[] = "\n\
Return private key portion of the PKCS12 structure\n\
\n\
Arguments: self - The PKCS12 object\n\
args - The Python argument tuple, should be empty\n\
Returns: PKey object containing the private key\n\
";
static PyObject *
crypto_PKCS12_get_privatekey(crypto_PKCS12Obj *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":get_privatekey"))
return NULL;
Py_INCREF(self->key);
return self->key;
}
static char crypto_PKCS12_get_ca_certificates_doc[] = "\n\
Return CA certificates within of the PKCS12 object\n\
\n\
Arguments: self - The PKCS12 object\n\
args - The Python argument tuple, should be empty\n\
Returns: A newly created tuple containing the CA certificates in the chain,\n\
if any are present, or None if no CA certificates are present.\n\
";
static PyObject *
crypto_PKCS12_get_ca_certificates(crypto_PKCS12Obj *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, ":get_ca_certificates"))
return NULL;
Py_INCREF(self->cacerts);
return self->cacerts;
}
#define ADD_METHOD(name) \
{ #name, (PyCFunction)crypto_PKCS12_##name, METH_VARARGS, crypto_PKCS12_##name##_doc }
static PyMethodDef crypto_PKCS12_methods[] =
{
ADD_METHOD(get_certificate),
ADD_METHOD(get_privatekey),
ADD_METHOD(get_ca_certificates),
{ NULL, NULL }
};
#undef ADD_METHOD
crypto_PKCS12Obj *
crypto_PKCS12_New(PKCS12 *p12, char *passphrase)
{
crypto_PKCS12Obj *self;
PyObject *cacertobj = NULL;
X509 *cert = NULL;
EVP_PKEY *pkey = NULL;
STACK_OF(X509) *cacerts = NULL;
int i, cacert_count = 0;
cacerts = sk_X509_new_null();
if (!(cacerts && PKCS12_parse(p12, passphrase, &pkey, &cert, &cacerts)))
{
exception_from_error_queue();
return NULL;
}
if (!(self = PyObject_New(crypto_PKCS12Obj, &crypto_PKCS12_Type)))
return NULL;
self->cert = NULL;
self->key = NULL;
Py_INCREF(Py_None);
self->cacerts = Py_None;
if ((self->cert = (PyObject *)crypto_X509_New(cert, 1)) == NULL)
goto error;
if ((self->key = (PyObject *)crypto_PKey_New(pkey, 1)) == NULL)
goto error;
cacert_count = sk_X509_num(cacerts);
if (cacert_count > 0)
{
Py_DECREF(self->cacerts);
if ((self->cacerts = PyTuple_New(cacert_count)) == NULL)
goto error;
for (i = 0; i < cacert_count; i++)
{
cert = sk_X509_value(cacerts, i);
if ((cacertobj = (PyObject *)crypto_X509_New(cert, 1)) == NULL)
goto error;
PyTuple_SET_ITEM(self->cacerts, i, cacertobj);
}
}
sk_X509_free(cacerts);
return self;
error:
crypto_PKCS12_dealloc(self);
return NULL;
}
static void
crypto_PKCS12_dealloc(crypto_PKCS12Obj *self)
{
Py_XDECREF(self->cert);
Py_XDECREF(self->key);
Py_XDECREF(self->cacerts);
PyObject_Del(self);
}
static PyObject *
crypto_PKCS12_getattr(crypto_PKCS12Obj *self, char *name)
{
return Py_FindMethod(crypto_PKCS12_methods, (PyObject *)self, name);
}
PyTypeObject crypto_PKCS12_Type = {
PyObject_HEAD_INIT(NULL)
0,
"PKCS12",
sizeof(crypto_PKCS12Obj),
0,
(destructor)crypto_PKCS12_dealloc,
NULL,
(getattrfunc)crypto_PKCS12_getattr,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
int
init_crypto_pkcs12(PyObject *dict)
{
crypto_PKCS12_Type.ob_type = &PyType_Type;
Py_INCREF(&crypto_PKCS12_Type);
PyDict_SetItemString(dict, "PKCS12Type", (PyObject *)&crypto_PKCS12_Type);
return 1;
}