]> www.wagner.pp.ru Git - oss/ctypescrypto.git/blobdiff - ctypescrypto/x509.py
Python 3 support for modules pbkdf2 pkey ec x509
[oss/ctypescrypto.git] / ctypescrypto / x509.py
index b018f782b90f6f56edd6ef3ab7c271796ffcf67e..35ab1fee27faeb47b199e62385df1239828f02f1 100644 (file)
@@ -8,14 +8,14 @@ such as CMS, OCSP and timestamps.
 
 
 
 
 
 
-from ctypes import c_void_p, c_long, c_int, POINTER, c_char_p, Structure, cast
+from ctypes import c_void_p, c_long, c_ulong, c_int, POINTER, c_char_p, Structure, cast
 from ctypescrypto.bio import Membio
 from ctypescrypto.pkey import PKey
 from ctypescrypto.oid import Oid
 from ctypescrypto.exception import LibCryptoError
 from ctypescrypto.bio import Membio
 from ctypescrypto.pkey import PKey
 from ctypescrypto.oid import Oid
 from ctypescrypto.exception import LibCryptoError
-from ctypescrypto import libcrypto
+from ctypescrypto import libcrypto, pyver, chartype, inttype, bintype
 from datetime import datetime
 from datetime import datetime
-
+import sys
 try:
     from pytz import utc
 except ImportError:
 try:
     from pytz import utc
 except ImportError:
@@ -45,11 +45,11 @@ if hasattr(libcrypto,"X509_get_version"):
     _X509_get_version.restype = c_long
     _X509_get_version.argtypes = (c_void_p,)
 
     _X509_get_version.restype = c_long
     _X509_get_version.argtypes = (c_void_p,)
 
-    _X509_get_notBefore=libcrypto.X509_get_notBefore
+    _X509_get_notBefore=libcrypto.X509_getm_notBefore
     _X509_get_notBefore.restype = c_void_p
     _X509_get_notBefore.argtypes = (c_void_p,)
 
     _X509_get_notBefore.restype = c_void_p
     _X509_get_notBefore.argtypes = (c_void_p,)
 
-    _X509_get_notAfter=libcrypto.X509_get_notAfter
+    _X509_get_notAfter=libcrypto.X509_getm_notAfter
     _X509_get_notAfter.restype = c_void_p
     _X509_get_notAfter.argtypes = (c_void_p,)
 else:
     _X509_get_notAfter.restype = c_void_p
     _X509_get_notAfter.argtypes = (c_void_p,)
 else:
@@ -101,6 +101,22 @@ else:
     def _X509_get_notAfter(ptr):
         return cast(ptr, _px509)[0].cert_info[0].validity[0].notAfter
 
     def _X509_get_notAfter(ptr):
         return cast(ptr, _px509)[0].cert_info[0].validity[0].notAfter
 
+if hasattr(libcrypto,'sk_num'):
+    sk_num = libcrypto.sk_num
+    sk_set = libcrypto.sk_set
+    sk_value = libcrypto.sk_value
+    sk_delete = libcrypto.sk_delete
+    sk_new_null = libcrypto.sk_new_null
+    sk_pop_free = libcrypto.sk_pop_free
+    sk_push = libcrypto.sk_push
+else:
+    sk_num = libcrypto.OPENSSL_sk_num
+    sk_set = libcrypto.OPENSSL_sk_set
+    sk_value = libcrypto.OPENSSL_sk_value
+    sk_delete = libcrypto.OPENSSL_sk_delete
+    sk_new_null = libcrypto.OPENSSL_sk_new_null
+    sk_pop_free = libcrypto.OPENSSL_sk_pop_free
+    sk_push = libcrypto.OPENSSL_sk_push
 class X509Error(LibCryptoError):
     """
     Exception, generated when some openssl function fail
 class X509Error(LibCryptoError):
     """
     Exception, generated when some openssl function fail
@@ -144,7 +160,7 @@ class X509Name(object):
         """
         if self.need_free:
             libcrypto.X509_NAME_free(self.ptr)
         """
         if self.need_free:
             libcrypto.X509_NAME_free(self.ptr)
