]> www.wagner.pp.ru Git - oss/ctypescrypto.git/commitdiff
Fixes some style. Improved tests coverage for bio,oid,digest and cipher. Prepare...
authorVictor Wagner <vitus@wagner.pp.ru>
Sun, 21 Dec 2014 08:47:56 +0000 (11:47 +0300)
committerVictor Wagner <vitus@wagner.pp.ru>
Sun, 21 Dec 2014 08:47:56 +0000 (11:47 +0300)
ctypescrypto/bio.py
ctypescrypto/cipher.py
ctypescrypto/digest.py
ctypescrypto/oid.py
ctypescrypto/pkey.py
ctypescrypto/rand.py
ctypescrypto/x509.py
tests/testbio.py
tests/testdigest.py
tests/testoids.py
tests/testx509.py

index 2743f705032ab407e8583c5bfe04c0a89125739b..b1700b9a869ca80dd1eba7dba1c13117782202b0 100644 (file)
@@ -42,7 +42,7 @@ class Membio(object):
                @param length - if specifed, limits amount of data read. If not BIO is read until end of buffer
                """
                if not length is None:
                @param length - if specifed, limits amount of data read. If not BIO is read until end of buffer
                """
                if not length is None:
-                       if type(length)!=type(0):
+                       if not isinstance(length,(int,long)):
                                raise TypeError("length to read should be number")
                        buf=create_string_buffer(length)
                        readbytes=libcrypto.BIO_read(self.bio,buf,length)
                                raise TypeError("length to read should be number")
                        buf=create_string_buffer(length)
                        readbytes=libcrypto.BIO_read(self.bio,buf,length)
index 332272570f824c9830dbe003a09c123f138b5aa7..815a42541897232853a0721b9fea12be9d42217b 100644 (file)
@@ -171,7 +171,7 @@ class Cipher:
                """
                if self.cipher_finalized :
                        raise CipherError("No updates allowed")
                """
                if self.cipher_finalized :
                        raise CipherError("No updates allowed")
-               if type(data) != type(""):
+               if not isinstance(data,str):
                        raise TypeError("A string is expected")
                if len(data) <= 0:
                        return ""
                        raise TypeError("A string is expected")
                if len(data) <= 0:
                        return ""
index 2963e7034b19eac01bad510ff7ad389e65f0cb1c..30d77c5a57b35f19d2f0aa501f010581ae4740dc 100644 (file)
@@ -41,13 +41,29 @@ class DigestType(object):
        """\r
        def __init__(self,      digest_name):\r
                """\r
        """\r
        def __init__(self,      digest_name):\r
                """\r
-                       Finds digest by its name\r
+                       Finds digest by its name. You can pass Oid object instead of\r
+                       name.\r
+\r
+                       Special case is when None is passed as name. In this case\r
+                       unitialized digest is created, and can be initalized later\r
+                       by setting its digest attribute to pointer to EVP_MD\r
                """\r
                """\r
-               self.digest_name = digest_name\r
-               self.digest = libcrypto.EVP_get_digestbyname(self.digest_name)\r
+               if digest_name is None:\r
+                       return \r
+               if isinstance(digest_name,Oid):\r
+                       self.digest_name=digest_name.longname()\r
+                       self.digest=libcrypto.EVP_get_digestbyname(self.digest_name)\r
+               else:\r
+                       self.digest_name = str(digest_name)\r
+                       self.digest = libcrypto.EVP_get_digestbyname(self.digest_name)\r
                if self.digest is None:\r
                        raise DigestError("Unknown digest: %s" % self.digest_name)\r
 \r
                if self.digest is None:\r
                        raise DigestError("Unknown digest: %s" % self.digest_name)\r
 \r
+       @property\r
+       def name(self):\r
+               if not hasattr(self,'digest_name'):\r
+                       self.digest_name=Oid(libcrypto.EVP_MD_type(self.digest)).longname()\r
+               return self.digest_name\r
        def __del__(self):\r
                pass\r
        def digest_size(self):\r
        def __del__(self):\r
                pass\r
        def digest_size(self):\r
