]> www.wagner.pp.ru Git - oss/ctypescrypto.git/commitdiff
Python 3 support for modules pbkdf2 pkey ec x509
authorVictor Wagner <vitus@wagner.pp.ru>
Sun, 29 Apr 2018 16:07:52 +0000 (19:07 +0300)
committerVictor Wagner <vitus@wagner.pp.ru>
Sun, 29 Apr 2018 16:07:52 +0000 (19:07 +0300)
ctypescrypto/bio.py
ctypescrypto/pbkdf2.py
ctypescrypto/pkey.py
ctypescrypto/x509.py
tests/testec.py
tests/testpbkdf.py
tests/testpkey.py
tests/testx509.py

index 75d5f6a608ad9294c5b820d065301f5ec4e34f7d..0c80263b08fb500f2e46a9ca13321127ff7d2dd2 100644 (file)
@@ -1,7 +1,7 @@
 """
 Interface to OpenSSL BIO library
 """
 """
 Interface to OpenSSL BIO library
 """
-from ctypescrypto import libcrypto,pyver, inttype
+from ctypescrypto import libcrypto,pyver, inttype, chartype
 from ctypes import c_char_p, c_void_p, c_int, string_at, c_long
 from ctypes import POINTER, byref, create_string_buffer
 class Membio(object):
 from ctypes import c_char_p, c_void_p, c_int, string_at, c_long
 from ctypes import POINTER, byref, create_string_buffer
 class Membio(object):
@@ -9,19 +9,30 @@ class Membio(object):
     Provides interface to OpenSSL memory bios
     use str() or unicode() to get contents of writable bio
     use bio member to pass to libcrypto function
     Provides interface to OpenSSL memory bios
     use str() or unicode() to get contents of writable bio
     use bio member to pass to libcrypto function
+    
     """
     """
-    def __init__(self, data=None):
+    def __init__(self, data=None, clone=False):
         """
         """
-        If data is specified, creates read-only BIO. If data is
+        If data is specified, creates read-only BIO. 
+        If clone is True, makes copy of data in the instance member
+        If data is
         None, creates writable BIO, contents of which can be retrieved
         by str() or unicode()
         None, creates writable BIO, contents of which can be retrieved
         by str() or unicode()
+        
         """
         if data is None:
             method = libcrypto.BIO_s_mem()
             self.bio = libcrypto.BIO_new(method)
         else:
         """
         if data is None:
             method = libcrypto.BIO_s_mem()
             self.bio = libcrypto.BIO_new(method)
         else:
-            self.bio = libcrypto.BIO_new_mem_buf(c_char_p(data), len(data))
-
+            if isinstance(data, chartype):
+                data = data.encode("utf-8")
+                clone = True
+            if clone :
+                self.data = data
+                self.bio = libcrypto.BIO_new_mem_buf(c_char_p(self.data), len(data))
+            else:
+                self.bio = libcrypto.BIO_new_mem_buf(c_char_p(data), len(data))
+                
     def __del__(self):
         """
         Cleans up memory used by bio
     def __del__(self):
         """
         Cleans up memory used by bio
index bde567b5e361e119758ef0e7037a073ceb6bb519..2a2125af9f802b6532c3911d4f4cf7623aa0f29f 100644 (file)
@@ -4,7 +4,7 @@ PKCS5 PBKDF2 function.
 """
 
 from ctypes import c_char_p, c_int, c_void_p, create_string_buffer
 """
 
 from ctypes import c_char_p, c_int, c_void_p, create_string_buffer
-from ctypescrypto import libcrypto
+from ctypescrypto import libcrypto, chartype
 from ctypescrypto.digest import DigestType
 from ctypescrypto.exception import LibCryptoError
 
 from ctypescrypto.digest import DigestType
 from ctypescrypto.exception import LibCryptoError
 
@@ -25,7 +25,11 @@ def pbkdf2(password, salt, outlen, digesttype="sha1", iterations=2000):
     """
     dgst = DigestType(digesttype)
     out = create_string_buffer(outlen)
     """
     dgst = DigestType(digesttype)
     out = create_string_buffer(outlen)