-    def __str__(self):
+    def __bytes__(self):
         """
         Produces an ascii representation of the name, escaping all
         symbols > 0x80.  Probably it is not what you want, unless
         """
         Produces an ascii representation of the name, escaping all
         symbols > 0x80.  Probably it is not what you want, unless
@@ -153,7 +169,7 @@ class X509Name(object):
         bio = Membio()
         libcrypto.X509_NAME_print_ex(bio.bio, self.ptr, 0,
                                      self.PRINT_FLAG | self.ESC_MSB)
         bio = Membio()
         libcrypto.X509_NAME_print_ex(bio.bio, self.ptr, 0,
                                      self.PRINT_FLAG | self.ESC_MSB)
-        return str(bio)
+        return bio.__bytes__()
 
     def __unicode__(self):
         """
 
     def __unicode__(self):
         """
@@ -161,7 +177,13 @@ class X509Name(object):
         """
         bio = Membio()
         libcrypto.X509_NAME_print_ex(bio.bio, self.ptr, 0, self.PRINT_FLAG)
         """
         bio = Membio()
         libcrypto.X509_NAME_print_ex(bio.bio, self.ptr, 0, self.PRINT_FLAG)
-        return unicode(bio)
+        return bio.__unicode__()
+    if pyver == 2:
+        __str__ = __bytes__
+    else:
+        __str__ = __unicode__
+            
+
     def __len__(self):
         """
         return number of components in the name
     def __len__(self):
         """
         return number of components in the name
@@ -174,6 +196,10 @@ class X509Name(object):
         return libcrypto.X509_NAME_cmp(self.ptr, other.ptr)
     def __eq__(self, other):
         return libcrypto.X509_NAME_cmp(self.ptr, other.ptr) == 0
         return libcrypto.X509_NAME_cmp(self.ptr, other.ptr)
     def __eq__(self, other):
         return libcrypto.X509_NAME_cmp(self.ptr, other.ptr) == 0
+    def __gt__(self, other):
+        return libcrypto.X509_NAME_cmp(self.ptr, other.ptr) > 0
+    def __lt__(self, other):
+        return libcrypto.X509_NAME_cmp(self.ptr, other.ptr) < 0
 
     def __getitem__(self, key):
         if isinstance(key, Oid):
 
     def __getitem__(self, key):
         if isinstance(key, Oid):
@@ -185,8 +211,8 @@ class X509Name(object):
             value = libcrypto.X509_NAME_ENTRY_get_data(entry)
             bio = Membio()
             libcrypto.ASN1_STRING_print_ex(bio.bio, value, self.PRINT_FLAG)
             value = libcrypto.X509_NAME_ENTRY_get_data(entry)
             bio = Membio()
             libcrypto.ASN1_STRING_print_ex(bio.bio, value, self.PRINT_FLAG)
-            return unicode(bio)
-        elif isinstance(key, (int, long)):
+            return chartype(bio)
+        elif isinstance(key, inttype):
             # Return OID, string tuple
             entry = libcrypto.X509_NAME_get_entry(self.ptr, key)
             if entry is None:
             # Return OID, string tuple
             entry = libcrypto.X509_NAME_get_entry(self.ptr, key)
             if entry is None:
@@ -195,7 +221,7 @@ class X509Name(object):
             value = libcrypto.X509_NAME_ENTRY_get_data(entry)
             bio = Membio()
             libcrypto.ASN1_STRING_print_ex(bio.bio, value, self.PRINT_FLAG)
             value = libcrypto.X509_NAME_ENTRY_get_data(entry)
             bio = Membio()
             libcrypto.ASN1_STRING_print_ex(bio.bio, value, self.PRINT_FLAG)
-            return (oid, unicode(bio))
+            return (oid, chartype(bio))
         else:
             raise TypeError("X509 NAME can be indexed by Oids or integers only")
 
         else:
             raise TypeError("X509 NAME can be indexed by Oids or integers only")
 
@@ -232,14 +258,18 @@ class X509_EXT(object):
             self.ptr = cast(ptr, POINTER(_x509_ext))
     def __del__(self):
         libcrypto.X509_EXTENSION_free(self.ptr)
             self.ptr = cast(ptr, POINTER(_x509_ext))
     def __del__(self):
         libcrypto.X509_EXTENSION_free(self.ptr)