@@ -69,7 +85,7 @@ class Digest(object):
                """\r
                self._clean_ctx()\r
                self.ctx = libcrypto.EVP_MD_CTX_create()\r
                """\r
                self._clean_ctx()\r
                self.ctx = libcrypto.EVP_MD_CTX_create()\r
-               if self.ctx == 0:\r
+               if self.ctx is None:\r
                        raise DigestError("Unable to create digest context")\r
                result = libcrypto.EVP_DigestInit_ex(self.ctx, digest_type.digest, None)\r
                if result == 0:\r
                        raise DigestError("Unable to create digest context")\r
                result = libcrypto.EVP_DigestInit_ex(self.ctx, digest_type.digest, None)\r
                if result == 0:\r
@@ -92,11 +108,11 @@ class Digest(object):
                """\r
                if self.digest_finalized:\r
                        raise DigestError("No updates allowed")\r
                """\r
                if self.digest_finalized:\r
                        raise DigestError("No updates allowed")\r
-               if type(data) != type(""):\r
+               if not isinstance(data,str):\r
                        raise TypeError("A string is expected")\r
                if length is None:\r
                        raise TypeError("A string is expected")\r
                if length is None:\r
-                       length=len(data)\r
-               elif length> len(data):\r
+                       length = len(data)\r
+               elif length > len(data):\r
                        raise ValueError("Specified length is greater than length of data")\r
                result = libcrypto.EVP_DigestUpdate(self.ctx, c_char_p(data), length)\r
                if result != 1:\r
                        raise ValueError("Specified length is greater than length of data")\r
                result = libcrypto.EVP_DigestUpdate(self.ctx, c_char_p(data), length)\r
                if result != 1:\r
index 6941ce4b399b6b353026dfa99aac02238b656e5e..8caa57a68ad766c94cb79b4d40ad99042939e113 100644 (file)
@@ -29,11 +29,13 @@ class Oid(object):
 
        def __init__(self,value):
                " Object constuctor. Accepts string or integer"
 
        def __init__(self,value):
                " Object constuctor. Accepts string or integer"
-               if type(value) == type(""):
+               if isinstance(value,unicode):
+                       value=value.encode('ascii')
+               if isinstance(value,str):
                        self.nid=libcrypto.OBJ_txt2nid(value)
                        if self.nid==0:
                                raise ValueError("Cannot find object %s in the database"%(value))
                        self.nid=libcrypto.OBJ_txt2nid(value)
                        if self.nid==0:
                                raise ValueError("Cannot find object %s in the database"%(value))
-               elif type(value) == type(0):
+               elif isinstance(value,(int,long)):
                        cn=libcrypto.OBJ_nid2sn(value)
                        if cn is None:
                                raise ValueError("No such nid %d in the database"%(value))
                        cn=libcrypto.OBJ_nid2sn(value)
                        if cn is None:
                                raise ValueError("No such nid %d in the database"%(value))
index 85b831d96c870a8e140cecf9f88b1ee00890a6f7..fdf384d3f446c2f97c43e2531e7a457dc9749cb7 100644 (file)
@@ -241,9 +241,9 @@ class PKey(object):
                                continue
                        rv=libcrypto.EVP_PKEY_CTX_ctrl_str(ctx,oper,str(opts[oper]))
                        if rv==-2:
                                continue
                        rv=libcrypto.EVP_PKEY_CTX_ctrl_str(ctx,oper,str(opts[oper]))
                        if rv==-2:
-                               raise PKeyError("Parameter %s is not supported by key"%(oper))
+                               raise PKeyError("Parameter %s is not supported by key"%(oper,))
                        if rv<1:
                        if rv<1:
-                               raise PKeyError("Error setting parameter %s"(oper))
+                               raise PKeyError("Error setting parameter %s"%(oper,))
 # Declare function prototypes
 libcrypto.EVP_PKEY_cmp.argtypes=(c_void_p,c_void_p)
 libcrypto.PEM_read_bio_PrivateKey.restype=c_void_p
 # Declare function prototypes
 libcrypto.EVP_PKEY_cmp.argtypes=(c_void_p,c_void_p)
 libcrypto.PEM_read_bio_PrivateKey.restype=c_void_p
index 4cc86e297fe0151264c517133a96b4c32822aa10..4bc073a1ceb63f727d6022e5586d85d577084dbf 100644 (file)
@@ -47,7 +47,7 @@ def seed(data, entropy=None):
                If entropy is not None, it should be floating point(double)
                value estimating amount of entropy  in the data (in bytes).
        """
                If entropy is not None, it should be floating point(double)
                value estimating amount of entropy  in the data (in bytes).
        """
-       if type(data) != type(""):
+       if not isinstance(data,str):
                raise TypeError("A string is expected")
        ptr = c_char_p(data)
        size = len(data)
                raise TypeError("A string is expected")
        ptr = c_char_p(data)
        size = len(data)
index 44919f1ff9a26be49f66b80570872018c319f84c..4f086328f2ee143afed0c939c6efbb9d7631be22 100644 (file)
@@ -148,7 +148,7 @@ class X509Name(object):
                        # Return first matching field
                        idx=libcrypto.X509_NAME_get_index_by_NID(self.ptr,key.nid,-1)
                        if idx<0:
                        # Return first matching field
                        idx=libcrypto.X509_NAME_get_index_by_NID(self.ptr,key.nid,-1)
                        if idx<0:
-                               raise KeyError("Key not found "+repr(Oid))
+                               raise KeyError("Key not found "+str(Oid))
                        entry=libcrypto.X509_NAME_get_entry(self.ptr,idx)
                        s=libcrypto.X509_NAME_ENTRY_get_data(entry)
                        b=Membio()
                        entry=libcrypto.X509_NAME_get_entry(self.ptr,idx)
                        s=libcrypto.X509_NAME_ENTRY_get_data(entry)
                        b=Membio()
@@ -168,6 +168,8 @@ class X509Name(object):
        def __setitem__(self,key,val):
                if not self.writable:
                        raise ValueError("Attempt to modify constant X509 object")
        def __setitem__(self,key,val):
                if not self.writable:
                        raise ValueError("Attempt to modify constant X509 object")
+               else:
+                       raise NotImplementedError
 
 class _x509_ext(Structure):
        """ Represens C structure X509_EXTENSION """
 
 class _x509_ext(Structure):
        """ Represens C structure X509_EXTENSION """
@@ -191,7 +193,6 @@ class X509_EXT(object):
        def __str__(self):
                b=Membio()
                libcrypto.X509V3_EXT_print(b.bio,self.ptr,0x20010,0)
        def __str__(self):
                b=Membio()
                libcrypto.X509V3_EXT_print(b.bio,self.ptr,0x20010,0)
-               libcrypto.X509V3_EXT_print.argtypes=(c_void_p,POINTER(_x509_ext),c_long,c_int)
                return str(b)
        def __unicode__(self):
                b=Membio()
                return str(b)
        def __unicode__(self):
                b=Membio()
@@ -547,3 +548,4 @@ 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.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.X509V3_EXT_print.argtypes=(c_void_p,POINTER(_x509_ext),c_long,c_int)
index 1bd2e1f1bf68b068e04b3f4fd8450c12e70741e7..c8fc313902765beb809cec9372e9f3cdf8adb3ac 100644 (file)
@@ -6,8 +6,22 @@ class TestRead(unittest.TestCase):
                s="A quick brown fox jumps over a lazy dog"
                bio=Membio(s)
                data=bio.read()
                s="A quick brown fox jumps over a lazy dog"
                bio=Membio(s)
                data=bio.read()
+               self.assertEqual(data,s)
+               data2=bio.read()
+               self.assertEqual(data2,"")
                del bio
                del bio
