blob: ff1f3de2b5b16853bad04f5d68f123e7bd378230 [file] [log] [blame]
Jean-Paul Calderone897bc252008-02-18 20:50:23 -05001/*
2 * x509.c
3 *
4 * Copyright (C) AB Strakt 2001, All rights reserved
5 *
6 * Certificate (X.509) handling code, mostly thin wrappers around OpenSSL.
7 * See the file RATIONALE for a short explanation of why this module was written.
8 *
9 * Reviewed 2001-07-23
10 */
11#include <Python.h>
12#define crypto_MODULE
13#include "crypto.h"
14
15static char *CVSid = "@(#) $Id: x509.c,v 1.20 2004/08/10 10:37:31 martin Exp $";
16
Jean-Paul Calderone525ef802008-03-09 20:39:42 -040017/*
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050018 * X.509 is a standard for digital certificates. See e.g. the OpenSSL homepage
19 * http://www.openssl.org/ for more information
20 */
21
22static char crypto_X509_get_version_doc[] = "\n\
23Return version number of the certificate\n\
24\n\
25Arguments: self - The X509 object\n\
26 args - The Python argument tuple, should be empty\n\
27Returns: Version number as a Python integer\n\
28";
29
30static PyObject *
31crypto_X509_get_version(crypto_X509Obj *self, PyObject *args)
32{
33 if (!PyArg_ParseTuple(args, ":get_version"))
34 return NULL;
35
36 return PyInt_FromLong((long)X509_get_version(self->x509));
37}
38
39static char crypto_X509_set_version_doc[] = "\n\
40Set version number of the certificate\n\
41\n\
42Arguments: self - The X509 object\n\
43 args - The Python argument tuple, should be:\n\
44 version - The version number\n\
45Returns: None\n\
46";
47
48static PyObject *
49crypto_X509_set_version(crypto_X509Obj *self, PyObject *args)
50{
51 int version;
52
53 if (!PyArg_ParseTuple(args, "i:set_version", &version))
54 return NULL;
55
56 X509_set_version(self->x509, version);
57
58 Py_INCREF(Py_None);
59 return Py_None;
60}
61
62static char crypto_X509_get_serial_number_doc[] = "\n\
63Return serial number of the certificate\n\
64\n\
65Arguments: self - The X509 object\n\
66 args - The Python argument tuple, should be empty\n\
67Returns: Serial number as a Python integer\n\
68";
69
70static PyObject *
71crypto_X509_get_serial_number(crypto_X509Obj *self, PyObject *args)
72{
73 ASN1_INTEGER *asn1_i;
Jean-Paul Calderone78381d22008-03-06 23:35:22 -050074 BIGNUM *bignum;
75 char *hex;
76 PyObject *res;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050077
78 if (!PyArg_ParseTuple(args, ":get_serial_number"))
79 return NULL;
80
81 asn1_i = X509_get_serialNumber(self->x509);
Jean-Paul Calderone78381d22008-03-06 23:35:22 -050082 bignum = ASN1_INTEGER_to_BN(asn1_i, NULL);
83 hex = BN_bn2hex(bignum);
84 res = PyLong_FromString(hex, NULL, 16);
85 BN_free(bignum);
86 free(hex);
87 return res;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -050088}
89
90static char crypto_X509_set_serial_number_doc[] = "\n\
91Set serial number of the certificate\n\
92\n\
93Arguments: self - The X509 object\n\
94 args - The Python argument tuple, should be:\n\
95 serial - The serial number\n\
96Returns: None\n\
97";
98
99static PyObject *
100crypto_X509_set_serial_number(crypto_X509Obj *self, PyObject *args)
101{
Jean-Paul Calderone78381d22008-03-06 23:35:22 -0500102 long small_serial;
103 PyObject *serial = NULL;
104 PyObject *hex = NULL;
105 PyObject *format = NULL;
106 PyObject *format_args = NULL;
107 ASN1_INTEGER *asn1_i = NULL;
108 BIGNUM *bignum = NULL;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500109
Jean-Paul Calderone78381d22008-03-06 23:35:22 -0500110 if (!PyArg_ParseTuple(args, "O:set_serial_number", &serial)) {
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500111 return NULL;
Jean-Paul Calderone78381d22008-03-06 23:35:22 -0500112 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500113
Jean-Paul Calderone78381d22008-03-06 23:35:22 -0500114 if (!PyInt_Check(serial) && !PyLong_Check(serial)) {
115 PyErr_SetString(
116 PyExc_TypeError, "serial number must be integer");
117 goto err;
118 }
119
120 if ((format_args = Py_BuildValue("(O)", serial)) == NULL) {
121 goto err;
122 }
123
124 if ((format = PyString_FromString("%x")) == NULL) {
125 goto err;
126 }
127
128 if ((hex = PyString_Format(format, format_args)) == NULL) {
129 goto err;
130 }
131
132 /**
133 * BN_hex2bn stores the result in &bignum. Unless it doesn't feel like
134 * it. If bignum is still NULL after this call, then the return value
135 * is actually the result. I hope. -exarkun
136 */
137 small_serial = BN_hex2bn(&bignum, PyString_AsString(hex));
138
139 Py_DECREF(format_args);
140 format_args = NULL;
141 Py_DECREF(format);
142 format = NULL;
143 Py_DECREF(hex);
144 hex = NULL;
145
146 if (bignum == NULL) {
147 if (ASN1_INTEGER_set(X509_get_serialNumber(self->x509), small_serial)) {
148 exception_from_error_queue();
149 goto err;
150 }
151 } else {
152 asn1_i = BN_to_ASN1_INTEGER(bignum, NULL);
153 BN_free(bignum);
154 bignum = NULL;
155 if (asn1_i == NULL) {
156 exception_from_error_queue();
157 goto err;
158 }
159 if (!X509_set_serialNumber(self->x509, asn1_i)) {
160 exception_from_error_queue();
161 goto err;
162 }
163 ASN1_INTEGER_free(asn1_i);
164 asn1_i = NULL;
165 }
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500166
167 Py_INCREF(Py_None);
168 return Py_None;
Jean-Paul Calderone78381d22008-03-06 23:35:22 -0500169
170 err:
171 if (format_args) {
172 Py_DECREF(format_args);
173 }
174 if (format) {
175 Py_DECREF(format);
176 }
177 if (hex) {
178 Py_DECREF(hex);
179 }
180 if (bignum) {
181 BN_free(bignum);
182 }
183 if (asn1_i) {
184 ASN1_INTEGER_free(asn1_i);
185 }
186 return NULL;
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500187}
188
189static char crypto_X509_get_issuer_doc[] = "\n\
190Create an X509Name object for the issuer of the certificate\n\
191\n\
192Arguments: self - The X509 object\n\
193 args - The Python argument tuple, should be empty\n\
194Returns: An X509Name object\n\
195";
196
197static PyObject *
198crypto_X509_get_issuer(crypto_X509Obj *self, PyObject *args)
199{
200 crypto_X509NameObj *pyname;
201 X509_NAME *name;
202
203 if (!PyArg_ParseTuple(args, ":get_issuer"))
204 return NULL;
205
206 name = X509_get_issuer_name(self->x509);
207 pyname = crypto_X509Name_New(name, 0);
208 if (pyname != NULL)
209 {
210 pyname->parent_cert = (PyObject *)self;
211 Py_INCREF(self);
212 }
213 return (PyObject *)pyname;
214}
215
216static char crypto_X509_set_issuer_doc[] = "\n\
217Set the issuer of the certificate\n\
218\n\
219Arguments: self - The X509 object\n\
220 args - The Python argument tuple, should be:\n\
221 issuer - The issuer name\n\
222Returns: None\n\
223";
224
225static PyObject *
226crypto_X509_set_issuer(crypto_X509Obj *self, PyObject *args)
227{
228 crypto_X509NameObj *issuer;
229
230 if (!PyArg_ParseTuple(args, "O!:set_issuer", &crypto_X509Name_Type,
231 &issuer))
232 return NULL;
233
234 if (!X509_set_issuer_name(self->x509, issuer->x509_name))
235 {
236 exception_from_error_queue();
237 return NULL;
238 }
239
240 Py_INCREF(Py_None);
241 return Py_None;
242}
243
244static char crypto_X509_get_subject_doc[] = "\n\
245Create an X509Name object for the subject of the certificate\n\
246\n\
247Arguments: self - The X509 object\n\
248 args - The Python argument tuple, should be empty\n\
249Returns: An X509Name object\n\
250";
251
252static PyObject *
253crypto_X509_get_subject(crypto_X509Obj *self, PyObject *args)
254{
255 crypto_X509NameObj *pyname;
256 X509_NAME *name;
257
258 if (!PyArg_ParseTuple(args, ":get_subject"))
259 return NULL;
260
261 name = X509_get_subject_name(self->x509);
262 pyname = crypto_X509Name_New(name, 0);
263 if (pyname != NULL)
264 {
265 pyname->parent_cert = (PyObject *)self;
266 Py_INCREF(self);
267 }
268 return (PyObject *)pyname;
269}
270
271static char crypto_X509_set_subject_doc[] = "\n\
272Set the subject of the certificate\n\
273\n\
274Arguments: self - The X509 object\n\
275 args - The Python argument tuple, should be:\n\
276 subject - The subject name\n\
277Returns: None\n\
278";
279
280static PyObject *
281crypto_X509_set_subject(crypto_X509Obj *self, PyObject *args)
282{
283 crypto_X509NameObj *subject;
284
285 if (!PyArg_ParseTuple(args, "O!:set_subject", &crypto_X509Name_Type,
286 &subject))
287 return NULL;
288
289 if (!X509_set_subject_name(self->x509, subject->x509_name))
290 {
291 exception_from_error_queue();
292 return NULL;
293 }
294
295 Py_INCREF(Py_None);
296 return Py_None;
297}
298
299static char crypto_X509_get_pubkey_doc[] = "\n\
300Get the public key of the certificate\n\
301\n\
302Arguments: self - The X509 object\n\
303 args - The Python argument tuple, should be empty\n\
304Returns: The public key\n\
305";
306
307static PyObject *
308crypto_X509_get_pubkey(crypto_X509Obj *self, PyObject *args)
309{
310 crypto_PKeyObj *crypto_PKey_New(EVP_PKEY *, int);
311 EVP_PKEY *pkey;
312
313 if (!PyArg_ParseTuple(args, ":get_pubkey"))
314 return NULL;
315
316 if ((pkey = X509_get_pubkey(self->x509)) == NULL)
317 {
318 exception_from_error_queue();
319 return NULL;
320 }
321
Jean-Paul Calderone19555b92008-02-19 22:29:57 -0500322 return (PyObject *)crypto_PKey_New(pkey, 1);
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500323}
324
325static char crypto_X509_set_pubkey_doc[] = "\n\
326Set the public key of the certificate\n\
327\n\
328Arguments: self - The X509 object\n\
329 args - The Python argument tuple, should be:\n\
330 pkey - The public key\n\
331Returns: None\n\
332";
333
334static PyObject *
335crypto_X509_set_pubkey(crypto_X509Obj *self, PyObject *args)
336{
337 crypto_PKeyObj *pkey;
338
339 if (!PyArg_ParseTuple(args, "O!:set_pubkey", &crypto_PKey_Type, &pkey))
340 return NULL;
341
342 if (!X509_set_pubkey(self->x509, pkey->pkey))
343 {
344 exception_from_error_queue();
345 return NULL;
346 }
347
348 Py_INCREF(Py_None);
349 return Py_None;
350}
351
Jean-Paul Calderone525ef802008-03-09 20:39:42 -0400352static PyObject*
353_set_asn1_time(char *format, ASN1_TIME* timestamp, crypto_X509Obj *self, PyObject *args)
354{
355 char *when;
356
357 if (!PyArg_ParseTuple(args, format, &when))
358 return NULL;
359
360 if (ASN1_GENERALIZEDTIME_set_string(timestamp, when) == 0) {
361 ASN1_GENERALIZEDTIME dummy;
362 dummy.type = V_ASN1_GENERALIZEDTIME;
363 dummy.length = strlen(when);
364 dummy.data = when;
365 if (!ASN1_GENERALIZEDTIME_check(&dummy)) {
366 PyErr_SetString(PyExc_ValueError, "Invalid string");
367 } else {
368 PyErr_SetString(PyExc_RuntimeError, "Unknown ASN1_GENERALIZEDTIME_set_string failure");
369 }
370 return NULL;
371 }
372 Py_INCREF(Py_None);
373 return Py_None;
374}
375
376static char crypto_X509_set_notBefore_doc[] = "\n\
377Set the time stamp for when the certificate starts being valid\n\
378\n\
379Arguments: self - The X509 object\n\
380 args - The Python argument tuple, should be:\n\
381 when - A string giving the timestamp, in the format:\n\
382\n\
383 YYYYMMDDhhmmssZ\n\
384 YYYYMMDDhhmmss+hhmm\n\
385 YYYYMMDDhhmmss-hhmm\n\
386\n\
387Returns: None\n\
388";
389
390static PyObject*
391crypto_X509_set_notBefore(crypto_X509Obj *self, PyObject *args)
392{
393 return _set_asn1_time(
394 "s:set_notBefore", X509_get_notBefore(self->x509), self, args);
395}
396
397static char crypto_X509_set_notAfter_doc[] = "\n\
398Set the time stamp for when the certificate stops being valid\n\
399\n\
400Arguments: self - The X509 object\n\
401 args - The Python argument tuple, should be:\n\
402 when - A string giving the timestamp, in the format:\n\
403\n\
404 YYYYMMDDhhmmssZ\n\
405 YYYYMMDDhhmmss+hhmm\n\
406 YYYYMMDDhhmmss-hhmm\n\
407\n\
408Returns: None\n\
409";
410
411static PyObject*
412crypto_X509_set_notAfter(crypto_X509Obj *self, PyObject *args)
413{
414 return _set_asn1_time(
415 "s:set_notAfter", X509_get_notAfter(self->x509), self, args);
416}
417
418static PyObject*
419_get_asn1_time(char *format, ASN1_TIME* timestamp, crypto_X509Obj *self, PyObject *args)
420{
421 ASN1_GENERALIZEDTIME *gt_timestamp = NULL;
422 PyObject *py_timestamp = NULL;
423
424 if (!PyArg_ParseTuple(args, format)) {
425 return NULL;
426 }
427
428 /*
429 * http://www.columbia.edu/~ariel/ssleay/asn1-time.html
430 */
431 /*
432 * There must be a way to do this without touching timestamp->data
433 * directly. -exarkun
434 */
Jean-Paul Calderonee0615b52008-03-09 21:44:46 -0400435 if (timestamp->length == 0) {
436 Py_INCREF(Py_None);
437 return Py_None;
438 } else if (timestamp->type == V_ASN1_GENERALIZEDTIME) {
Jean-Paul Calderone525ef802008-03-09 20:39:42 -0400439 return PyString_FromString(timestamp->data);
440 } else {
441 ASN1_TIME_to_generalizedtime(timestamp, &gt_timestamp);
442 if (gt_timestamp != NULL) {
443 exception_from_error_queue();
444 return NULL;
445 } else {
446 py_timestamp = PyString_FromString(gt_timestamp->data);
447 ASN1_GENERALIZEDTIME_free(gt_timestamp);
448 return py_timestamp;
449 }
450 }
451}
452
453static char crypto_X509_get_notBefore_doc[] = "\n\
454Retrieve the time stamp for when the certificate starts being valid\n\
455\n\
456Arguments: self - The X509 object\n\
457 args - The Python argument tuple, should be empty.\n\
458\n\
459Returns: A string giving the timestamp, in the format:\n\
460\n\
461 YYYYMMDDhhmmssZ\n\
462 YYYYMMDDhhmmss+hhmm\n\
463 YYYYMMDDhhmmss-hhmm\n\
464 or None if there is no value set.\n\
465";
466
467static PyObject*
468crypto_X509_get_notBefore(crypto_X509Obj *self, PyObject *args)
469{
470 /*
471 * X509_get_notBefore returns a borrowed reference.
472 */
473 return _get_asn1_time(
474 ":get_notBefore", X509_get_notBefore(self->x509), self, args);
475}
476
477
478static char crypto_X509_get_notAfter_doc[] = "\n\
479Retrieve the time stamp for when the certificate stops being valid\n\
480\n\
481Arguments: self - The X509 object\n\
482 args - The Python argument tuple, should be empty.\n\
483\n\
484Returns: A string giving the timestamp, in the format:\n\
485\n\
486 YYYYMMDDhhmmssZ\n\
487 YYYYMMDDhhmmss+hhmm\n\
488 YYYYMMDDhhmmss-hhmm\n\
489 or None if there is no value set.\n\
490";
491
492static PyObject*
493crypto_X509_get_notAfter(crypto_X509Obj *self, PyObject *args)
494{
495 /*
496 * X509_get_notAfter returns a borrowed reference.
497 */
498 return _get_asn1_time(
499 ":get_notAfter", X509_get_notAfter(self->x509), self, args);
500}
501
502
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500503static char crypto_X509_gmtime_adj_notBefore_doc[] = "\n\
Jean-Paul Calderone525ef802008-03-09 20:39:42 -0400504Change the timestamp for when the certificate starts being valid to the current\n\
505time plus an offset.\n \
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500506\n\
507Arguments: self - The X509 object\n\
508 args - The Python argument tuple, should be:\n\
509 i - The adjustment\n\
510Returns: None\n\
511";
512
513static PyObject *
514crypto_X509_gmtime_adj_notBefore(crypto_X509Obj *self, PyObject *args)
515{
516 long i;
517
518 if (!PyArg_ParseTuple(args, "l:gmtime_adj_notBefore", &i))
519 return NULL;
520
521 X509_gmtime_adj(X509_get_notBefore(self->x509), i);
522
523 Py_INCREF(Py_None);
524 return Py_None;
525}
526
527static char crypto_X509_gmtime_adj_notAfter_doc[] = "\n\
528Adjust the time stamp for when the certificate stops being valid\n\
529\n\
530Arguments: self - The X509 object\n\
531 args - The Python argument tuple, should be:\n\
532 i - The adjustment\n\
533Returns: None\n\
534";
535
536static PyObject *
537crypto_X509_gmtime_adj_notAfter(crypto_X509Obj *self, PyObject *args)
538{
539 long i;
540
541 if (!PyArg_ParseTuple(args, "l:gmtime_adj_notAfter", &i))
542 return NULL;
543
544 X509_gmtime_adj(X509_get_notAfter(self->x509), i);
545
546 Py_INCREF(Py_None);
547 return Py_None;
548}
549
550static char crypto_X509_sign_doc[] = "\n\
551Sign the certificate using the supplied key and digest\n\
552\n\
553Arguments: self - The X509 object\n\
554 args - The Python argument tuple, should be:\n\
555 pkey - The key to sign with\n\
556 digest - The message digest to use\n\
557Returns: None\n\
558";
559
560static PyObject *
561crypto_X509_sign(crypto_X509Obj *self, PyObject *args)
562{
563 crypto_PKeyObj *pkey;
564 char *digest_name;
565 const EVP_MD *digest;
566
567 if (!PyArg_ParseTuple(args, "O!s:sign", &crypto_PKey_Type, &pkey,
568 &digest_name))
569 return NULL;
570
571 if ((digest = EVP_get_digestbyname(digest_name)) == NULL)
572 {
573 PyErr_SetString(PyExc_ValueError, "No such digest method");
574 return NULL;
575 }
576
577 if (!X509_sign(self->x509, pkey->pkey, digest))
578 {
579 exception_from_error_queue();
580 return NULL;
581 }
582
583 Py_INCREF(Py_None);
584 return Py_None;
585}
586
587static char crypto_X509_has_expired_doc[] = "\n\
588Check whether the certificate has expired.\n\
589\n\
590Arguments: self - The X509 object\n\
591 args - The Python argument tuple, should be empty\n\
592Returns: True if the certificate has expired, false otherwise\n\
593";
594
595static PyObject *
596crypto_X509_has_expired(crypto_X509Obj *self, PyObject *args)
597{
598 time_t tnow;
599
600 if (!PyArg_ParseTuple(args, ":has_expired"))
601 return NULL;
602
603 tnow = time(NULL);
604 if (ASN1_UTCTIME_cmp_time_t(X509_get_notAfter(self->x509), tnow) < 0)
605 return PyInt_FromLong(1L);
606 else
607 return PyInt_FromLong(0L);
608}
609
610static char crypto_X509_subject_name_hash_doc[] = "\n\
611Return the hash of the X509 subject.\n\
612\n\
613Arguments: self - The X509 object\n\
614 args - The Python argument tuple, should be empty\n\
615Returns: The hash of the subject\n\
616";
617
618static PyObject *
619crypto_X509_subject_name_hash(crypto_X509Obj *self, PyObject *args)
620{
621 if (!PyArg_ParseTuple(args, ":subject_name_hash"))
622 return NULL;
623
624 return PyLong_FromLong(X509_subject_name_hash(self->x509));
625}
626
627static char crypto_X509_digest_doc[] = "\n\
628Return the digest of the X509 object.\n\
629\n\
630Arguments: self - The X509 object\n\
631 args - The Python argument tuple, should be empty\n\
632Returns: The digest of the object\n\
633";
634
635static PyObject *
636crypto_X509_digest(crypto_X509Obj *self, PyObject *args)
637{
638 unsigned char fp[EVP_MAX_MD_SIZE];
639 char *tmp;
640 char *digest_name;
641 int len,i;
642 PyObject *ret;
643 const EVP_MD *digest;
644
645 if (!PyArg_ParseTuple(args, "s:digest", &digest_name))
646 return NULL;
647
648 if ((digest = EVP_get_digestbyname(digest_name)) == NULL)
649 {
650 PyErr_SetString(PyExc_ValueError, "No such digest method");
651 return NULL;
652 }
653
654 if (!X509_digest(self->x509,digest,fp,&len))
655 {
656 exception_from_error_queue();
657 }
658 tmp = malloc(3*len+1);
659 memset(tmp, 0, 3*len+1);
660 for (i = 0; i < len; i++) {
661 sprintf(tmp+i*3,"%02X:",fp[i]);
662 }
663 tmp[3*len-1] = 0;
664 ret = PyString_FromStringAndSize(tmp,3*len-1);
665 free(tmp);
666 return ret;
667}
668
669
670static char crypto_X509_add_extensions_doc[] = "\n\
671Add extensions to the certificate.\n\
672\n\
673Arguments: self - X509 object\n\
674 args - The Python argument tuple, should be:\n\
675 extensions - a sequence of X509Extension objects\n\
676Returns: None\n\
677";
678
679static PyObject *
680crypto_X509_add_extensions(crypto_X509Obj *self, PyObject *args)
681{
682 PyObject *extensions, *seq;
683 crypto_X509ExtensionObj *ext;
684 int nr_of_extensions, i;
685
686 if (!PyArg_ParseTuple(args, "O:add_extensions", &extensions))
687 return NULL;
688
689 seq = PySequence_Fast(extensions, "Expected a sequence");
690 if (seq == NULL)
691 return NULL;
692
693 nr_of_extensions = PySequence_Fast_GET_SIZE(seq);
694
695 for (i = 0; i < nr_of_extensions; i++)
696 {
697 ext = (crypto_X509ExtensionObj *)PySequence_Fast_GET_ITEM(seq, i);
698 if (!crypto_X509Extension_Check(ext))
699 {
700 Py_DECREF(seq);
701 PyErr_SetString(PyExc_ValueError,
702 "One of the elements is not an X509Extension");
703 return NULL;
704 }
705 if (!X509_add_ext(self->x509, ext->x509_extension, -1))
706 {
707 Py_DECREF(seq);
708 exception_from_error_queue();
709 return NULL;
710 }
711 }
712
713 Py_INCREF(Py_None);
714 return Py_None;
715}
716
717/*
718 * ADD_METHOD(name) expands to a correct PyMethodDef declaration
719 * { 'name', (PyCFunction)crypto_X509_name, METH_VARARGS }
720 * for convenience
721 */
722#define ADD_METHOD(name) \
723 { #name, (PyCFunction)crypto_X509_##name, METH_VARARGS, crypto_X509_##name##_doc }
724static PyMethodDef crypto_X509_methods[] =
725{
726 ADD_METHOD(get_version),
727 ADD_METHOD(set_version),
728 ADD_METHOD(get_serial_number),
729 ADD_METHOD(set_serial_number),
730 ADD_METHOD(get_issuer),
731 ADD_METHOD(set_issuer),
732 ADD_METHOD(get_subject),
733 ADD_METHOD(set_subject),
734 ADD_METHOD(get_pubkey),
735 ADD_METHOD(set_pubkey),
Jean-Paul Calderone525ef802008-03-09 20:39:42 -0400736 ADD_METHOD(get_notBefore),
737 ADD_METHOD(set_notBefore),
738 ADD_METHOD(get_notAfter),
739 ADD_METHOD(set_notAfter),
Jean-Paul Calderone897bc252008-02-18 20:50:23 -0500740 ADD_METHOD(gmtime_adj_notBefore),
741 ADD_METHOD(gmtime_adj_notAfter),
742 ADD_METHOD(sign),
743 ADD_METHOD(has_expired),
744 ADD_METHOD(subject_name_hash),
745 ADD_METHOD(digest),
746 ADD_METHOD(add_extensions),
747 { NULL, NULL }
748};
749#undef ADD_METHOD
750
751
752/*
753 * Constructor for X509 objects, never called by Python code directly
754 *
755 * Arguments: cert - A "real" X509 certificate object
756 * dealloc - Boolean value to specify whether the destructor should
757 * free the "real" X509 object
758 * Returns: The newly created X509 object
759 */
760crypto_X509Obj *
761crypto_X509_New(X509 *cert, int dealloc)
762{
763 crypto_X509Obj *self;
764
765 self = PyObject_New(crypto_X509Obj, &crypto_X509_Type);
766
767 if (self == NULL)
768 return NULL;
769
770 self->x509 = cert;
771 self->dealloc = dealloc;
772
773 return self;
774}
775
776/*
777 * Deallocate the memory used by the X509 object
778 *
779 * Arguments: self - The X509 object
780 * Returns: None
781 */
782static void
783crypto_X509_dealloc(crypto_X509Obj *self)
784{
785 /* Sometimes we don't have to dealloc the "real" X509 pointer ourselves */
786 if (self->dealloc)
787 X509_free(self->x509);
788
789 PyObject_Del(self);
790}
791
792/*
793 * Find attribute
794 *
795 * Arguments: self - The X509 object
796 * name - The attribute name
797 * Returns: A Python object for the attribute, or NULL if something went
798 * wrong
799 */
800static PyObject *
801crypto_X509_getattr(crypto_X509Obj *self, char *name)
802{
803 return Py_FindMethod(crypto_X509_methods, (PyObject *)self, name);
804}
805
806PyTypeObject crypto_X509_Type = {
807 PyObject_HEAD_INIT(NULL)
808 0,
809 "X509",
810 sizeof(crypto_X509Obj),
811 0,
812 (destructor)crypto_X509_dealloc,
813 NULL, /* print */
814 (getattrfunc)crypto_X509_getattr,
815};
816
817/*
818 * Initialize the X509 part of the crypto sub module
819 *
820 * Arguments: dict - The crypto module dictionary
821 * Returns: None
822 */
823int
824init_crypto_x509(PyObject *dict)
825{
826 crypto_X509_Type.ob_type = &PyType_Type;
827 Py_INCREF(&crypto_X509_Type);
828 PyDict_SetItemString(dict, "X509Type", (PyObject *)&crypto_X509_Type);
829 return 1;
830}
831