]> www.wagner.pp.ru Git - oss/ctypescrypto.git/blob - ctypescrypto/x509.py
Python 3 support for modules pbkdf2 pkey ec x509
[oss/ctypescrypto.git] / ctypescrypto / x509.py
1 """
2 Implements interface to openssl X509 and X509Store structures,
3 I.e allows to load, analyze and verify certificates.
4
5 X509Store objects are also used to verify other signed documets,
6 such as CMS, OCSP and timestamps.
7 """
8
9
10
11 from ctypes import c_void_p, c_long, c_ulong, c_int, POINTER, c_char_p, Structure, cast
12 from ctypescrypto.bio import Membio
13 from ctypescrypto.pkey import PKey
14 from ctypescrypto.oid import Oid
15 from ctypescrypto.exception import LibCryptoError
16 from ctypescrypto import libcrypto, pyver, chartype, inttype, bintype
17 from datetime import datetime
18 import sys
19 try:
20     from pytz import utc
21 except ImportError:
22     from datetime import timedelta, tzinfo
23     ZERO = timedelta(0)
24     class UTC(tzinfo):
25         """tzinfo object for UTC.
26             If no pytz is available, we would use it.
27         """
28         def utcoffset(self, dt):
29             return ZERO
30
31         def tzname(self, dt):
32             return "UTC"
33
34         def dst(self, dt):
35             return ZERO
36
37     utc = UTC()
38
39 __all__ = ['X509', 'X509Error', 'X509Name', 'X509Store', 'StackOfX509']
40
41 if hasattr(libcrypto,"X509_get_version"):
42     
43 # If it is OpenSSL 1.1 or above, use accessor functions
44     _X509_get_version = libcrypto.X509_get_version
45     _X509_get_version.restype = c_long
46     _X509_get_version.argtypes = (c_void_p,)
47
48     _X509_get_notBefore=libcrypto.X509_getm_notBefore
49     _X509_get_notBefore.restype = c_void_p
50     _X509_get_notBefore.argtypes = (c_void_p,)
51
52     _X509_get_notAfter=libcrypto.X509_getm_notAfter
53     _X509_get_notAfter.restype = c_void_p
54     _X509_get_notAfter.argtypes = (c_void_p,)
55 else:
56     # Otherwise declare X509 structure internals and define deep poke
57     # functions
58     class _validity(Structure):
59         """ ctypes representation of X509_VAL structure
60             needed to access certificate validity period, because openssl
61             doesn't provide fuctions for it - only macros
62         """
63         _fields_ = [('notBefore', c_void_p), ('notAfter', c_void_p)]
64
65     class _cinf(Structure):
66         """ ctypes representtion of X509_CINF structure
67             neede to access certificate data, which are accessable only
68             via macros
69         """
70         _fields_ = [('version', c_void_p),
71                     ('serialNumber', c_void_p),
72                     ('sign_alg', c_void_p),
73                     ('issuer', c_void_p),
74                     ('validity', POINTER(_validity)),
75                     ('subject', c_void_p),
76                     ('pubkey', c_void_p),
77                     ('issuerUID', c_void_p),
78                     ('subjectUID', c_void_p),
79                     ('extensions', c_void_p),
80                 ]
81
82     class _x509(Structure):
83         """
84         ctypes represntation of X509 structure needed
85         to access certificate data which are accesable only via
86         macros, not functions
87         """
88         _fields_ = [('cert_info', POINTER(_cinf)),
89                     ('sig_alg', c_void_p),
90                     ('signature', c_void_p),
91                     # There are a lot of parsed extension fields there
92                 ]
93     _px509 = POINTER(_x509)
94     def _X509_get_version(ptr):
95         asn1int = cast(ptr, _px509)[0].cert_info[0].version  
96         return libcrypto.ASN1_INTEGER_get(asn1int)
97
98     def _X509_get_notBefore(ptr):   
99         # (x)->cert_info->validity->notBefore
100         return cast(ptr, _px509)[0].cert_info[0].validity[0].notBefore
101     def _X509_get_notAfter(ptr):
102         return cast(ptr, _px509)[0].cert_info[0].validity[0].notAfter
103
104 if hasattr(libcrypto,'sk_num'):
105     sk_num = libcrypto.sk_num
106     sk_set = libcrypto.sk_set
107     sk_value = libcrypto.sk_value
108     sk_delete = libcrypto.sk_delete
109     sk_new_null = libcrypto.sk_new_null
110     sk_pop_free = libcrypto.sk_pop_free
111     sk_push = libcrypto.sk_push
112 else:
113     sk_num = libcrypto.OPENSSL_sk_num
114     sk_set = libcrypto.OPENSSL_sk_set
115     sk_value = libcrypto.OPENSSL_sk_value
116     sk_delete = libcrypto.OPENSSL_sk_delete
117     sk_new_null = libcrypto.OPENSSL_sk_new_null
118     sk_pop_free = libcrypto.OPENSSL_sk_pop_free
119     sk_push = libcrypto.OPENSSL_sk_push
120 class X509Error(LibCryptoError):
121     """
122     Exception, generated when some openssl function fail
123     during X509 operation
124     """
125     pass
126
127
128 class X509Name(object):
129     """
130     Class which represents X.509 distinguished name - typically
131     a certificate subject name or an issuer name.
132
133     Now used only to represent information, extracted from the
134     certificate. Potentially can be also used to build DN when creating
135     certificate signing request
136     """
137     # XN_FLAG_SEP_COMMA_PLUS & ASN1_STRFLG_UTF8_CONVERT
138     PRINT_FLAG = 0x10010
139     ESC_MSB = 4
140     def __init__(self, ptr=None, copy=False):
141         """
142         Creates a X509Name object
143         @param ptr - pointer to X509_NAME C structure (as returned by some
144                      OpenSSL functions
145         @param copy - indicates that this structure have to be freed upon
146                       object destruction
147         """
148         if ptr is not None:
149             self.ptr = ptr
150             self.need_free = copy
151             self.writable = False
152         else:
153             self.ptr = libcrypto.X509_NAME_new()
154             self.need_free = True
155             self.writable = True
156
157     def __del__(self):
158         """
159         Frees if neccessary
160         """
161         if self.need_free:
162             libcrypto.X509_NAME_free(self.ptr)
163     def __bytes__(self):
164         """
165         Produces an ascii representation of the name, escaping all
166         symbols > 0x80.  Probably it is not what you want, unless
167         your native language is English
168         """
169         bio = Membio()
170         libcrypto.X509_NAME_print_ex(bio.bio, self.ptr, 0,
171                                      self.PRINT_FLAG | self.ESC_MSB)
172         return bio.__bytes__()
173
174     def __unicode__(self):
175         """
176         Produces unicode representation of the name.
177         """
178         bio = Membio()
179         libcrypto.X509_NAME_print_ex(bio.bio, self.ptr, 0, self.PRINT_FLAG)
180         return bio.__unicode__()
181     if pyver == 2:
182         __str__ = __bytes__
183     else:
184         __str__ = __unicode__
185             
186
187     def __len__(self):
188         """
189         return number of components in the name
190         """
191         return libcrypto.X509_NAME_entry_count(self.ptr)
192     def __cmp__(self, other):
193         """
194         Compares X509 names
195         """
196         return libcrypto.X509_NAME_cmp(self.ptr, other.ptr)
197     def __eq__(self, other):
198         return libcrypto.X509_NAME_cmp(self.ptr, other.ptr) == 0
199     def __gt__(self, other):
200         return libcrypto.X509_NAME_cmp(self.ptr, other.ptr) > 0
201     def __lt__(self, other):
202         return libcrypto.X509_NAME_cmp(self.ptr, other.ptr) < 0
203
204     def __getitem__(self, key):
205         if isinstance(key, Oid):
206             # Return first matching field
207             idx = libcrypto.X509_NAME_get_index_by_NID(self.ptr, key.nid, -1)
208             if idx < 0:
209                 raise KeyError("Key not found " + str(Oid))
210             entry = libcrypto.X509_NAME_get_entry(self.ptr, idx)
211             value = libcrypto.X509_NAME_ENTRY_get_data(entry)
212             bio = Membio()
213             libcrypto.ASN1_STRING_print_ex(bio.bio, value, self.PRINT_FLAG)
214             return chartype(bio)
215         elif isinstance(key, inttype):
216             # Return OID, string tuple
217             entry = libcrypto.X509_NAME_get_entry(self.ptr, key)
218             if entry is None:
219                 raise IndexError("name entry index out of range")
220             oid = Oid.fromobj(libcrypto.X509_NAME_ENTRY_get_object(entry))
221             value = libcrypto.X509_NAME_ENTRY_get_data(entry)
222             bio = Membio()
223             libcrypto.ASN1_STRING_print_ex(bio.bio, value, self.PRINT_FLAG)
224             return (oid, chartype(bio))
225         else:
226             raise TypeError("X509 NAME can be indexed by Oids or integers only")
227
228     def __setitem__(self, key, val):
229         if not self.writable:
230             raise ValueError("Attempt to modify constant X509 object")
231         else:
232             raise NotImplementedError
233     def __delitem__(self, key):
234         if not self.writable:
235             raise ValueError("Attempt to modify constant X509 object")
236         else:
237             raise NotImplementedError
238     def __hash__(self):
239         return libcrypto.X509_NAME_hash(self.ptr)
240
241 class _x509_ext(Structure):
242     """ Represens C structure X509_EXTENSION """
243     _fields_ = [("object", c_void_p),
244                 ("critical", c_int),
245                 ("value", c_void_p)
246                ]
247
248 class X509_EXT(object):
249     """ Python object which represents a certificate extension """
250     def __init__(self, ptr, copy=False):
251         """ Initializes from the pointer to X509_EXTENSION.
252             If copy is True, creates a copy, otherwise just
253             stores pointer.
254         """
255         if copy:
256             self.ptr = libcrypto.X509_EXTENSION_dup(ptr)
257         else:
258             self.ptr = cast(ptr, POINTER(_x509_ext))
259     def __del__(self):
260         libcrypto.X509_EXTENSION_free(self.ptr)
261     def __bytes__(self):
262         bio = Membio()
263         libcrypto.X509V3_EXT_print(bio.bio, self.ptr, 0x20010, 0)
264         return bintype(bio)
265     def __unicode__(self):
266         bio = Membio()
267         libcrypto.X509V3_EXT_print(bio.bio, self.ptr, 0x20010, 0)
268         return chartype(bio)
269     if pyver == 2:
270         __str__ = __bytes__
271     else:
272         __str__ = __unicode__
273     @property
274     def oid(self):
275         "Returns OID of the extension"
276         return Oid.fromobj(self.ptr[0].object)
277     @property
278     def critical(self):
279         "Returns True if extensin have critical flag set"
280         return self.ptr[0].critical > 0
281
282 class _X509extlist(object):
283     """
284     Represents list of certificate extensions. Really it keeps
285     reference to certificate object
286     """
287     def __init__(self, cert):
288         """
289         Initialize from X509 object
290         """
291         self.cert = cert
292
293     def __len__(self):
294         """
295         Returns number of extensions
296         """
297         return libcrypto.X509_get_ext_count(self.cert.cert)
298
299     def __getitem__(self, item):
300         """
301         Returns extension by index, creating a copy
302         """
303         ext_ptr = libcrypto.X509_get_ext(self.cert.cert, item)
304         if ext_ptr is None:
305             raise IndexError
306         return X509_EXT(ext_ptr, True)
307     def find(self, oid):
308         """
309         Return list of extensions with given Oid
310         """
311         if not isinstance(oid, Oid):
312             raise TypeError("Need crytypescrypto.oid.Oid as argument")
313         found = []
314         index = -1
315         end = len(self)
316         while True:
317             index = libcrypto.X509_get_ext_by_NID(self.cert.cert, oid.nid,
318                                                   index)
319             if index >= end or index < 0:
320                 break
321             found.append(self[index])
322         return found
323
324     def find_critical(self, crit=True):
325         """
326         Return list of critical extensions (or list of non-cricital, if
327         optional second argument is False
328         """
329         if crit:
330             flag = 1
331         else:
332             flag = 0
333         found = []
334         end = len(self)
335         index = -1
336         while True:
337             index = libcrypto.X509_get_ext_by_critical(self.cert.cert, flag,
338                                                        index)
339             if index >= end or index < 0:
340                 break
341             found.append(self[index])
342         return found
343
344 def _X509__asn1date_to_datetime(asn1date):
345     """ 
346     Converts openssl ASN1_TIME object to python datetime.datetime
347     """
348     bio = Membio()
349     libcrypto.ASN1_TIME_print(bio.bio, asn1date)
350     pydate = datetime.strptime(str(bio), "%b %d %H:%M:%S %Y %Z")
351     return pydate.replace(tzinfo=utc)
352
353 class X509(object):
354     """
355     Represents X.509 certificate.
356     """
357     def __init__(self, data=None, ptr=None, format="PEM"):
358         """
359         Initializes certificate
360         @param data - serialized certificate in PEM or DER format.
361         @param ptr - pointer to X509, returned by some openssl function.
362             mutually exclusive with data
363         @param format - specifies data format. "PEM" or "DER", default PEM
364         """
365         if ptr is not None:
366             if data is not None:
367                 raise TypeError("Cannot use data and ptr simultaneously")
368             self.cert = ptr
369         elif data is None:
370             raise TypeError("data argument is required")
371         else:
372             bio = Membio(data)
373             if format == "PEM":
374                 self.cert = libcrypto.PEM_read_bio_X509(bio.bio, None, None,
375                                                         None)
376             else:
377                 self.cert = libcrypto.d2i_X509_bio(bio.bio, None)
378             if self.cert is None:
379                 raise X509Error("error reading certificate")
380         self.extensions = _X509extlist(self)
381     def __del__(self):
382         """
383         Frees certificate object
384         """
385         libcrypto.X509_free(self.cert)
386     def __bytes__(self):
387         """ Returns der string of the certificate """
388         bio = Membio()
389         if libcrypto.i2d_X509_bio(bio.bio, self.cert) == 0:
390             raise X509Error("error serializing certificate")
391         return str(bio)
392     if pyver == 2:
393         __str__ = __bytes__
394     def __repr__(self):
395         """ Returns valid call to the constructor """
396         return "X509(data=" + repr(self.pem()) + ",format='PEM')"
397     @property
398     def pubkey(self):
399         """EVP PKEy object of certificate public key"""
400         return PKey(ptr=libcrypto.X509_get_pubkey(self.cert, False))
401     def pem(self):
402         """ Returns PEM represntation of the certificate """
403         bio = Membio()
404         if libcrypto.PEM_write_bio_X509(bio.bio, self.cert) == 0:
405             raise X509Error("error serializing certificate")
406         return str(bio)
407     def verify(self, store=None, chain=None, key=None):
408         """
409         Verify self. Supports verification on both X509 store object
410         or just public issuer key
411         @param store X509Store object.
412         @param chain - list of X509 objects to add into verification
413             context.These objects are untrusted, but can be used to
414             build certificate chain up to trusted object in the store
415         @param key - PKey object with open key to validate signature
416
417         parameters store and key are mutually exclusive. If neither
418         is specified, attempts to verify self as self-signed certificate
419         """
420         if store is not None and key is not None:
421             raise X509Error("key and store cannot be specified simultaneously")
422         if store is not None:
423             ctx = libcrypto.X509_STORE_CTX_new()
424             if ctx is None:
425                 raise X509Error("Error allocating X509_STORE_CTX")
426             if chain is not None and len(chain) > 0:
427                 chain_ptr = StackOfX509(chain).ptr
428             else:
429                 chain_ptr = None
430             if libcrypto.X509_STORE_CTX_init(ctx, store.store, self.cert,
431                                              chain_ptr) < 0:
432                 raise X509Error("Error allocating X509_STORE_CTX")
433             res = libcrypto.X509_verify_cert(ctx)
434             libcrypto.X509_STORE_CTX_free(ctx)
435             return res > 0
436         else:
437             if key is None:
438                 if self.issuer != self.subject:
439                     # Not a self-signed certificate
440                     return False
441                 key = self.pubkey
442             res = libcrypto.X509_verify(self.cert, key.key)
443             if res < 0:
444                 raise X509Error("X509_verify failed")
445             return res > 0
446
447     @property
448     def subject(self):
449         """ X509Name for certificate subject name """
450         return X509Name(libcrypto.X509_get_subject_name(self.cert))
451     @property
452     def issuer(self):
453         """ X509Name for certificate issuer name """
454         return X509Name(libcrypto.X509_get_issuer_name(self.cert))
455     @property
456     def serial(self):
457         """ Serial number of certificate as integer """
458         asnint = libcrypto.X509_get_serialNumber(self.cert)
459         bio = Membio()
460         libcrypto.i2a_ASN1_INTEGER(bio.bio, asnint)
461         return int(str(bio), 16)
462     @property
463     def version(self):
464         """
465         certificate version as integer. Really certificate stores 0 for
466         version 1 and 2 for version 3, but we return 1 and 3
467         """
468         return _X509_get_version(self.cert) + 1
469     @property
470     def startDate(self):
471         """ Certificate validity period start date """
472         asn1 = _X509_get_notBefore(self.cert)
473         return __asn1date_to_datetime(asn1)
474     @property
475     def endDate(self):
476         """ Certificate validity period end date """
477         asn1 = _X509_get_notAfter(self.cert)
478         return __asn1date_to_datetime(asn1)
479     def check_ca(self):
480         """ Returns True if certificate is CA certificate """
481         return libcrypto.X509_check_ca(self.cert) > 0
482
483 class X509Store(object):
484     """
485     Represents trusted certificate store. Can be used to lookup CA
486     certificates to verify
487
488     @param file - file with several certificates and crls
489             to load into store
490     @param dir - hashed directory with certificates and crls
491     @param default - if true, default verify location (directory)
492         is installed
493
494     """
495     def __init__(self, file=None, dir=None, default=False):
496         """
497         Creates X509 store and installs lookup method. Optionally initializes
498         by certificates from given file or directory.
499         """
500         #
501         # Todo - set verification flags
502         #
503         self.store = libcrypto.X509_STORE_new()
504         if self.store is None:
505             raise X509Error("allocating store")
506         lookup = libcrypto.X509_STORE_add_lookup(self.store,
507                                                  libcrypto.X509_LOOKUP_file())
508         if lookup is None:
509             raise X509Error("error installing file lookup method")
510         if file is not None:
511             if pyver == 2:
512                 fn = file
513             else:
514                 fn = file.encode(sys.getfilesystemencoding())
515             if not libcrypto.X509_LOOKUP_ctrl(lookup, 1, fn, 1, None) > 0:
516                 raise X509Error("error loading trusted certs from file "+file)
517         lookup = libcrypto.X509_STORE_add_lookup(self.store,
518                                              libcrypto.X509_LOOKUP_hash_dir())
519         if lookup is None:
520             raise X509Error("error installing hashed lookup method")
521         if dir is not None:
522             if pyver == 2:
523                 dr = dir
524             else:
525                 dr = dir.encode(sys.getfilesystemencoding())
526             if not libcrypto.X509_LOOKUP_ctrl(lookup, 2, dr, 1, None) > 0:
527                 raise X509Error("error adding hashed  trusted certs dir "+dir)
528         if default:
529             if not libcrypto.X509_LOOKUP_ctrl(lookup, 2, None, 3, None) > 0:
530                 raise X509Error("error adding default trusted certs dir ")
531     def add_cert(self, cert):
532         """
533         Explicitely adds certificate to set of trusted in the store
534         @param cert - X509 object to add
535         """
536         if not isinstance(cert, X509):
537             raise TypeError("cert should be X509")
538         libcrypto.X509_STORE_add_cert(self.store, cert.cert)
539     def add_callback(self, callback):
540         """
541         Installs callback function, which would receive detailed information
542         about verified ceritificates
543         """
544         raise NotImplementedError
545     def setflags(self, flags):
546         """
547         Set certificate verification flags.
548         @param flags - integer bit mask. See OpenSSL X509_V_FLAG_* constants
549         """
550         libcrypto.X509_STORE_set_flags(self.store, flags)
551     def setpurpose(self, purpose):
552         """
553         Sets certificate purpose which verified certificate should match
554         @param purpose - number from 1 to 9 or standard strind defined
555                          in Openssl
556         possible strings - sslcient,sslserver, nssslserver, smimesign,i
557                          smimeencrypt, crlsign, any, ocsphelper
558         """
559         if isinstance(purpose, str):
560             purp_no = libcrypto.X509_PURPOSE_get_by_sname(purpose)
561             if purp_no <= 0:
562                 raise X509Error("Invalid certificate purpose '%s'" % purpose)
563         elif isinstance(purpose, int):
564             purp_no = purpose
565         if libcrypto.X509_STORE_set_purpose(self.store, purp_no) <= 0:
566             raise X509Error("cannot set purpose")
567     def setdepth(self, depth):
568         """
569         Sets the verification depth i.e. max length of certificate chain
570         which is acceptable
571         """
572         libcrypto.X509_STORE_set_depth(self.store, depth)
573     def settime(self, time):
574         """
575         Set point in time used to check validity of certificates for
576         Time can be either python datetime object or number of seconds
577         sinse epoch
578         """
579         if isinstance(time, datetime) or isinstance(time,
580                                                              datetime.date):
581             seconds = int(time.strftime("%s"))
582         elif isinstance(time, int):
583             seconds = time
584         else:
585             raise TypeError("datetime.date, datetime.datetime or integer " +
586                             "is required as time argument")
587         raise NotImplementedError
588 class StackOfX509(object):
589     """
590     Implements OpenSSL STACK_OF(X509) object.
591     It looks much like python container types
592     """
593     def __init__(self, certs=None, ptr=None, disposable=True):
594         """
595         Create stack
596         @param certs - list of X509 objects. If specified, read-write
597             stack is created and populated by these certificates
598         @param ptr - pointer to OpenSSL STACK_OF(X509) as returned by
599             some functions
600         @param disposable - if True, stack created from object, returned
601                 by function is copy, and can be modified and need to be
602                 freeid. If false, it is just pointer into another
603                 structure i.e. CMS_ContentInfo
604         """
605         self.need_free = False
606         if  ptr is None:
607             self.need_free = True
608             self.ptr = sk_new_null()
609             if certs is not None:
610                 for crt in certs:
611                     self.append(crt)
612         elif certs is not None:
613             raise ValueError("cannot handle certs an ptr simultaneously")
614         else:
615             self.need_free = disposable
616             self.ptr = ptr
617     def __len__(self):
618         return sk_num(self.ptr)
619     def __getitem__(self, index):
620         if index < 0 or index >= len(self):
621             raise IndexError
622         p = sk_value(self.ptr, index)
623         return X509(ptr=libcrypto.X509_dup(p))
624     def __setitem__(self, index, value):
625         if not self.need_free:
626             raise ValueError("Stack is read-only")
627         if index < 0 or index >= len(self):
628             raise IndexError
629         if not isinstance(value, X509):
630             raise TypeError('StackOfX509 can contain only X509 objects')
631         p = sk_value(self.ptr, index)
632         sk_set(self.ptr, index, libcrypto.X509_dup(value.cert))
633         libcrypto.X509_free(p)
634     def __delitem__(self, index):
635         if not self.need_free:
636             raise ValueError("Stack is read-only")
637         if index < 0 or index >= len(self):
638             raise IndexError
639         p = sk_delete(self.ptr, index)
640         libcrypto.X509_free(p)
641     def __del__(self):
642         if self.need_free:
643             sk_pop_free(self.ptr, libcrypto.X509_free)
644     def append(self, value):
645         """ Adds certificate to stack """
646         if not self.need_free:
647             raise ValueError("Stack is read-only")
648         if not isinstance(value, X509):
649             raise TypeError('StackOfX509 can contain only X509 objects')
650         sk_push(self.ptr, libcrypto.X509_dup(value.cert))
651
652 libcrypto.d2i_X509_bio.argtypes = (c_void_p,POINTER(c_void_p))
653 libcrypto.X509_free.argtypes = (c_void_p,)
654 libcrypto.X509_dup.restype = c_void_p
655 libcrypto.X509_dup.argtypes = (c_void_p, )
656 libcrypto.i2a_ASN1_INTEGER.argtypes = (c_void_p, c_void_p)
657 libcrypto.ASN1_STRING_print_ex.argtypes = (c_void_p, c_void_p, c_long)
658 libcrypto.PEM_read_bio_X509.restype = c_void_p
659 libcrypto.PEM_read_bio_X509.argtypes = (c_void_p, POINTER(c_void_p),
660                                         c_void_p, c_void_p)
661 libcrypto.PEM_write_bio_X509.restype = c_int
662 libcrypto.PEM_write_bio_X509.argtypes = (c_void_p, c_void_p)
663 libcrypto.ASN1_TIME_print.argtypes = (c_void_p, c_void_p)
664 libcrypto.ASN1_INTEGER_get.argtypes = (c_void_p, )
665 libcrypto.ASN1_INTEGER_get.restype = c_long
666 libcrypto.X509_check_ca.argtypes = (c_void_p, )
667 libcrypto.X509_get_serialNumber.argtypes = (c_void_p, )
668 libcrypto.X509_get_serialNumber.restype = c_void_p
669 libcrypto.X509_get_subject_name.argtypes = (c_void_p, )
670 libcrypto.X509_get_subject_name.restype = c_void_p
671 libcrypto.X509_get_issuer_name.argtypes = (c_void_p, )
672 libcrypto.X509_get_issuer_name.restype = c_void_p
673 libcrypto.X509_NAME_ENTRY_get_object.restype = c_void_p
674 libcrypto.X509_NAME_ENTRY_get_object.argtypes = (c_void_p, )
675 libcrypto.X509_NAME_ENTRY_get_data.restype = c_void_p
676 libcrypto.X509_NAME_ENTRY_get_data.argtypes = (c_void_p, )
677 libcrypto.OBJ_obj2nid.argtypes = (c_void_p, )
678 libcrypto.X509_NAME_get_entry.restype = c_void_p
679 libcrypto.X509_NAME_get_entry.argtypes = (c_void_p, c_int)
680 libcrypto.X509_STORE_new.restype = c_void_p
681 libcrypto.X509_STORE_add_lookup.restype = c_void_p
682 libcrypto.X509_STORE_add_lookup.argtypes = (c_void_p, c_void_p)
683 libcrypto.X509_STORE_add_cert.argtypes = (c_void_p, c_void_p)
684 libcrypto.X509_STORE_CTX_new.restype = c_void_p
685 libcrypto.X509_STORE_CTX_free.argtypes = (c_void_p,)
686 libcrypto.X509_STORE_CTX_init.argtypes = (c_void_p, c_void_p, c_void_p,
687                                             c_void_p)
688 libcrypto.X509_STORE_set_depth.argtypes = (c_void_p, c_int)
689 libcrypto.X509_STORE_set_flags.argtypes = (c_void_p, c_ulong)
690 libcrypto.X509_STORE_set_purpose.argtypes = (c_void_p, c_int)
691 libcrypto.X509_LOOKUP_file.restype = c_void_p
692 libcrypto.X509_LOOKUP_hash_dir.restype = c_void_p
693 libcrypto.X509_LOOKUP_ctrl.restype = c_int
694 libcrypto.X509_LOOKUP_ctrl.argtypes = (c_void_p, c_int, c_char_p, c_long,
695                                        POINTER(c_char_p))
696 libcrypto.X509_EXTENSION_free.argtypes = (c_void_p, )
697 libcrypto.X509_EXTENSION_dup.argtypes = (c_void_p, )
698 libcrypto.X509_EXTENSION_dup.restype = POINTER(_x509_ext)
699 libcrypto.X509V3_EXT_print.argtypes = (c_void_p, POINTER(_x509_ext), c_long,
700                                        c_int)
701 libcrypto.X509_get_ext.restype = c_void_p
702 libcrypto.X509_get_ext.argtypes = (c_void_p, c_int)
703 libcrypto.X509_get_ext_by_critical.argtypes = (c_void_p, c_int, c_int)
704 libcrypto.X509_get_ext_by_NID.argtypes = (c_void_p, c_int, c_int)
705 libcrypto.X509_get_ext_count.argtypes = (c_void_p, )
706 libcrypto.X509_get_pubkey.restype = c_void_p
707 libcrypto.X509_get_pubkey.argtypes = (c_void_p, )
708 libcrypto.X509V3_EXT_print.argtypes = (c_void_p, POINTER(_x509_ext), c_long,
709       c_int)
710 libcrypto.X509_LOOKUP_file.restype = c_void_p
711 libcrypto.X509_LOOKUP_hash_dir.restype = c_void_p
712 libcrypto.X509_NAME_cmp.argtypes = (c_void_p, c_void_p)
713 libcrypto.X509_NAME_entry_count.argtypes = (c_void_p,) 
714 libcrypto.X509_NAME_free.argtypes = (c_void_p,)
715 libcrypto.X509_NAME_new.restype = c_void_p
716 libcrypto.X509_NAME_print_ex.argtypes = (c_void_p, c_void_p, c_int, c_ulong)
717 libcrypto.X509_PURPOSE_get_by_sname.argtypes=(c_char_p,)
718 libcrypto.X509_verify.argtypes = (c_void_p, c_void_p)
719 libcrypto.X509_verify_cert.argtypes = (c_void_p,)
720 sk_num.restype = c_int
721 sk_num.argtypes= (c_void_p,)
722 sk_set.argtypes = (c_void_p, c_int, c_void_p)
723 sk_set.restype = c_void_p
724 sk_value.argtypes = (c_void_p, c_int)
725 sk_value.restype = c_void_p
726 sk_delete.argtypes = (c_void_p, c_int)
727 sk_delete.restype = c_void_p
728 sk_new_null.restype = c_void_p
729 sk_pop_free.argtypes = (c_void_p, c_void_p)
730 sk_push.argtypes = (c_void_p, c_void_p)
731 libcrypto.X509_NAME_hash.restype = c_long
732 libcrypto.X509_NAME_hash.argtypes = (c_void_p, )
733 libcrypto.X509_NAME_get_index_by_NID.argtypes = (c_void_p, c_int, c_int)