+       def test_readwithlen(self):
+               s="A quick brown fox jumps over a lazy dog"
+               bio=Membio(s)
+               data=bio.read(len(s))
                self.assertEqual(data,s)
                self.assertEqual(data,s)
+               data2=bio.read(5)
+               self.assertEqual(data2,"")
+       def test_readwrongtype(self):
+               s="A quick brown fox jumps over a lazy dog"
+               bio=Membio(s)
+               with self.assertRaises(TypeError):
+                       data=bio.read("5")
        def test_reset(self):
                s="A quick brown fox jumps over a lazy dog"
                bio=Membio(s)
        def test_reset(self):
                s="A quick brown fox jumps over a lazy dog"
                bio=Membio(s)
index e8400809e08713903092ae279ce571aaab9f222f..741c1d67c1808682a3aba317242c05ea47f353cd 100644 (file)
@@ -9,32 +9,58 @@ class TestDigestType(unittest.TestCase):
                self.assertEqual(d.digest_size(),16)
                self.assertEqual(d.block_size(),64)
                self.assertEqual(d.oid(),Oid("md4"))
                self.assertEqual(d.digest_size(),16)
                self.assertEqual(d.block_size(),64)
                self.assertEqual(d.oid(),Oid("md4"))
+               self.assertEqual(d.name,'md4')
        def test_md5(self):
                d=digest.DigestType("md5")
                self.assertEqual(d.digest_size(),16)
                self.assertEqual(d.block_size(),64)
                self.assertEqual(d.oid(),Oid("md5"))
        def test_md5(self):
                d=digest.DigestType("md5")
                self.assertEqual(d.digest_size(),16)
                self.assertEqual(d.block_size(),64)
                self.assertEqual(d.oid(),Oid("md5"))
+               self.assertEqual(d.name,'md5')
        def test_sha1(self):
                d=digest.DigestType("sha1")
                self.assertEqual(d.digest_size(),20)
                self.assertEqual(d.block_size(),64)
                self.assertEqual(d.oid(),Oid("sha1"))
        def test_sha1(self):
                d=digest.DigestType("sha1")
                self.assertEqual(d.digest_size(),20)
                self.assertEqual(d.block_size(),64)
                self.assertEqual(d.oid(),Oid("sha1"))
+               self.assertEqual(d.name,'sha1')
        def test_sha256(self):
                d=digest.DigestType("sha256")
                self.assertEqual(d.digest_size(),32)
                self.assertEqual(d.block_size(),64)
                self.assertEqual(d.oid(),Oid("sha256"))
        def test_sha256(self):
                d=digest.DigestType("sha256")
                self.assertEqual(d.digest_size(),32)
                self.assertEqual(d.block_size(),64)
                self.assertEqual(d.oid(),Oid("sha256"))
+               self.assertEqual(d.name,'sha256')
        def test_sha384(self):
                d=digest.DigestType("sha384")
                self.assertEqual(d.digest_size(),48)
                self.assertEqual(d.block_size(),128)
                self.assertEqual(d.oid(),Oid("sha384"))
        def test_sha384(self):
                d=digest.DigestType("sha384")
                self.assertEqual(d.digest_size(),48)
                self.assertEqual(d.block_size(),128)
                self.assertEqual(d.oid(),Oid("sha384"))
+               self.assertEqual(d.name,'sha384')
        def test_sha512(self):
                d=digest.DigestType("sha512")
                self.assertEqual(d.digest_size(),64)
                self.assertEqual(d.block_size(),128)
                self.assertEqual(d.oid(),Oid("sha512"))
        def test_sha512(self):
                d=digest.DigestType("sha512")
                self.assertEqual(d.digest_size(),64)
                self.assertEqual(d.block_size(),128)
                self.assertEqual(d.oid(),Oid("sha512"))
