blob: 614a6061aa65df4970d99d06f9c2e5313003e37b [file] [log] [blame]
#include <Python.h>
#define crypto_MODULE
#include "crypto.h"
static X509_REVOKED * X509_REVOKED_dup(X509_REVOKED *orig) {
X509_REVOKED *dupe = NULL;
dupe = X509_REVOKED_new();
if (dupe == NULL) {
return NULL;
}
if (orig->serialNumber) {
dupe->serialNumber = M_ASN1_INTEGER_dup(orig->serialNumber);
}
if (orig->revocationDate) {
dupe->revocationDate = M_ASN1_INTEGER_dup(orig->revocationDate);
}
if (orig->extensions) {
STACK_OF(X509_EXTENSION) *sk = NULL;
X509_EXTENSION * ext;
int j;
sk = sk_X509_EXTENSION_new_null();
for (j = 0; j < sk_X509_EXTENSION_num(orig->extensions); j++) {
ext = sk_X509_EXTENSION_value(orig->extensions, j);
ext = X509_EXTENSION_dup(ext);
sk_X509_EXTENSION_push(sk, ext);
}
dupe->extensions = sk;
}
dupe->sequence = orig->sequence;
return dupe;
}
static char crypto_CRL_get_revoked_doc[] = "\n\
Return revoked portion of the CRL structure (by value\n\
not reference).\n\
\n\
:return: A tuple of Revoked objects.\n\
";
static PyObject *
crypto_CRL_get_revoked(crypto_CRLObj *self, PyObject *args) {
int j, num_rev;
X509_REVOKED *r = NULL;
PyObject *obj = NULL, *rev_obj;
if (!PyArg_ParseTuple(args, ":get_revoked")) {
return NULL;
}
num_rev = sk_X509_REVOKED_num(self->crl->crl->revoked);
if (num_rev < 0) {
Py_INCREF(Py_None);
return Py_None;
}
if ((obj = PyTuple_New(num_rev)) == NULL) {
return NULL;
}
for (j = 0; j < num_rev; j++) {
r = sk_X509_REVOKED_value(self->crl->crl->revoked, j);
r = X509_REVOKED_dup(r);
if (r == NULL ) {
goto error;
}
rev_obj = (PyObject *) crypto_Revoked_New(r);
if (rev_obj == NULL) {
goto error;
}
r = NULL; /* it's now owned by rev_obj */
PyTuple_SET_ITEM(obj, j, rev_obj);
}
return obj;
error:
if (r) {
X509_REVOKED_free(r);
}
Py_XDECREF(obj);
return NULL;
}
static char crypto_CRL_add_revoked_doc[] = "\n\
Add a revoked (by value not reference) to the CRL structure\n\
\n\
:param cert: The new revoked.\n\
:type cert: :class:`X509`\n\
:return: None\n\
";
static PyObject *
crypto_CRL_add_revoked(crypto_CRLObj *self, PyObject *args, PyObject *keywds) {
crypto_RevokedObj * rev_obj = NULL;
static char *kwlist[] = {"revoked", NULL};
X509_REVOKED * dup;
if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!:add_revoked",
kwlist, &crypto_Revoked_Type, &rev_obj)) {
return NULL;
}
dup = X509_REVOKED_dup( rev_obj->revoked );
if (dup == NULL) {
return NULL;
}
X509_CRL_add0_revoked(self->crl, dup);
Py_INCREF(Py_None);
return Py_None;
}
static char crypto_CRL_export_doc[] = "\n\
export(cert, key[, type[, days]]) -> export a CRL as a string\n\
\n\
:param cert: Used to sign CRL.\n\
:type cert: :class:`X509`\n\
:param key: Used to sign CRL.\n\
:type key: :class:`PKey`\n\
:param type: The export format, either :py:data:`FILETYPE_PEM`, :py:data:`FILETYPE_ASN1`, or :py:data:`FILETYPE_TEXT`.\n\
:param days: The number of days until the next update of this CRL.\n\
:type days: :py:data:`int`\n\
:return: :py:data:`str`\n\
";
static PyObject *
crypto_CRL_export(crypto_CRLObj *self, PyObject *args, PyObject *keywds) {
int ret, buf_len, type = X509_FILETYPE_PEM, days = 100;
char *temp;
BIO *bio;
PyObject *buffer;
crypto_PKeyObj *key;
ASN1_TIME *tmptm;
crypto_X509Obj *x509;
static char *kwlist[] = {"cert", "key", "type", "days", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "O!O!|ii:dump_crl", kwlist,
&crypto_X509_Type, &x509,
&crypto_PKey_Type, &key, &type, &days)) {
return NULL;
}
bio = BIO_new(BIO_s_mem());
tmptm = ASN1_TIME_new();
if (!tmptm) {
return 0;
}
X509_gmtime_adj(tmptm,0);
X509_CRL_set_lastUpdate(self->crl, tmptm);
X509_gmtime_adj(tmptm,days*24*60*60);
X509_CRL_set_nextUpdate(self->crl, tmptm);
ASN1_TIME_free(tmptm);
X509_CRL_set_issuer_name(self->crl, X509_get_subject_name(x509->x509));
if (!X509_CRL_sign(self->crl, key->pkey, EVP_md5())) {
exception_from_error_queue(crypto_Error);
BIO_free(bio);
return NULL;
}
switch (type) {
case X509_FILETYPE_PEM:
ret = PEM_write_bio_X509_CRL(bio, self->crl);
break;
case X509_FILETYPE_ASN1:
ret = (int) i2d_X509_CRL_bio(bio, self->crl);
break;
case X509_FILETYPE_TEXT:
ret = X509_CRL_print(bio, self->crl);
break;
default:
PyErr_SetString(
PyExc_ValueError,
"type argument must be FILETYPE_PEM, FILETYPE_ASN1, or FILETYPE_TEXT");
return NULL;
}
if (!ret) {
exception_from_error_queue(crypto_Error);
BIO_free(bio);
return NULL;
}
buf_len = BIO_get_mem_data(bio, &temp);
buffer = PyBytes_FromStringAndSize(temp, buf_len);
BIO_free(bio);
return buffer;
}
crypto_CRLObj *
crypto_CRL_New(X509_CRL *crl) {
crypto_CRLObj *self;
self = PyObject_New(crypto_CRLObj, &crypto_CRL_Type);
if (self == NULL) {
return NULL;
}
self->crl = crl;
return self;
}
/*
* ADD_METHOD(name) expands to a correct PyMethodDef declaration
* { 'name', (PyCFunction)crypto_CRL_name, METH_VARARGS, crypto_CRL_name_doc }
* for convenience
*/
#define ADD_METHOD(name) \
{ #name, (PyCFunction)crypto_CRL_##name, METH_VARARGS, crypto_CRL_##name##_doc }
#define ADD_KW_METHOD(name) \
{ #name, (PyCFunction)crypto_CRL_##name, METH_VARARGS | METH_KEYWORDS, crypto_CRL_##name##_doc }
static PyMethodDef crypto_CRL_methods[] = {
ADD_KW_METHOD(add_revoked),
ADD_METHOD(get_revoked),
ADD_KW_METHOD(export),
{ NULL, NULL }
};
#undef ADD_METHOD
static void
crypto_CRL_dealloc(crypto_CRLObj *self) {
X509_CRL_free(self->crl);
self->crl = NULL;
PyObject_Del(self);
}
static char crypto_CRL_doc[] = "\n\
CRL() -> CRL instance\n\
\n\
Create a new empty CRL object.\n\
\n\
:returns: The CRL object\n\
";
static PyObject* crypto_CRL_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) {
if (!PyArg_ParseTuple(args, ":CRL")) {
return NULL;
}
return (PyObject *)crypto_CRL_New(X509_CRL_new());
}
PyTypeObject crypto_CRL_Type = {
PyOpenSSL_HEAD_INIT(&PyType_Type, 0)
"CRL",
sizeof(crypto_CRLObj),
0,
(destructor)crypto_CRL_dealloc,
NULL, /* print */
NULL, /* getattr */
NULL, /* setattr */
NULL, /* compare */
NULL, /* repr */
NULL, /* as_number */
NULL, /* as_sequence */
NULL, /* as_mapping */
NULL, /* hash */
NULL, /* call */
NULL, /* str */
NULL, /* getattro */
NULL, /* setattro */
NULL, /* as_buffer */
Py_TPFLAGS_DEFAULT,
crypto_CRL_doc, /* doc */
NULL, /* traverse */
NULL, /* clear */
NULL, /* tp_richcompare */
0, /* tp_weaklistoffset */
NULL, /* tp_iter */
NULL, /* tp_iternext */
crypto_CRL_methods, /* tp_methods */
NULL, /* tp_members */
NULL, /* tp_getset */
NULL, /* tp_base */
NULL, /* tp_dict */
NULL, /* tp_descr_get */
NULL, /* tp_descr_set */
0, /* tp_dictoffset */
NULL, /* tp_init */
NULL, /* tp_alloc */
crypto_CRL_new, /* tp_new */
};
int init_crypto_crl(PyObject *module) {
if (PyType_Ready(&crypto_CRL_Type) < 0) {
return 0;
}
/* PyModule_AddObject steals a reference.
*/
Py_INCREF((PyObject *)&crypto_CRL_Type);
if (PyModule_AddObject(module, "CRL", (PyObject *)&crypto_CRL_Type) != 0) {
return 0;
}
return 1;
}