-    res = libcrypto.PKCS5_PBKDF2_HMAC(password, len(password), salt, len(salt),
+    if isinstance(password,chartype):
+        pwd = password.encode("utf-8")
+    else:
+        pwd = password
+    res = libcrypto.PKCS5_PBKDF2_HMAC(pwd, len(pwd), salt, len(salt),
                                       iterations, dgst.digest, outlen, out)
     if res <= 0:
         raise LibCryptoError("error computing PBKDF2")
                                       iterations, dgst.digest, outlen, out)
     if res <= 0:
         raise LibCryptoError("error computing PBKDF2")
index af31a6725bc5ed04726ee7c401bed94e3ee331e6..97fe4b131dd8c175db95a90168451523d9871517 100644 (file)
@@ -7,7 +7,7 @@ PKey object of this module is wrapper around OpenSSL EVP_PKEY object.
 
 from ctypes import c_char, c_char_p, c_void_p, c_int, c_long, POINTER
 from ctypes import create_string_buffer, byref, memmove, CFUNCTYPE
 
 from ctypes import c_char, c_char_p, c_void_p, c_int, c_long, POINTER
 from ctypes import create_string_buffer, byref, memmove, CFUNCTYPE
-from ctypescrypto import libcrypto
+from ctypescrypto import libcrypto,pyver,bintype,chartype
 from ctypescrypto.exception import LibCryptoError, clear_err_stack
 from ctypescrypto.bio import Membio
 
 from ctypescrypto.exception import LibCryptoError, clear_err_stack
 from ctypescrypto.bio import Membio
 
@@ -32,18 +32,35 @@ def _password_callback(c):
     if  c is None:
         return PW_CALLBACK_FUNC(0)
     if callable(c):
     if  c is None:
         return PW_CALLBACK_FUNC(0)
     if callable(c):
-         def __cb(buf, length, rwflag, userdata):
-             pwd = c(rwflag)
-             cnt = min(len(pwd),length)
-             memmove(buf,pwd, cnt)
-             return cnt
+        if pyver ==2 :
+            def __cb(buf, length, rwflag, userdata):
+                pwd = c(rwflag)
+                cnt = min(len(pwd),length)
+                memmove(buf,pwd, cnt)
+                return cnt
+        else:        
+            def __cb(buf, length, rwflag, userdata):
+                pwd = c(rwflag).encode("utf-8")
+                cnt = min(len(pwd),length)
+                memmove(buf,pwd, cnt)
+                return cnt
     else:
     else:
+        if pyver > 2:
+            c=c.encode("utf-8")
         def __cb(buf,length,rwflag,userdata):
             cnt=min(len(c),length)
             memmove(buf,c,cnt)
             return cnt
     return PW_CALLBACK_FUNC(__cb)        
 
         def __cb(buf,length,rwflag,userdata):
             cnt=min(len(c),length)
             memmove(buf,c,cnt)
             return cnt
     return PW_CALLBACK_FUNC(__cb)        
 
+def _keybio(blob, format):
+    # But DER string should be binary
+    if format == "PEM" and isinstance(blob,chartype):
+        return Membio(blob.encode("ascii"),clone=True)
+    elif isinstance(blob,bintype):
+        return Membio(blob)
+    else:
+        raise TypeError("Key should be either blob or PEM string")
 
 class PKey(object):
     """
 
 class PKey(object):
     """
@@ -100,7 +117,7 @@ class PKey(object):
             if not pubkey is None:
                 raise TypeError("Just one of ptr, pubkey or privkey can " +
                                 "be specified")
             if not pubkey is None:
                 raise TypeError("Just one of ptr, pubkey or privkey can " +
                                 "be specified")