-               
+               self.assertEqual(d.name,'sha512')
+       def test_createfromoid(self):
+               oid=Oid('sha256')
+               d=digest.DigestType(oid)
+               self.assertEqual(d.digest_size(),32)
+               self.assertEqual(d.block_size(),64)
+               self.assertEqual(d.oid(),Oid("sha256"))
+               self.assertEqual(d.name,'sha256')
+       def test_createfromEVP_MD(self):
+               d1=digest.DigestType("sha256")
+               d2=digest.DigestType(None)
+               with self.assertRaises(AttributeError):
+                       s=d2.name
+               d2.digest=d1.digest
+               self.assertEqual(d2.digest_size(),32)
+               self.assertEqual(d2.block_size(),64)
+               self.assertEqual(d2.oid(),Oid("sha256"))
+               self.assertEqual(d2.name,'sha256')
+       def test_invalidDigest(self):
+               with self.assertRaises(digest.DigestError):
+                       d=digest.DigestType("no-such-digest")
+
 
 class TestIface(unittest.TestCase):
        """ Test all methods with one algorithms """
 
 class TestIface(unittest.TestCase):
        """ Test all methods with one algorithms """
@@ -46,6 +72,10 @@ class TestIface(unittest.TestCase):
                dgst.update(self.msg)
                self.assertEqual(dgst.digest_size,20)
                self.assertEqual(dgst.hexdigest(),self.dgst)
                dgst.update(self.msg)
                self.assertEqual(dgst.digest_size,20)
                self.assertEqual(dgst.hexdigest(),self.dgst)
+       def test_digestwithdata(self):
+               md=digest.DigestType("sha1")
+               dgst=digest.Digest(md)
+               self.assertEqual(dgst.digest(self.msg),b16decode(self.dgst))
        def test_length(self):
                l=len(self.msg)
                msg=self.msg+" Dog barks furiously."
        def test_length(self):
                l=len(self.msg)
                msg=self.msg+" Dog barks furiously."
index f324f7e663a790daaf57b2f3f5da7e06142b8d05..0ff256484c0917eeb588ca1cadd0913487d603bc 100644 (file)
@@ -24,12 +24,18 @@ class TestStandard(unittest.TestCase):
                o=Oid("2.5.4.3")
                x=Oid(o.nid)
                self.assertEqual(o.nid,x.nid)
                o=Oid("2.5.4.3")
                x=Oid(o.nid)
                self.assertEqual(o.nid,x.nid)
+       def test_fromunicode(self):
+               o=Oid(u'commonName')
+               self.assertEqual(o.shortname(),'CN')
        def test_wrongoid(self):
                with self.assertRaises(ValueError):
                        o=Oid("1.2.3.4.5.6.7.8.10.111.1111")
        def test_wrongname(self):
                with self.assertRaises(ValueError):
                        o=Oid("No such oid in the database")
        def test_wrongoid(self):
                with self.assertRaises(ValueError):
                        o=Oid("1.2.3.4.5.6.7.8.10.111.1111")
        def test_wrongname(self):
                with self.assertRaises(ValueError):
                        o=Oid("No such oid in the database")
+       def test_wrongnid(self):
+               with self.assertRaises(ValueError):
+                       o=Oid(9999999)
        def test_wrongtype(self):
                with self.assertRaises(TypeError):
                        o=Oid([2,5,3,4])
        def test_wrongtype(self):
                with self.assertRaises(TypeError):
                        o=Oid([2,5,3,4])
index a54417ba5733cb0e966f92bc7c196f8b624c2c0b..82b6d55f817615e7dcbf606d87aae96032f12df6 100644 (file)
@@ -118,6 +118,12 @@ zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA
        def test_subject(self):
                c=X509(self.cert1)
                self.assertEqual(unicode(c.subject),u'C=RU,ST=Москва,L=Москва,O=Частное лицо,CN=Виктор Вагнер')
        def test_subject(self):
                c=X509(self.cert1)
                self.assertEqual(unicode(c.subject),u'C=RU,ST=Москва,L=Москва,O=Частное лицо,CN=Виктор Вагнер')
