6 #define strcasecmp(string1, string2) _stricmp(string1, string2)
9 /* http://www.openssl.org/docs/apps/x509v3_config.html#CRL_distribution_points_ */
10 /* which differs from crl_reasons of crypto/x509v3/v3_enum.c that matches */
11 /* OCSP_crl_reason_str. We use the latter, just like the command line program. */
12 static const char *crl_reasons[] = {
18 "cessationOfOperation",
24 #define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
26 static char crypto_Revoked_all_reasons_doc[] = "\n\
27 Return a list of all the supported reason strings.\n\
29 @return: A list of reason strings.\n\
32 crypto_Revoked_all_reasons(crypto_RevokedObj *self, PyObject *args) {
37 for (j = 0; j < NUM_REASONS; j++) {
39 str = PyBytes_FromString(crl_reasons[j]);
40 PyList_Append(list, str);
48 X509_EXTENSION_value_to_PyString(X509_EXTENSION *ex) {
54 /* Create a openssl BIO buffer */
55 bio = BIO_new(BIO_s_mem());
60 /* These are not the droids you are looking for. */
61 if (!X509V3_EXT_print(bio, ex, 0, 0)) {
62 if (M_ASN1_OCTET_STRING_print(bio, ex->value) == 0) {
67 /* Convert to a Python string. */
68 str_len = BIO_get_mem_data(bio, &tmp_str);
69 str = PyBytes_FromStringAndSize(tmp_str, str_len);
86 delete_reason(STACK_OF(X509_EXTENSION) *sk) {
90 for (j = 0; j < sk_X509_EXTENSION_num(sk); j++) {
91 ext = sk_X509_EXTENSION_value(sk, j);
92 if (OBJ_obj2nid(ext->object) == NID_crl_reason) {
93 X509_EXTENSION_free(ext);
94 (void) sk_X509_EXTENSION_delete(sk, j);
101 reason_str_to_code(const char * reason_str) {
102 int reason_code = -1, j;
103 char *spaceless_reason, * sp;
105 /* Remove spaces so that the responses of
106 * get_reason() work in set_reason() */
107 if ((spaceless_reason = strdup(reason_str)) == NULL) {
111 while ((sp = strchr(spaceless_reason, ' '))) {
112 memmove(sp, sp+1, strlen(sp));
115 for (j = 0; j < NUM_REASONS; j++) {
116 if(crl_reasons[j] && !strcasecmp(spaceless_reason, crl_reasons[j])) {
121 free(spaceless_reason);
126 static char crypto_Revoked_set_reason_doc[] = "\n\
127 Set the reason of a Revoked object.\n\
129 @param reason: The reason string.\n\
130 @type reason: L{str}\n\
134 crypto_Revoked_set_reason(crypto_RevokedObj *self, PyObject *args, PyObject *keywds) {
135 static char *kwlist[] = {"reason", NULL};
136 const char *reason_str = NULL;
138 ASN1_ENUMERATED *rtmp = NULL;
140 if (!PyArg_ParseTupleAndKeywords(
141 args, keywds, "O&:set_reason", kwlist,
142 crypto_byte_converter, &reason_str)) {
146 if(reason_str == NULL) {
147 delete_reason(self->revoked->extensions);
151 reason_code = reason_str_to_code(reason_str);
152 if (reason_code == -1) {
153 PyErr_SetString(PyExc_ValueError, "bad reason string");
157 rtmp = ASN1_ENUMERATED_new();
158 if (!rtmp || !ASN1_ENUMERATED_set(rtmp, reason_code)) {
161 delete_reason(self->revoked->extensions);
162 if (!X509_REVOKED_add1_ext_i2d(self->revoked, NID_crl_reason, rtmp, 0, 0)) {
171 exception_from_error_queue(crypto_Error);
176 static char crypto_Revoked_get_reason_doc[] = "\n\
177 Return the reason of a Revoked object.\n\
179 @return: The reason as a string\n\
182 crypto_Revoked_get_reason(crypto_RevokedObj *self, PyObject *args) {
183 X509_EXTENSION * ext;
185 STACK_OF(X509_EXTENSION) *sk = NULL;
187 if (!PyArg_ParseTuple(args, ":get_reason")) {
191 sk = self->revoked->extensions;
192 for (j = 0; j < sk_X509_EXTENSION_num(sk); j++) {
193 ext = sk_X509_EXTENSION_value(sk, j);
194 if (OBJ_obj2nid(ext->object) == NID_crl_reason) {
195 return X509_EXTENSION_value_to_PyString(ext);
204 static char crypto_Revoked_get_rev_date_doc[] = "\n\
205 Retrieve the revocation date\n\
207 @return: A string giving the timestamp, in the format:\n\
210 YYYYMMDDhhmmss+hhmm\n\
211 YYYYMMDDhhmmss-hhmm\n\
215 crypto_Revoked_get_rev_date(crypto_RevokedObj *self, PyObject *args) {
216 /* returns a borrowed reference. */
217 return _get_asn1_time(
218 ":get_rev_date", self->revoked->revocationDate, args);
221 static char crypto_Revoked_set_rev_date_doc[] = "\n\
222 Set the revocation timestamp\n\
224 @param when: A string giving the timestamp, in the format:\n\
227 YYYYMMDDhhmmss+hhmm\n\
228 YYYYMMDDhhmmss-hhmm\n\
234 crypto_Revoked_set_rev_date(crypto_RevokedObj *self, PyObject *args) {
235 return _set_asn1_time(
236 BYTESTRING_FMT ":set_rev_date", self->revoked->revocationDate, args);
239 /* The integer is converted to an upper-case hex string
240 * without a '0x' prefix. */
242 ASN1_INTEGER_to_PyString(ASN1_INTEGER *asn1_int) {
244 PyObject *str = NULL;
248 /* Create a openssl BIO buffer */
249 bio = BIO_new(BIO_s_mem());
254 /* Write the integer to the BIO as a hex string. */
255 if (i2a_ASN1_INTEGER(bio, asn1_int) < 0) {
259 /* Convert to a Python string. */
260 str_len = BIO_get_mem_data(bio, &tmp_str);
261 str = PyBytes_FromStringAndSize(tmp_str, str_len);
278 static char crypto_Revoked_get_serial_doc[] = "\n\
279 Return the serial number of a Revoked structure\n\
281 @return: The serial number as a string\n\
284 crypto_Revoked_get_serial(crypto_RevokedObj *self, PyObject *args) {
285 if (!PyArg_ParseTuple(args, ":get_serial")) {
289 if (self->revoked->serialNumber == NULL) {
294 return ASN1_INTEGER_to_PyString(self->revoked->serialNumber);
298 static char crypto_Revoked_set_serial_doc[] = "\n\
299 Set the serial number of a revoked Revoked structure\n\
301 @param hex_str: The new serial number.\n\
302 @type hex_str: L{str}\n\
306 crypto_Revoked_set_serial(crypto_RevokedObj *self, PyObject *args, PyObject *keywds) {
307 static char *kwlist[] = {"hex_str", NULL};
308 const char *hex_str = NULL;
309 BIGNUM *serial = NULL;
310 ASN1_INTEGER *tmpser = NULL;
312 if (!PyArg_ParseTupleAndKeywords(args, keywds, BYTESTRING_FMT ":set_serial",
317 if (!BN_hex2bn(&serial, hex_str) ) {
318 PyErr_SetString(PyExc_ValueError, "bad hex string");
322 tmpser = BN_to_ASN1_INTEGER(serial, NULL);
325 X509_REVOKED_set_serialNumber(self->revoked, tmpser);
326 ASN1_INTEGER_free(tmpser);
334 crypto_Revoked_New(X509_REVOKED *revoked) {
335 crypto_RevokedObj *self;
337 self = PyObject_New(crypto_RevokedObj, &crypto_Revoked_Type);
341 self->revoked = revoked;
346 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
347 * { 'name', (PyCFunction)crypto_Revoked_name, METH_VARARGS, crypto_Revoked_name_doc }
350 #define ADD_METHOD(name) \
351 { #name, (PyCFunction)crypto_Revoked_##name, METH_VARARGS, crypto_Revoked_##name##_doc }
352 #define ADD_KW_METHOD(name) \
353 { #name, (PyCFunction)crypto_Revoked_##name, METH_VARARGS | METH_KEYWORDS, crypto_Revoked_##name##_doc }
354 static PyMethodDef crypto_Revoked_methods[] = {
355 ADD_METHOD(all_reasons),
356 ADD_METHOD(get_reason),
357 ADD_KW_METHOD(set_reason),
358 ADD_METHOD(get_rev_date),
359 ADD_METHOD(set_rev_date),
360 ADD_METHOD(get_serial),
361 ADD_KW_METHOD(set_serial),
368 crypto_Revoked_dealloc(crypto_RevokedObj *self) {
369 X509_REVOKED_free(self->revoked);
370 self->revoked = NULL;
375 static char crypto_Revoked_doc[] = "\n\
376 Revoked() -> Revoked instance\n\
378 Create a new empty Revoked object.\n\
380 @returns: The Revoked object\n\
383 static PyObject* crypto_Revoked_new(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) {
384 if (!PyArg_ParseTuple(args, ":Revoked")) {
388 return (PyObject *)crypto_Revoked_New(X509_REVOKED_new());
391 PyTypeObject crypto_Revoked_Type = {
392 PyOpenSSL_HEAD_INIT(&PyType_Type, 0)
394 sizeof(crypto_RevokedObj),
396 (destructor)crypto_Revoked_dealloc,
402 NULL, /* as_number */
403 NULL, /* as_sequence */
404 NULL, /* as_mapping */
410 NULL, /* as_buffer */
412 crypto_Revoked_doc, /* doc */
415 NULL, /* tp_richcompare */
416 0, /* tp_weaklistoffset */
418 NULL, /* tp_iternext */
419 crypto_Revoked_methods, /* tp_methods */
420 NULL, /* tp_members */
421 NULL, /* tp_getset */
424 NULL, /* tp_descr_get */
425 NULL, /* tp_descr_set */
426 0, /* tp_dictoffset */
429 crypto_Revoked_new, /* tp_new */
432 int init_crypto_revoked(PyObject *module) {
433 if(PyType_Ready(&crypto_Revoked_Type) < 0) {
437 if (PyModule_AddObject(module, "Revoked", (PyObject *)&crypto_Revoked_Type) != 0) {