-            bio = Membio(privkey)
+            bio=_keybio(privkey,format)
             self.cansign = True
             if format == "PEM":
                 self.key = libcrypto.PEM_read_bio_PrivateKey(bio.bio, None,
             self.cansign = True
             if format == "PEM":
                 self.key = libcrypto.PEM_read_bio_PrivateKey(bio.bio, None,
@@ -116,7 +133,7 @@ class PKey(object):
             if self.key is None:
                 raise PKeyError("error parsing private key")
         elif not pubkey is None:
             if self.key is None:
                 raise PKeyError("error parsing private key")
         elif not pubkey is None:
-            bio = Membio(pubkey)
+            bio = _keybio(pubkey,format)
             self.cansign = False
             if format == "PEM":
                 self.key = libcrypto.PEM_read_bio_PUBKEY(bio.bio, None,
             self.cansign = False
             if format == "PEM":
                 self.key = libcrypto.PEM_read_bio_PUBKEY(bio.bio, None,
@@ -132,7 +149,8 @@ class PKey(object):
 
     def __del__(self):
         """ Frees EVP_PKEY object (note, it is reference counted) """
 
     def __del__(self):
         """ Frees EVP_PKEY object (note, it is reference counted) """
-        libcrypto.EVP_PKEY_free(self.key)
+        if hasattr(self,"key"):
+            libcrypto.EVP_PKEY_free(self.key)
 
     def __eq__(self, other):
         """ Compares two public keys. If one has private key and other
 
     def __eq__(self, other):
         """ Compares two public keys. If one has private key and other
@@ -257,7 +275,11 @@ class PKey(object):
         paramsfrom does work too
         """
         tmpeng = c_void_p(None)
         paramsfrom does work too
         """
         tmpeng = c_void_p(None)
-        ameth = libcrypto.EVP_PKEY_asn1_find_str(byref(tmpeng), algorithm, -1)
+        if isinstance(algorithm, chartype):
+            alg  = algorithm.encode("ascii")
+        else:
+            alg = algorithm
+        ameth = libcrypto.EVP_PKEY_asn1_find_str(byref(tmpeng), alg, -1)
         if ameth is None:
             raise PKeyError("Algorithm %s not foind\n"%(algorithm))
         clear_err_stack()
         if ameth is None:
             raise PKeyError("Algorithm %s not foind\n"%(algorithm))
         clear_err_stack()
@@ -317,14 +339,17 @@ class PKey(object):
                                          evp_cipher, None, 0,
                                          _password_callback(password),
                                          None)
                                          evp_cipher, None, 0,
                                          _password_callback(password),
                                          None)
+            if ret ==0:
+                raise PKeyError("error serializing private key")
+            return str(bio)
         else:
             ret = libcrypto.i2d_PKCS8PrivateKey_bio(bio.bio, self.key,
                                                evp_cipher, None, 0,
                                               _password_callback(password),
                                                None)
         else:
             ret = libcrypto.i2d_PKCS8PrivateKey_bio(bio.bio, self.key,
                                                evp_cipher, None, 0,
                                               _password_callback(password),
                                                None)
-        if ret == 0:
-            raise PKeyError("error serializing private key")
-        return str(bio)
+            if ret ==0:
+                raise PKeyError("error serializing private key")
+            return bintype(bio)
 
     @staticmethod
     def _configure_context(ctx, opts, skip=()):
 
     @staticmethod
     def _configure_context(ctx, opts, skip=()):
@@ -340,7 +365,20 @@ class PKey(object):
         for oper in opts:
             if oper in skip:
                 continue
         for oper in opts:
             if oper in skip:
                 continue
-            ret = libcrypto.EVP_PKEY_CTX_ctrl_str(ctx, oper, str(opts[oper]))
+            if isinstance(oper,chartype):
+                op = oper.encode("ascii")
+            else:
+                op = oper
+            if isinstance(opts[oper],chartype):
+                value = opts[oper].encode("ascii")
+            elif isinstance(opts[oper],bintype):
+                value = opts[oper]
+            else:
+                if pyver == 2:
+                    value = str(opts[oper])
+                else:
+                    value = str(opts[oper]).encode('ascii')
+            ret = libcrypto.EVP_PKEY_CTX_ctrl_str(ctx, op, value)
             if ret == -2:
                 raise PKeyError("Parameter %s is not supported by key" % oper)
             if ret < 1:
             if ret == -2:
                 raise PKeyError("Parameter %s is not supported by key" % oper)
             if ret < 1:
index 91364c4746ce805f8f07da4d30a39485cbdfb28d..35ab1fee27faeb47b199e62385df1239828f02f1 100644 (file)
@@ -13,9 +13,9 @@ from ctypescrypto.bio import Membio
 from ctypescrypto.pkey import PKey
 from ctypescrypto.oid import Oid
 from ctypescrypto.exception import LibCryptoError
 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:
@@ -160,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
@@ -169,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):
         """
@@ -177,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
@@ -190,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):
@@ -201,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:
@@ -211,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")
 
@@ -248,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"
@@ -369,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"""
@@ -492,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:
index ccf289cfe16922f7c09d5705ec3cd243f83e6768..b5d060c7a464096057f200c73954b37f8f260a19 100644 (file)
@@ -1,3 +1,4 @@
+from ctypescrypto import pyver
 from ctypescrypto.oid import Oid
 from ctypescrypto.ec import create
 from base64 import b16decode
 from ctypescrypto.oid import Oid
 from ctypescrypto.ec import create
 from base64 import b16decode
@@ -18,13 +19,13 @@ def dump_pub_key(key):
     """
     return Popen(["openssl","pkey","-text_pub","-noout"],stdin=PIPE,stdout=PIPE).communicate(key)[0]
 class TestEcCreation(unittest.TestCase):
     """
     return Popen(["openssl","pkey","-text_pub","-noout"],stdin=PIPE,stdout=PIPE).communicate(key)[0]
 class TestEcCreation(unittest.TestCase):
-    ec1priv="""-----BEGIN PRIVATE KEY-----
+    ec1priv=b"""-----BEGIN PRIVATE KEY-----
 MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgKnG6neqZvB98EEuuxnHs
 fv+L/5abuNNG20wzUqRpncOhRANCAARWKXWeUZ6WiCKZ2kHx87jmJyx0G3ZB1iQC
 +Gp2AJYswbQPhGPigKolzIbZYfwnn7QOca6N8QDhPAn3QQK8trZI
 -----END PRIVATE KEY-----
 """
 MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgKnG6neqZvB98EEuuxnHs
 fv+L/5abuNNG20wzUqRpncOhRANCAARWKXWeUZ6WiCKZ2kHx87jmJyx0G3ZB1iQC
 +Gp2AJYswbQPhGPigKolzIbZYfwnn7QOca6N8QDhPAn3QQK8trZI
 -----END PRIVATE KEY-----
 """
-    bigkey="""-----BEGIN PRIVATE KEY-----
+    bigkey=b"""-----BEGIN PRIVATE KEY-----
 MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgAAAAAAAAAAAAAAAAAAAA
 AUVRIxlQt1/EQC2hcy/Jvr6hRANCAASRZsKJufkF5V+ePfn2nX81a0oiCV+JT0cV
 cUqktWYGr/GB65Zr5Ky1z/nha2bYCb6U4hTwbJP9CRCZr5hJklXn
 MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgAAAAAAAAAAAAAAAAAAAA
 AUVRIxlQt1/EQC2hcy/Jvr6hRANCAASRZsKJufkF5V+ePfn2nX81a0oiCV+JT0cV
 cUqktWYGr/GB65Zr5Ky1z/nha2bYCb6U4hTwbJP9CRCZr5hJklXn
@@ -34,13 +35,24 @@ cUqktWYGr/GB65Zr5Ky1z/nha2bYCb6U4hTwbJP9CRCZr5hJklXn
         key=create(Oid("secp256k1"),b16decode("2A71BA9DEA99BC1F7C104BAEC671EC7EFF8BFF969BB8D346DB4C3352A4699DC3",True))
             
         out=key.exportpriv()
         key=create(Oid("secp256k1"),b16decode("2A71BA9DEA99BC1F7C104BAEC671EC7EFF8BFF969BB8D346DB4C3352A4699DC3",True))
             
         out=key.exportpriv()
+        if pyver > 2:
+            out=out.encode("ascii")
         self.assertEqual(dump_key(out),dump_key(self.ec1priv))
         self.assertEqual(dump_key(out),dump_key(self.ec1priv))
-        self.assertEqual(str(key),dump_pub_key(self.ec1priv))
+        if pyver == 2:
+            self.assertEqual(str(key),dump_pub_key(self.ec1priv))
+        else:    
+            self.assertEqual(str(key).encode("ascii"),dump_pub_key(self.ec1priv))
 
     def test_bignum(self):
 
     def test_bignum(self):
-        keyval='\xff'*32
+        keyval=b'\xff'*32
         key=create(Oid("secp256k1"),keyval)
         key=create(Oid("secp256k1"),keyval)
-        self.assertEqual(dump_key(key.exportpriv()),dump_key(self.bigkey))
-        self.assertEqual(str(key),dump_pub_key(self.bigkey))
+        keyblob = key.exportpriv()
+        if pyver > 2:
+            keyblob = keyblob.encode("ascii")
+        self.assertEqual(dump_key(keyblob),dump_key(self.bigkey))
+        keyblob2 = str(key)
+        if pyver > 2:
+             keyblob2 = keyblob2.encode('ascii')
+        self.assertEqual(keyblob2,dump_pub_key(self.bigkey))
 if __name__ == "__main__":
     unittest.main()
 if __name__ == "__main__":
     unittest.main()
index 251ce2d8b6cc860e191dc6acd3e9b71dcaf855a6..8979ee3effa3ee068995fc22999d839b66cb5603 100644 (file)
@@ -2,20 +2,20 @@ from ctypescrypto.pbkdf2 import pbkdf2
 import unittest
 
 class TestPBKDF2(unittest.TestCase):
 import unittest
 
 class TestPBKDF2(unittest.TestCase):
-    answersha1='\xc13\xb3\xc8\x80\xc2\t\x01\xdaR]\x08\x03\xaf>\x85\xed\x9bU\xf0\x89\n\x81Ctu\xee\xe3\xfe\xd9\xfd\x85\xe2"\x8c\xfbQ\xfeb4\x8f(ZF\xfd\xc3w\x13'
-    answersha256='oY\xaf\xf7\xfeB7@\xa80%\t\'\xd5r0\xbe\xb4\xf7\xe6TQ\xd2|Tx\xc0e\xff[0a\xe56\xec\xff\xda\xcd\xed~\xbde\xad"\xe8\t\x01o'
-    answersha1_1000='\xe9\xfe\xbf\xf5K\xfc\xe6h\xfd\xe3\x01\xac\xc8Uc\xcc\x9d\xc7\x1e\xf6\xf8\xd7\xaa\xef\x06se\xbe\x0e^e"\xefa\xba\xe1\xb0\x0b\xc1;\xcd\x05G<\xcc\rE\xfb'
+    answersha1=b'\xc13\xb3\xc8\x80\xc2\t\x01\xdaR]\x08\x03\xaf>\x85\xed\x9bU\xf0\x89\n\x81Ctu\xee\xe3\xfe\xd9\xfd\x85\xe2"\x8c\xfbQ\xfeb4\x8f(ZF\xfd\xc3w\x13'
+    answersha256=b'oY\xaf\xf7\xfeB7@\xa80%\t\'\xd5r0\xbe\xb4\xf7\xe6TQ\xd2|Tx\xc0e\xff[0a\xe56\xec\xff\xda\xcd\xed~\xbde\xad"\xe8\t\x01o'
+    answersha1_1000=b'\xe9\xfe\xbf\xf5K\xfc\xe6h\xfd\xe3\x01\xac\xc8Uc\xcc\x9d\xc7\x1e\xf6\xf8\xd7\xaa\xef\x06se\xbe\x0e^e"\xefa\xba\xe1\xb0\x0b\xc1;\xcd\x05G<\xcc\rE\xfb'
     def test_defaults(self):
     def test_defaults(self):
-        d=pbkdf2("password","saltsalt",48)
+        d=pbkdf2("password",b"saltsalt",48)
         self.assertEqual(d,self.answersha1)
     def test_sha1(self):
         self.assertEqual(d,self.answersha1)
     def test_sha1(self):
-        d=pbkdf2("password","saltsalt",48,digesttype="sha1",iterations=2000)
+        d=pbkdf2("password",b"saltsalt",48,digesttype="sha1",iterations=2000)
         self.assertEqual(d,self.answersha1)
     def test_1000iter(self):
         self.assertEqual(d,self.answersha1)
     def test_1000iter(self):
-        d=pbkdf2("password","saltsalt",48,digesttype="sha1",iterations=1000)
+        d=pbkdf2("password",b"saltsalt",48,digesttype="sha1",iterations=1000)
         self.assertEqual(d,self.answersha1_1000)
     def test_sha256(self):  
         self.assertEqual(d,self.answersha1_1000)
     def test_sha256(self):  
-        d=pbkdf2("password","\01\02\03\04\0abc",48,digesttype="sha256")
+        d=pbkdf2("password",b"\01\02\03\04\0abc",48,digesttype="sha256")
         self.assertEqual(d,self.answersha256)
         
 if __name__ == "__main__":
         self.assertEqual(d,self.answersha256)
         
 if __name__ == "__main__":
index 7fda32c75ef2783bd5cfd9f4c5f5344d709f87e0..190cb88fef990215ca9d472104bb57010cd8f286 100644 (file)
@@ -1,4 +1,5 @@
 from ctypescrypto.pkey import PKey
 from ctypescrypto.pkey import PKey
+from ctypescrypto import pyver
 import unittest,re
 from base64 import b64decode, b16decode
 from subprocess import Popen,PIPE,CalledProcessError
 import unittest,re
 from base64 import b64decode, b16decode
 from subprocess import Popen,PIPE,CalledProcessError
@@ -10,10 +11,12 @@ def pem2der(s):
     return b64decode(data)
 
 def runopenssl(args,indata):
     return b64decode(data)
 
 def runopenssl(args,indata):
-    p=Popen(['openssl']+args,stdin=PIPE,stdout=PIPE,stderr=PIPE,universal_newlines=True)
+    p=Popen(['openssl']+args,stdin=PIPE,stdout=PIPE,stderr=PIPE)
     (out,err)=p.communicate(indata)
     if p.returncode:
         raise CalledProcessError(p.returncode," ".join(['openssl']+args)+":"+err)
     (out,err)=p.communicate(indata)
     if p.returncode:
         raise CalledProcessError(p.returncode," ".join(['openssl']+args)+":"+err)
+    if pyver > 2:
+        out = out.decode("utf-8")
     return out
 
 
     return out
 
 
@@ -138,6 +141,8 @@ AvhqdgCWLMG0D4Rj4oCqJcyG2WH8J5+0DnGujfEA4TwJ90ECvLa2SA==
         from ctypescrypto.cipher import CipherType
         key=PKey(privkey=self.rsa)
         pem=key.exportpriv(password='2222',cipher=CipherType("aes256"))
         from ctypescrypto.cipher import CipherType
         key=PKey(privkey=self.rsa)
         pem=key.exportpriv(password='2222',cipher=CipherType("aes256"))
+        if pyver >2:
+            pem = pem.encode("ascii")
         self.assertEqual(runopenssl(["pkey","-text_pub","-noout","-passin","pass:2222"],
                                     pem),self.rsakeytext)
     def test_export_priv_der(self):
         self.assertEqual(runopenssl(["pkey","-text_pub","-noout","-passin","pass:2222"],
                                     pem),self.rsakeytext)
     def test_export_priv_der(self):
index 5be8042db4626c8d1a224067ec2e72dc60e7a0d0..baf9fe154fc91e377f312c4853eaa82b857b822f 100644 (file)
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
 # -*- encoding: utf-8 -*-
 
 #!/usr/bin/env python
 # -*- encoding: utf-8 -*-
 
+from ctypescrypto import chartype, bintype, inttype
 from ctypescrypto.x509 import X509,X509Store,utc,StackOfX509
 from ctypescrypto.oid import Oid
 from tempfile import NamedTemporaryFile
 from ctypescrypto.x509 import X509,X509Store,utc,StackOfX509
 from ctypescrypto.oid import Oid
 from tempfile import NamedTemporaryFile
@@ -122,16 +123,16 @@ zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA
         self.assertEqual(c.pem(),self.cert1)
     def test_subject(self):
         c=X509(self.cert1)
         self.assertEqual(c.pem(),self.cert1)
     def test_subject(self):
         c=X509(self.cert1)
-        self.assertEqual(unicode(c.subject),u'C=RU,ST=Москва,L=Москва,O=Частное лицо,CN=Виктор Вагнер')
+        self.assertEqual(chartype(c.subject),u'C=RU,ST=Москва,L=Москва,O=Частное лицо,CN=Виктор Вагнер')
     def test_subject_str(self):
         c=X509(self.cert1)
     def test_subject_str(self):
         c=X509(self.cert1)
-        self.assertEqual(str(c.subject),b'C=RU,ST=\\D0\\9C\\D0\\BE\\D1\\81\\D0\\BA\\D0\\B2\\D0\\B0,L=\\D0\\9C\\D0\\BE\\D1\\81\\D0\\BA\\D0\\B2\\D0\\B0,O=\\D0\\A7\\D0\\B0\\D1\\81\\D1\\82\\D0\\BD\\D0\\BE\\D0\\B5 \\D0\\BB\\D0\\B8\\D1\\86\\D0\\BE,CN=\\D0\\92\\D0\\B8\\D0\\BA\\D1\\82\\D0\\BE\\D1\\80 \\D0\\92\\D0\\B0\\D0\\B3\\D0\\BD\\D0\\B5\\D1\\80')
+        self.assertEqual(bintype(c.subject),b'C=RU,ST=\\D0\\9C\\D0\\BE\\D1\\81\\D0\\BA\\D0\\B2\\D0\\B0,L=\\D0\\9C\\D0\\BE\\D1\\81\\D0\\BA\\D0\\B2\\D0\\B0,O=\\D0\\A7\\D0\\B0\\D1\\81\\D1\\82\\D0\\BD\\D0\\BE\\D0\\B5 \\D0\\BB\\D0\\B8\\D1\\86\\D0\\BE,CN=\\D0\\92\\D0\\B8\\D0\\BA\\D1\\82\\D0\\BE\\D1\\80 \\D0\\92\\D0\\B0\\D0\\B3\\D0\\BD\\D0\\B5\\D1\\80')
     def test_subject_len(self):
         c=X509(self.cert1)
         self.assertEqual(len(c.subject),5)
     def test_issuer(self):
         c=X509(self.cert1)
     def test_subject_len(self):
         c=X509(self.cert1)
         self.assertEqual(len(c.subject),5)
     def test_issuer(self):
         c=X509(self.cert1)
-        self.assertEqual(unicode(c.issuer),u'O=Удостоверяющий центр,CN=Виктор Вагнер,C=RU,ST=Москва')
+        self.assertEqual(chartype(c.issuer),u'O=Удостоверяющий центр,CN=Виктор Вагнер,C=RU,ST=Москва')
     def test_subjectfields(self):
         c=X509(self.cert1)
         self.assertEqual(c.subject[Oid("C")],"RU")
     def test_subjectfields(self):
         c=X509(self.cert1)
         self.assertEqual(c.subject[Oid("C")],"RU")
@@ -177,7 +178,7 @@ zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA
         self.assertEqual(ca.issuer,ca.subject)
     def test_serial(self):
         c=X509(self.cert1)
         self.assertEqual(ca.issuer,ca.subject)
     def test_serial(self):
         c=X509(self.cert1)
-        self.assertEqual(c.serial,0xf941addf6362d979L)
+        self.assertEqual(c.serial,int("f941addf6362d979",16))
     def test_version(self):
         c=X509(self.cert1)
         self.assertEqual(c.version,3)
     def test_version(self):
         c=X509(self.cert1)
         self.assertEqual(c.version,3)
@@ -206,8 +207,8 @@ zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA
     def test_extension_text(self):
         cert=X509(self.cert1)
         ext=cert.extensions[0]
     def test_extension_text(self):
         cert=X509(self.cert1)
         ext=cert.extensions[0]
-        self.assertEqual(str(ext),'CA:FALSE')
-        self.assertEqual(unicode(ext),u'CA:FALSE')
+        self.assertEqual(bintype(ext),b'CA:FALSE')
+        self.assertEqual(chartype(ext),u'CA:FALSE')
     def test_extenson_find(self):
         cert=X509(self.cert1)
         exts=cert.extensions.find(Oid('subjectAltName'))
     def test_extenson_find(self):
         cert=X509(self.cert1)
         exts=cert.extensions.find(Oid('subjectAltName'))
@@ -246,7 +247,7 @@ zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA
         c2=X509(self.digicert_cert)
         self.assertTrue(c2.verify(store))
     def test_verify_by_filestore(self):
         c2=X509(self.digicert_cert)
         self.assertTrue(c2.verify(store))
     def test_verify_by_filestore(self):
-        trusted=NamedTemporaryFile(delete=False)
+        trusted=NamedTemporaryFile(delete=False,mode="w")
         trusted.write(self.ca_cert)
         trusted.close()
         goodcert=X509(self.cert1)
         trusted.write(self.ca_cert)
         trusted.close()
         goodcert=X509(self.cert1)
@@ -267,21 +268,21 @@ zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA
     def test_certstack1(self):
         l=[]
         l.append(X509(self.cert1))
     def test_certstack1(self):
         l=[]
         l.append(X509(self.cert1))
-        self.assertEqual(unicode(l[0].subject[Oid('CN')]),u'Виктор Вагнер')
+        self.assertEqual(chartype(l[0].subject[Oid('CN')]),u'Виктор Вагнер')
         l.append(X509(self.ca_cert))
         l.append(X509(self.digicert_cert))
         stack=StackOfX509(certs=l)
         self.assertEqual(len(stack),3)
         self.assertTrue(isinstance(stack[1],X509))
         l.append(X509(self.ca_cert))
         l.append(X509(self.digicert_cert))
         stack=StackOfX509(certs=l)
         self.assertEqual(len(stack),3)
         self.assertTrue(isinstance(stack[1],X509))
-        self.assertEqual(unicode(stack[0].subject[Oid('CN')]),u'Виктор Вагнер')
+        self.assertEqual(chartype(stack[0].subject[Oid('CN')]),u'Виктор Вагнер')
         with self.assertRaises(IndexError):
             c=stack[-1]
         with self.assertRaises(IndexError):
             c=stack[3]
         del stack[1]
         self.assertEqual(len(stack),2)
         with self.assertRaises(IndexError):
             c=stack[-1]
         with self.assertRaises(IndexError):
             c=stack[3]
         del stack[1]
         self.assertEqual(len(stack),2)
-        self.assertEqual(unicode(stack[0].subject[Oid('CN')]),u'Виктор Вагнер')
-        self.assertEqual(unicode(stack[1].subject[Oid('CN')]),u'DigiCert High Assurance EV CA-1')
+        self.assertEqual(chartype(stack[0].subject[Oid('CN')]),u'Виктор Вагнер')
+        self.assertEqual(chartype(stack[1].subject[Oid('CN')]),u'DigiCert High Assurance EV CA-1')
     def test_certstack2(self):
         stack=StackOfX509()
         stack.append(X509(self.cert1))
     def test_certstack2(self):
         stack=StackOfX509()
         stack.append(X509(self.cert1))
@@ -289,7 +290,7 @@ zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA
         c=stack[1]
         stack[1]=X509(self.digicert_cert)
         self.assertEqual(len(stack),2)
         c=stack[1]
         stack[1]=X509(self.digicert_cert)
         self.assertEqual(len(stack),2)
-        self.assertEqual(unicode(stack[1].subject[Oid('CN')]),u'DigiCert High Assurance EV CA-1')
+        self.assertEqual(chartype(stack[1].subject[Oid('CN')]),u'DigiCert High Assurance EV CA-1')
         with self.assertRaises(IndexError):
             stack[-1]=c
         with self.assertRaises(IndexError):
         with self.assertRaises(IndexError):
             stack[-1]=c
         with self.assertRaises(IndexError):
@@ -301,7 +302,7 @@ zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA
     def test_certstack3(self):
         l=[]
         l.append(X509(self.cert1))
     def test_certstack3(self):
         l=[]
         l.append(X509(self.cert1))
-        self.assertEqual(unicode(l[0].subject[Oid('CN')]),u'Виктор Вагнер')
+        self.assertEqual(chartype(l[0].subject[Oid('CN')]),u'Виктор Вагнер')
         l.append(X509(self.ca_cert))
         l.append(X509(self.digicert_cert))
         stack=StackOfX509(certs=l)
         l.append(X509(self.ca_cert))
         l.append(X509(self.digicert_cert))
         stack=StackOfX509(certs=l)