+       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')
+       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'C=RU,ST=Москва,O=Удостоверяющий центр,CN=Виктор Вагнер,emailAddress=vitus@wagner.pp.ru')
        def test_issuer(self):
                c=X509(self.cert1)
                self.assertEqual(unicode(c.issuer),u'C=RU,ST=Москва,O=Удостоверяющий центр,CN=Виктор Вагнер,emailAddress=vitus@wagner.pp.ru')
@@ -125,6 +131,19 @@ zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA
                c=X509(self.cert1)
                self.assertEqual(c.subject[Oid("C")],"RU")
                self.assertEqual(c.subject[Oid("L")],u'\u041c\u043e\u0441\u043a\u0432\u0430')
                c=X509(self.cert1)
                self.assertEqual(c.subject[Oid("C")],"RU")
                self.assertEqual(c.subject[Oid("L")],u'\u041c\u043e\u0441\u043a\u0432\u0430')
+       def test_subjectbadsubfield(self):
+               c=X509(self.cert1)
+               with self.assertRaises(KeyError):
+                       x=c.subject[Oid("streetAddress")]
+       def test_subjectfieldindex(self):
+               c=X509(self.cert1)
+               self.assertEqual(repr(c.subject[0]),repr((Oid('C'),u'RU')))
+       def test_subjectbadindex(self):
+               c=X509(self.cert1)
+               with self.assertRaises(IndexError):
+                       x=c.subject[11]
+               with self.assertRaises(IndexError):
+                       x=c.subject[-1]
        def test_notBefore(self):
                c=X509(self.cert1)
                self.assertEqual(c.startDate,datetime.datetime(2014,10,26,19,07,17,0,utc))
        def test_notBefore(self):
                c=X509(self.cert1)
                self.assertEqual(c.startDate,datetime.datetime(2014,10,26,19,07,17,0,utc))
@@ -169,11 +188,16 @@ zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA
                cert=X509(self.cert1)
                ext=cert.extensions[0]
                self.assertEqual(str(ext),'CA:FALSE')
                cert=X509(self.cert1)
                ext=cert.extensions[0]
                self.assertEqual(str(ext),'CA:FALSE')
+               self.assertEqual(unicode(ext),u'CA:FALSE')
        def test_extenson_find(self):
                cert=X509(self.cert1)
                exts=cert.extensions.find(Oid('subjectAltName'))
                self.assertEqual(len(exts),1)
                self.assertEqual(exts[0].oid,Oid('subjectAltName'))
        def test_extenson_find(self):
                cert=X509(self.cert1)
                exts=cert.extensions.find(Oid('subjectAltName'))
                self.assertEqual(len(exts),1)
                self.assertEqual(exts[0].oid,Oid('subjectAltName'))
+       def test_extension_bad_find(self):
+               cert=X509(self.cert1)
+               with self.assertRaises(TypeError):
+                       exts=cert.extensions.find('subjectAltName')
        def test_extenson_critical(self):
                cert=X509(self.digicert_cert)
                crit_exts=cert.extensions.find_critical()
        def test_extenson_critical(self):
                cert=X509(self.digicert_cert)
                crit_exts=cert.extensions.find_critical()
@@ -190,6 +214,9 @@ zVMSW4SOwg/H7ZMZ2cn6j1g0djIvruFQFGHUqFijyDATI+/GJYw2jxyA
                pk2=c.pubkey
                self.assertFalse(c.verify(key=pk2))
                self.assertTrue(c.verify(key=pubkey))
                pk2=c.pubkey
                self.assertFalse(c.verify(key=pk2))
                self.assertTrue(c.verify(key=pubkey))
+       def test_verify_self_singed(self):
+               ca=X509(self.ca_cert)
+               self.assertTrue(ca.verify())
        def test_default_filestore(self):
                store=X509Store(default=True)
                c1=X509(self.cert1)
        def test_default_filestore(self):
                store=X509Store(default=True)
                c1=X509(self.cert1)