4 * Copyright (C) Jean-Paul Calderone
5 * See LICENSE for details.
7 * Export X.509 extension functions and data structures.
8 * See the file RATIONALE for a short explanation of why this module was written.
16 static char crypto_X509Extension_get_critical_doc[] = "\n\
17 Returns the critical field of the X509Extension\n\
19 @return: The critical field.\n\
23 crypto_X509Extension_get_critical(crypto_X509ExtensionObj *self, PyObject *args)
25 if (!PyArg_ParseTuple(args, ":get_critical"))
28 return PyLong_FromLong(X509_EXTENSION_get_critical(self->x509_extension));
31 static char crypto_X509Extension_get_short_name_doc[] = "\n\
32 Returns the short version of the type name of the X509Extension\n\
34 @return: The short type name.\n\
38 crypto_X509Extension_get_short_name(crypto_X509ExtensionObj *self, PyObject *args) {
42 if (!PyArg_ParseTuple(args, ":get_short_name")) {
46 /* Returns an internal pointer to x509_extension, not a copy */
47 obj = X509_EXTENSION_get_object(self->x509_extension);
49 extname = OBJ_nid2sn(OBJ_obj2nid(obj));
50 return PyBytes_FromString(extname);
54 static char crypto_X509Extension_get_data_doc[] = "\n\
55 Returns the data of the X509Extension\n\
57 @return: A C{str} giving the X509Extension's ASN.1 encoded data.\n\
61 crypto_X509Extension_get_data(crypto_X509ExtensionObj *self, PyObject *args) {
62 ASN1_OCTET_STRING *data;
65 if (!PyArg_ParseTuple(args, ":get_data")) {
69 data = X509_EXTENSION_get_data(self->x509_extension);
70 result = PyBytes_FromStringAndSize((const char*)data->data, data->length);
75 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
76 * { 'name', (PyCFunction)crypto_X509Extension_name, METH_VARARGS }
79 #define ADD_METHOD(name) \
80 { #name, (PyCFunction)crypto_X509Extension_##name, METH_VARARGS, crypto_X509Extension_##name##_doc }
81 static PyMethodDef crypto_X509Extension_methods[] =
83 ADD_METHOD(get_critical),
84 ADD_METHOD(get_short_name),
91 * Constructor for X509Extension, never called by Python code directly
93 * Arguments: type_name - ???
96 * subject - An x509v3 certificate which is the subject for this extension.
97 * issuer - An x509v3 certificate which is the issuer for this extension.
98 * Returns: The newly created X509Extension object
100 crypto_X509ExtensionObj *
101 crypto_X509Extension_New(char *type_name, int critical, char *value,
102 crypto_X509Obj *subject, crypto_X509Obj *issuer) {
104 crypto_X509ExtensionObj *self;
105 char* value_with_critical = NULL;
109 * A context is necessary for any extension which uses the r2i conversion
110 * method. That is, X509V3_EXT_nconf may segfault if passed a NULL ctx.
111 * Start off by initializing most of the fields to NULL.
113 X509V3_set_ctx(&ctx, NULL, NULL, NULL, NULL, 0);
116 * We have no configuration database - but perhaps we should (some
117 * extensions may require it).
119 X509V3_set_ctx_nodb(&ctx);
122 * Initialize the subject and issuer, if appropriate. ctx is a local, and
123 * as far as I can tell none of the X509V3_* APIs invoked here steal any
124 * references, so no need to incref subject or issuer.
127 ctx.subject_cert = subject->x509;
131 ctx.issuer_cert = issuer->x509;
134 self = PyObject_New(crypto_X509ExtensionObj, &crypto_X509Extension_Type);
142 /* There are other OpenSSL APIs which would let us pass in critical
143 * separately, but they're harder to use, and since value is already a pile
144 * of crappy junk smuggling a ton of utterly important structured data,
145 * what's the point of trying to avoid nasty stuff with strings? (However,
146 * X509V3_EXT_i2d in particular seems like it would be a better API to
147 * invoke. I do not know where to get the ext_struc it desires for its
148 * last parameter, though.) */
149 value_with_critical = malloc(strlen("critical,") + strlen(value) + 1);
150 if (!value_with_critical) {
151 goto critical_malloc_error;
155 strcpy(value_with_critical, "critical,");
156 strcpy(value_with_critical + strlen("critical,"), value);
158 strcpy(value_with_critical, value);
161 self->x509_extension = X509V3_EXT_nconf(
162 NULL, &ctx, type_name, value_with_critical);
164 free(value_with_critical);
166 if (!self->x509_extension) {
174 exception_from_error_queue(crypto_Error);
176 critical_malloc_error:
184 static char crypto_X509Extension_doc[] = "\n\
185 X509Extension(typename, critical, value[, subject][, issuer]) -> \n\
186 X509Extension instance\n\
188 @param typename: The name of the extension to create.\n\
189 @type typename: C{str}\n\
190 @param critical: A flag indicating whether this is a critical extension.\n\
191 @param value: The value of the extension.\n\
192 @type value: C{str}\n\
193 @param subject: Optional X509 cert to use as subject.\n\
194 @type subject: C{X509}\n\
195 @param issuer: Optional X509 cert to use as issuer.\n\
196 @type issuer: C{X509}\n\
197 @return: The X509Extension object\n\
201 crypto_X509Extension_new(PyTypeObject *subtype, PyObject *args,
203 char *type_name, *value;
205 crypto_X509Obj * subject = NULL;
206 crypto_X509Obj * issuer = NULL;
207 static char *kwlist[] = {"type_name", "critical", "value", "subject",
210 if (!PyArg_ParseTupleAndKeywords(
212 BYTESTRING_FMT "i" BYTESTRING_FMT "|O!O!:X509Extension",
213 kwlist, &type_name, &critical, &value,
214 &crypto_X509_Type, &subject,
215 &crypto_X509_Type, &issuer )) {
219 return (PyObject *)crypto_X509Extension_New(type_name, critical, value,
224 * Deallocate the memory used by the X509Extension object
226 * Arguments: self - The X509Extension object
230 crypto_X509Extension_dealloc(crypto_X509ExtensionObj *self)
232 /* Sometimes we don't have to dealloc this */
234 X509_EXTENSION_free(self->x509_extension);
240 * Print a nice text representation of the certificate request.
243 crypto_X509Extension_str(crypto_X509ExtensionObj *self)
248 BIO *bio = BIO_new(BIO_s_mem());
250 if (!X509V3_EXT_print(bio, self->x509_extension, 0, 0))
253 exception_from_error_queue(crypto_Error);
257 str_len = BIO_get_mem_data(bio, &tmp_str);
258 str = PyText_FromStringAndSize(tmp_str, str_len);
265 PyTypeObject crypto_X509Extension_Type = {
266 PyOpenSSL_HEAD_INIT(&PyType_Type, 0)
268 sizeof(crypto_X509ExtensionObj),
270 (destructor)crypto_X509Extension_dealloc,
273 NULL, /* setattr (setattrfunc)crypto_X509Name_setattr, */
276 NULL, /* as_number */
277 NULL, /* as_sequence */
278 NULL, /* as_mapping */
281 (reprfunc)crypto_X509Extension_str, /* str */
284 NULL, /* as_buffer */
286 crypto_X509Extension_doc, /* doc */
289 NULL, /* tp_richcompare */
290 0, /* tp_weaklistoffset */
292 NULL, /* tp_iternext */
293 crypto_X509Extension_methods, /* tp_methods */
294 NULL, /* tp_members */
295 NULL, /* tp_getset */
298 NULL, /* tp_descr_get */
299 NULL, /* tp_descr_set */
300 0, /* tp_dictoffset */
303 crypto_X509Extension_new, /* tp_new */
307 * Initialize the X509Extension part of the crypto module
309 * Arguments: dict - The crypto module
313 init_crypto_x509extension(PyObject *module)
315 if (PyType_Ready(&crypto_X509Extension_Type) < 0) {
319 if (PyModule_AddObject(module, "X509Extension",
320 (PyObject *)&crypto_X509Extension_Type) != 0) {
324 if (PyModule_AddObject(module, "X509ExtensionType",
325 (PyObject *)&crypto_X509Extension_Type) != 0) {