-    def __str__(self):
+    def __bytes__(self):
         bio = Membio()
         libcrypto.X509V3_EXT_print(bio.bio, self.ptr, 0x20010, 0)
         bio = Membio()
         libcrypto.X509V3_EXT_print(bio.bio, self.ptr, 0x20010, 0)
-        return str(bio)
+        return bintype(bio)
     def __unicode__(self):
         bio = Membio()
         libcrypto.X509V3_EXT_print(bio.bio, self.ptr, 0x20010, 0)
     def __unicode__(self):
         bio = Membio()
         libcrypto.X509V3_EXT_print(bio.bio, self.ptr, 0x20010, 0)
-        return unicode(bio)
+        return chartype(bio)
+    if pyver == 2:
+        __str__ = __bytes__
+    else:
+        __str__ = __unicode__
     @property
     def oid(self):
         "Returns OID of the extension"
     @property
     def oid(self):
         "Returns OID of the extension"
@@ -353,15 +383,17 @@ class X509(object):
         Frees certificate object
         """
         libcrypto.X509_free(self.cert)
         Frees certificate object
         """
         libcrypto.X509_free(self.cert)
-    def __str__(self):
+    def __bytes__(self):
         """ Returns der string of the certificate """
         bio = Membio()
         if libcrypto.i2d_X509_bio(bio.bio, self.cert) == 0:
             raise X509Error("error serializing certificate")
         return str(bio)
         """ Returns der string of the certificate """
         bio = Membio()
         if libcrypto.i2d_X509_bio(bio.bio, self.cert) == 0:
             raise X509Error("error serializing certificate")
         return str(bio)
+    if pyver == 2:
+        __str__ = __bytes__
     def __repr__(self):
         """ Returns valid call to the constructor """
     def __repr__(self):
         """ Returns valid call to the constructor """
-        return "X509(data=" + repr(str(self)) + ",format='DER')"
+        return "X509(data=" + repr(self.pem()) + ",format='PEM')"
     @property
     def pubkey(self):
         """EVP PKEy object of certificate public key"""
     @property
     def pubkey(self):
         """EVP PKEy object of certificate public key"""
@@ -476,14 +508,22 @@ class X509Store(object):
         if lookup is None:
             raise X509Error("error installing file lookup method")
         if file is not None:
         if lookup is None:
             raise X509Error("error installing file lookup method")
         if file is not None:
-            if not libcrypto.X509_LOOKUP_ctrl(lookup, 1, file, 1, None) > 0:
+            if pyver == 2:
+                fn = file
+            else:
+                fn = file.encode(sys.getfilesystemencoding())
+            if not libcrypto.X509_LOOKUP_ctrl(lookup, 1, fn, 1, None) > 0:
                 raise X509Error("error loading trusted certs from file "+file)
         lookup = libcrypto.X509_STORE_add_lookup(self.store,
                                              libcrypto.X509_LOOKUP_hash_dir())
         if lookup is None:
             raise X509Error("error installing hashed lookup method")
         if dir is not None:
                 raise X509Error("error loading trusted certs from file "+file)
         lookup = libcrypto.X509_STORE_add_lookup(self.store,
                                              libcrypto.X509_LOOKUP_hash_dir())
         if lookup is None:
             raise X509Error("error installing hashed lookup method")
         if dir is not None:
-            if not libcrypto.X509_LOOKUP_ctrl(lookup, 2, dir, 1, None) > 0:
+            if pyver == 2:
+                dr = dir
+            else:
+                dr = dir.encode(sys.getfilesystemencoding())
+            if not libcrypto.X509_LOOKUP_ctrl(lookup, 2, dr, 1, None) > 0:
                 raise X509Error("error adding hashed  trusted certs dir "+dir)
         if default:
             if not libcrypto.X509_LOOKUP_ctrl(lookup, 2, None, 3, None) > 0:
                 raise X509Error("error adding hashed  trusted certs dir "+dir)
         if default:
             if not libcrypto.X509_LOOKUP_ctrl(lookup, 2, None, 3, None) > 0:
@@ -565,7 +605,7 @@ class StackOfX509(object):
         self.need_free = False
         if  ptr is None:
             self.need_free = True
         self.need_free = False
         if  ptr is None:
             self.need_free = True
-            self.ptr = libcrypto.sk_new_null()
+            self.ptr = sk_new_null()
             if certs is not None:
                 for crt in certs:
                     self.append(crt)
             if certs is not None:
                 for crt in certs:
                     self.append(crt)
@@ -575,11 +615,11 @@ class StackOfX509(object):
             self.need_free = disposable
             self.ptr = ptr
     def __len__(self):
             self.need_free = disposable
             self.ptr = ptr
     def __len__(self):
-        return libcrypto.sk_num(self.ptr)
+        return sk_num(self.ptr)
     def __getitem__(self, index):
         if index < 0 or index >= len(self):
             raise IndexError
     def __getitem__(self, index):
         if index < 0 or index >= len(self):
             raise IndexError
-        p = libcrypto.sk_value(self.ptr, index)
+        p = sk_value(self.ptr, index)
         return X509(ptr=libcrypto.X509_dup(p))
     def __setitem__(self, index, value):
         if not self.need_free:
         return X509(ptr=libcrypto.X509_dup(p))
     def __setitem__(self, index, value):
         if not self.need_free:
@@ -587,28 +627,29 @@ class StackOfX509(object):
         if index < 0 or index >= len(self):
             raise IndexError
         if not isinstance(value, X509):
         if index < 0 or index >= len(self):
             raise IndexError
         if not isinstance(value, X509):
-            raise TypeError('StackOfX508 can contain only X509 objects')
-        p = libcrypto.sk_value(self.ptr, index)
-        libcrypto.sk_set(self.ptr, index, libcrypto.X509_dup(value.cert))
+            raise TypeError('StackOfX509 can contain only X509 objects')
+        p = sk_value(self.ptr, index)
+        sk_set(self.ptr, index, libcrypto.X509_dup(value.cert))
         libcrypto.X509_free(p)
     def __delitem__(self, index):
         if not self.need_free:
             raise ValueError("Stack is read-only")
         if index < 0 or index >= len(self):
             raise IndexError
         libcrypto.X509_free(p)
     def __delitem__(self, index):
         if not self.need_free:
             raise ValueError("Stack is read-only")
         if index < 0 or index >= len(self):
             raise IndexError
-        p = libcrypto.sk_delete(self.ptr, index)
+        p = sk_delete(self.ptr, index)
         libcrypto.X509_free(p)
     def __del__(self):
         if self.need_free:
         libcrypto.X509_free(p)
     def __del__(self):
         if self.need_free:
-            libcrypto.sk_pop_free(self.ptr, libcrypto.X509_free)
+            sk_pop_free(self.ptr, libcrypto.X509_free)
     def append(self, value):
         """ Adds certificate to stack """
         if not self.need_free:
             raise ValueError("Stack is read-only")
         if not isinstance(value, X509):
     def append(self, value):
         """ Adds certificate to stack """
         if not self.need_free:
             raise ValueError("Stack is read-only")
         if not isinstance(value, X509):
-            raise TypeError('StackOfX508 can contain only X509 objects')
-        libcrypto.sk_push(self.ptr, libcrypto.X509_dup(value.cert))
+            raise TypeError('StackOfX509 can contain only X509 objects')
+        sk_push(self.ptr, libcrypto.X509_dup(value.cert))
 
 
+libcrypto.d2i_X509_bio.argtypes = (c_void_p,POINTER(c_void_p))
 libcrypto.X509_free.argtypes = (c_void_p,)
 libcrypto.X509_dup.restype = c_void_p
 libcrypto.X509_dup.argtypes = (c_void_p, )
 libcrypto.X509_free.argtypes = (c_void_p,)
 libcrypto.X509_dup.restype = c_void_p
 libcrypto.X509_dup.argtypes = (c_void_p, )
@@ -622,38 +663,71 @@ libcrypto.PEM_write_bio_X509.argtypes = (c_void_p, c_void_p)
 libcrypto.ASN1_TIME_print.argtypes = (c_void_p, c_void_p)
 libcrypto.ASN1_INTEGER_get.argtypes = (c_void_p, )
 libcrypto.ASN1_INTEGER_get.restype = c_long
 libcrypto.ASN1_TIME_print.argtypes = (c_void_p, c_void_p)
 libcrypto.ASN1_INTEGER_get.argtypes = (c_void_p, )
 libcrypto.ASN1_INTEGER_get.restype = c_long
+libcrypto.X509_check_ca.argtypes = (c_void_p, )
 libcrypto.X509_get_serialNumber.argtypes = (c_void_p, )
 libcrypto.X509_get_serialNumber.restype = c_void_p
 libcrypto.X509_get_serialNumber.argtypes = (c_void_p, )
 libcrypto.X509_get_serialNumber.restype = c_void_p
+libcrypto.X509_get_subject_name.argtypes = (c_void_p, )
+libcrypto.X509_get_subject_name.restype = c_void_p
+libcrypto.X509_get_issuer_name.argtypes = (c_void_p, )
+libcrypto.X509_get_issuer_name.restype = c_void_p
 libcrypto.X509_NAME_ENTRY_get_object.restype = c_void_p
 libcrypto.X509_NAME_ENTRY_get_object.argtypes = (c_void_p, )
 libcrypto.X509_NAME_ENTRY_get_object.restype = c_void_p
 libcrypto.X509_NAME_ENTRY_get_object.argtypes = (c_void_p, )
+libcrypto.X509_NAME_ENTRY_get_data.restype = c_void_p
+libcrypto.X509_NAME_ENTRY_get_data.argtypes = (c_void_p, )
 libcrypto.OBJ_obj2nid.argtypes = (c_void_p, )
 libcrypto.X509_NAME_get_entry.restype = c_void_p
 libcrypto.X509_NAME_get_entry.argtypes = (c_void_p, c_int)
 libcrypto.X509_STORE_new.restype = c_void_p
 libcrypto.X509_STORE_add_lookup.restype = c_void_p
 libcrypto.X509_STORE_add_lookup.argtypes = (c_void_p, c_void_p)
 libcrypto.OBJ_obj2nid.argtypes = (c_void_p, )
 libcrypto.X509_NAME_get_entry.restype = c_void_p
 libcrypto.X509_NAME_get_entry.argtypes = (c_void_p, c_int)
 libcrypto.X509_STORE_new.restype = c_void_p
 libcrypto.X509_STORE_add_lookup.restype = c_void_p
 libcrypto.X509_STORE_add_lookup.argtypes = (c_void_p, c_void_p)
+libcrypto.X509_STORE_add_cert.argtypes = (c_void_p, c_void_p)
+libcrypto.X509_STORE_CTX_new.restype = c_void_p
+libcrypto.X509_STORE_CTX_free.argtypes = (c_void_p,)
+libcrypto.X509_STORE_CTX_init.argtypes = (c_void_p, c_void_p, c_void_p,
+                                            c_void_p)
+libcrypto.X509_STORE_set_depth.argtypes = (c_void_p, c_int)
+libcrypto.X509_STORE_set_flags.argtypes = (c_void_p, c_ulong)
+libcrypto.X509_STORE_set_purpose.argtypes = (c_void_p, c_int)
 libcrypto.X509_LOOKUP_file.restype = c_void_p
 libcrypto.X509_LOOKUP_hash_dir.restype = c_void_p
 libcrypto.X509_LOOKUP_ctrl.restype = c_int
 libcrypto.X509_LOOKUP_ctrl.argtypes = (c_void_p, c_int, c_char_p, c_long,
                                        POINTER(c_char_p))
 libcrypto.X509_LOOKUP_file.restype = c_void_p
 libcrypto.X509_LOOKUP_hash_dir.restype = c_void_p
 libcrypto.X509_LOOKUP_ctrl.restype = c_int
 libcrypto.X509_LOOKUP_ctrl.argtypes = (c_void_p, c_int, c_char_p, c_long,
                                        POINTER(c_char_p))
+libcrypto.X509_EXTENSION_free.argtypes = (c_void_p, )
 libcrypto.X509_EXTENSION_dup.argtypes = (c_void_p, )
 libcrypto.X509_EXTENSION_dup.restype = POINTER(_x509_ext)
 libcrypto.X509V3_EXT_print.argtypes = (c_void_p, POINTER(_x509_ext), c_long,
                                        c_int)
 libcrypto.X509_get_ext.restype = c_void_p
 libcrypto.X509_get_ext.argtypes = (c_void_p, c_int)
 libcrypto.X509_EXTENSION_dup.argtypes = (c_void_p, )
 libcrypto.X509_EXTENSION_dup.restype = POINTER(_x509_ext)
 libcrypto.X509V3_EXT_print.argtypes = (c_void_p, POINTER(_x509_ext), c_long,
                                        c_int)
 libcrypto.X509_get_ext.restype = c_void_p
 libcrypto.X509_get_ext.argtypes = (c_void_p, c_int)
+libcrypto.X509_get_ext_by_critical.argtypes = (c_void_p, c_int, c_int)
+libcrypto.X509_get_ext_by_NID.argtypes = (c_void_p, c_int, c_int)
+libcrypto.X509_get_ext_count.argtypes = (c_void_p, )
+libcrypto.X509_get_pubkey.restype = c_void_p
+libcrypto.X509_get_pubkey.argtypes = (c_void_p, )
 libcrypto.X509V3_EXT_print.argtypes = (c_void_p, POINTER(_x509_ext), c_long,
 libcrypto.X509V3_EXT_print.argtypes = (c_void_p, POINTER(_x509_ext), c_long,
-                                       c_int)
-libcrypto.sk_num.restupe = c_int
-libcrypto.sk_num.argtypes= (c_void_p,)
-libcrypto.sk_set.argtypes = (c_void_p, c_int, c_void_p)
-libcrypto.sk_set.restype = c_void_p
-libcrypto.sk_value.argtypes = (c_void_p, c_int)
-libcrypto.sk_value.restype = c_void_p
-libcrypto.sk_delete.argtypes = (c_void_p, c_int)
-libcrypto.sk_new_null.restype = c_void_p
-libcrypto.sk_pop_free.argtypes = (c_void_p, c_void_p)
-libcrypto.sk_push.argtypes = (c_void_p, c_void_p)
+      c_int)
+libcrypto.X509_LOOKUP_file.restype = c_void_p
+libcrypto.X509_LOOKUP_hash_dir.restype = c_void_p
+libcrypto.X509_NAME_cmp.argtypes = (c_void_p, c_void_p)
+libcrypto.X509_NAME_entry_count.argtypes = (c_void_p,) 
+libcrypto.X509_NAME_free.argtypes = (c_void_p,)
+libcrypto.X509_NAME_new.restype = c_void_p
+libcrypto.X509_NAME_print_ex.argtypes = (c_void_p, c_void_p, c_int, c_ulong)
+libcrypto.X509_PURPOSE_get_by_sname.argtypes=(c_char_p,)
+libcrypto.X509_verify.argtypes = (c_void_p, c_void_p)
+libcrypto.X509_verify_cert.argtypes = (c_void_p,)
+sk_num.restype = c_int
+sk_num.argtypes= (c_void_p,)
+sk_set.argtypes = (c_void_p, c_int, c_void_p)
+sk_set.restype = c_void_p
+sk_value.argtypes = (c_void_p, c_int)
+sk_value.restype = c_void_p
+sk_delete.argtypes = (c_void_p, c_int)
+sk_delete.restype = c_void_p
+sk_new_null.restype = c_void_p
+sk_pop_free.argtypes = (c_void_p, c_void_p)
+sk_push.argtypes = (c_void_p, c_void_p)
 libcrypto.X509_NAME_hash.restype = c_long
 libcrypto.X509_NAME_hash.argtypes = (c_void_p, )
 libcrypto.X509_NAME_hash.restype = c_long
 libcrypto.X509_NAME_hash.argtypes = (c_void_p, )
+libcrypto.X509_NAME_get_index_by_NID.argtypes = (c_void_p, c_int, c_int)