]> www.wagner.pp.ru Git - oss/ctypescrypto.git/commitdiff
Now passess sign/verify tests
authorVictor Wagner <vitus@wagner.pp.ru>
Thu, 5 Jun 2014 18:20:20 +0000 (22:20 +0400)
committerVictor Wagner <vitus@wagner.pp.ru>
Thu, 5 Jun 2014 18:20:20 +0000 (22:20 +0400)
ctypescrypto/pkey.py
tests/testpkey.py

index 0ef789d0bd064ffdbd4e2135c59cc15d7ce13ee1..bb995331bb8d4a757b7a9db149399e7a4a55a21e 100644 (file)
@@ -31,7 +31,7 @@ class PKey:
                        if format == "PEM":
                                self.key=libcrypto.PEM_read_bio_PrivateKey(b.bio,None,_cb,c_char_p(password))
                        else: 
-                               self.key=libcrypto.d2i_PKCS8PrivateKey_bio(b.bio,None,_cb,c_char_p(password))
+                               self.key=libcrypto.d2i_PrivateKey_bio(b.bio,None)
                        if self.key is None:
                                raise PKeyError("error parsing private key")
                elif not pubkey is None:
@@ -75,7 +75,7 @@ class PKey:
                        raise PKeyError("sign_init")
                for oper in kwargs:
                        rv=libcrypto.EVP_PKEY_CTX_ctrl_str(ctx,oper,kwargs[oper])
-                       if rw==-2:
+                       if rv==-2:
                                raise PKeyError("Parameter %s is not supported by key"%(oper))
                        if rv<1:
                                raise PKeyError("Error setting parameter %s"(oper))
@@ -84,9 +84,9 @@ class PKey:
                if libcrypto.EVP_PKEY_sign(ctx,None,byref(siglen),digest,len(digest))<1:
                        raise PKeyError("signing")      
                sig=create_string_buffer(siglen.value)
-               libcrypto.EVP_PKEY_sign(ctx,sig,byref(signlen),digest,len(digest))
+               libcrypto.EVP_PKEY_sign(ctx,sig,byref(siglen),digest,len(digest))
                libcrypto.EVP_PKEY_CTX_free(ctx)
-               return sig.value[:siglen.value]
+               return sig.raw[:siglen.value]
 
        def verify(self,digest,signature,**kwargs):
                """
@@ -100,15 +100,45 @@ class PKey:
                        raise PKeyError("verify_init")
                for oper in kwargs:
                        rv=libcrypto.EVP_PKEY_CTX_ctrl_str(ctx,oper,kwargs[oper])
-                       if rw==-2:
+                       if rv==-2:
                                raise PKeyError("Parameter %s is not supported by key"%(oper))
                        if rv<1:
                                raise PKeyError("Error setting parameter %s"(oper))
                rv=libcrypto.EVP_PKEY_verify(ctx,signature,len(signature),digest,len(digest))
                if rv<0:
                        raise PKeyError("Signature verification")
-               libcrypto=EVP_PKEY_CTX_free(ctx)
+               libcrypto.EVP_PKEY_CTX_free(ctx)
                return rv>0
+       def derive(self,peerkey,**kwargs):
+               """
+                       Derives shared key (DH,ECDH,VKO 34.10). Requires
+                       private key available
+
+                       @param peerkey - other key (may be public only)
+
+                       Keyword parameters are algorithm-specific
+               """
+               ctx=libcrypto.EVP_PKEY_CTX_new(self.key,None)
+               if ctx is None:
+                       raise PKeyError("Initailizing derive context")
+               if libcrypto.EVP_PKEY_derive_init(ctx)<1:
+                       raise PKeyError("derive_init")
+               for oper in kwargs:
+                       rv=libcrypto.EVP_PKEY_CTX_ctrl_str(ctx,oper,kwargs[oper])
+                       if rv==-2:
+                               raise PKeyError("Parameter %s is not supported by key"%(oper))
+                       if rv<1:
+                               raise PKeyError("Error setting parameter %s"(oper))
+               if libcrypto.EVP_PKEY_derive_set_peer(ctx,peerkey.key)<=0:
+                       raise PKeyError("Cannot set peer key")
+               keylen=c_long(0)
+               if libcrypto.EVP_PKEY_derive(ctx,None,byref(keylen))<=0:
+                       raise PKeyError("computing shared key length")
+               buf=create_string_buffer(keylen)
+               if libcrypto.EVP_PKEY_derive(ctx,buf,byref(keylen))<=0:
+                       raise PKeyError("computing actual shared key")
+               libcrypto.EVP_PKEY_CTX_free(ctx)
+               return buf.raw[:keylen]
        def generate(algorithm,**kwargs):
                """
                        Generates new private-public key pair for given algorithm
@@ -139,7 +169,7 @@ class PKey:
                        raise PKeyError("Error generating key")
                libcrypto.EVP_PKEY_CTX_free(ctx)
                return PKey(ptr=key,cansign=True)
-                       
+
 # Declare function prototypes
 libcrypto.EVP_PKEY_cmp.argtypes=(c_void_p,c_void_p)
 libcrypto.PEM_read_bio_PrivateKey.restype=c_void_p
@@ -148,3 +178,7 @@ libcrypto.d2i_PKCS8PrivateKey_bio.restype=c_void_p
 libcrypto.d2i_PKCS8PrivateKey_bio.argtypes=(c_void_p,POINTER(c_void_p),CALLBACK_FUNC,c_char_p)
 libcrypto.PEM_read_bio_PUBKEY.restype=c_void_p
 libcrypto.PEM_read_bio_PUBKEY.argtypes=(c_void_p,POINTER(c_void_p),CALLBACK_FUNC,c_char_p)
+libcrypto.d2i_PUBKEY_bio.restype=c_void_p
+libcrypto.d2i_PUBKEY_bio.argtypes=(c_void_p,c_void_p)
+libcrypto.EVP_PKEY_print_public.argtypes=(c_void_p,c_void_p,c_int,c_void_p)
+
index 9560c1c4b528314833b467340b3c8225c3d2ab85..4b556039b1b3929f0a3d9e0a2f3b6f9f22afdfd3 100644 (file)
@@ -1,9 +1,15 @@
 from ctypescrypto.pkey import PKey
 import unittest
+from base64 import b64decode, b16decode
+
+def pem2der(s):
+       start=s.find('-----\n')
+       finish=s.rfind('\n-----END')
+       data=s[start+6:finish]
+       return b64decode(data)
 
 class TestReadPkey(unittest.TestCase):
-       def test_unencrypted_pem(self):
-               rsa="""-----BEGIN PRIVATE KEY-----
+       rsa="""-----BEGIN PRIVATE KEY-----
 MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAL9CzVZu9bczTmB8
 776pPUoPo6WbAfwQqqiGrj91bk2mYE+MNLo4yIQH45IcwGzkyS8+YyQJf8Bux5BC
 oZ2nwzXm5+JZkxkN1mtMzit2D7/hHmrZLoSbr0sxXFrD4a35RI4hXnSK9Sk01sXA
@@ -20,7 +26,7 @@ Ao6uTm8fnkD4C836wS4mYAPqwRBK1JvnEXEQee9irf+ip89BAg74ViTcGF9lwJwQ
 gOM+X5Db+3pK
 -----END PRIVATE KEY-----
 """
-               keytext="""Public-Key: (1024 bit)
+       rsakeytext="""Public-Key: (1024 bit)
 Modulus:
     00:bf:42:cd:56:6e:f5:b7:33:4e:60:7c:ef:be:a9:
     3d:4a:0f:a3:a5:9b:01:fc:10:aa:a8:86:ae:3f:75:
@@ -33,17 +39,13 @@ Modulus:
     1b:a4:85:ab:b0:87:7b:78:2f
 Exponent: 65537 (0x10001)
 """
-               key=PKey(privkey=rsa)
-               self.assertIsNotNone(key.key)
-               self.assertEqual(str(key),keytext)
-       def test_unencrypted_pem_ec(self):
-               pem="""-----BEGIN EC PRIVATE KEY-----
+       ec1priv="""-----BEGIN EC PRIVATE KEY-----
 MHQCAQEEICpxup3qmbwffBBLrsZx7H7/i/+Wm7jTRttMM1KkaZ3DoAcGBSuBBAAK
 oUQDQgAEVil1nlGelogimdpB8fO45icsdBt2QdYkAvhqdgCWLMG0D4Rj4oCqJcyG
 2WH8J5+0DnGujfEA4TwJ90ECvLa2SA==
 -----END EC PRIVATE KEY-----
 """
-               keytext="""Public-Key: (256 bit)
+       ec1keytext="""Public-Key: (256 bit)
 pub: 
     04:56:29:75:9e:51:9e:96:88:22:99:da:41:f1:f3:
     b8:e6:27:2c:74:1b:76:41:d6:24:02:f8:6a:76:00:
@@ -52,45 +54,44 @@ pub:
     02:bc:b6:b6:48
 ASN1 OID: secp256k1
 """
-               
-               key=PKey(privkey=pem)
-               self.assertIsNotNone(key.key)
-               self.assertEqual(str(key),keytext)
-       def test_pubkey_pem(self):
-               pub="""-----BEGIN PUBLIC KEY-----
+       ec1pub="""-----BEGIN PUBLIC KEY-----
 MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEVil1nlGelogimdpB8fO45icsdBt2QdYk
 AvhqdgCWLMG0D4Rj4oCqJcyG2WH8J5+0DnGujfEA4TwJ90ECvLa2SA==
 -----END PUBLIC KEY-----
 """
-               key=PKey(pubkey=pub)
-               keytext="""Public-Key: (256 bit)
-pub: 
-    04:56:29:75:9e:51:9e:96:88:22:99:da:41:f1:f3:
-    b8:e6:27:2c:74:1b:76:41:d6:24:02:f8:6a:76:00:
-    96:2c:c1:b4:0f:84:63:e2:80:aa:25:cc:86:d9:61:
-    fc:27:9f:b4:0e:71:ae:8d:f1:00:e1:3c:09:f7:41:
-    02:bc:b6:b6:48
-ASN1 OID: secp256k1
-"""
+       def test_unencrypted_pem(self):
+               key=PKey(privkey=self.rsa)
+               self.assertIsNotNone(key.key)
+               self.assertEqual(str(key),self.rsakeytext)
+       def test_unencrypted_pem_ec(self):
+               
+               key=PKey(privkey=self.ec1priv)
+               self.assertIsNotNone(key.key)
+               self.assertEqual(str(key),self.ec1keytext)
+       def test_unencrypted_der_ec(self):
+               key=PKey(privkey=pem2der(self.ec1priv),format="DER")
+               self.assertIsNotNone(key.key)
+               self.assertEqual(str(key),self.ec1keytext)
+       def test_pubkey_pem(self):
+               key=PKey(pubkey=self.ec1pub)
+               self.assertIsNotNone(key.key)   
+               self.assertEqual(str(key),self.ec1keytext)
+       def test_pubkey_der(self):
+               key=PKey(pubkey=pem2der(self.ec1pub),format="DER")
                self.assertIsNotNone(key.key)   
-               self.assertEqual(str(key),keytext)
+               self.assertEqual(str(key),self.ec1keytext)
        def test_compare(self):
-               pem="""-----BEGIN EC PRIVATE KEY-----
-MHQCAQEEICpxup3qmbwffBBLrsZx7H7/i/+Wm7jTRttMM1KkaZ3DoAcGBSuBBAAK
-oUQDQgAEVil1nlGelogimdpB8fO45icsdBt2QdYkAvhqdgCWLMG0D4Rj4oCqJcyG
-2WH8J5+0DnGujfEA4TwJ90ECvLa2SA==
------END EC PRIVATE KEY-----
-"""
-               pub="""-----BEGIN PUBLIC KEY-----
-MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEVil1nlGelogimdpB8fO45icsdBt2QdYk
-AvhqdgCWLMG0D4Rj4oCqJcyG2WH8J5+0DnGujfEA4TwJ90ECvLa2SA==
------END PUBLIC KEY-----
-"""
-               key1=PKey(privkey=pem)
+               key1=PKey(privkey=self.ec1priv)
                self.assertIsNotNone(key1.key)
-               key2=PKey(pubkey=pub)
+               key2=PKey(pubkey=self.ec1pub)
                self.assertIsNotNone(key2.key)
                self.assertEqual(key1,key2)
-
+       def test_sign(self):
+               signer=PKey(privkey=self.ec1priv)
+               digest=b16decode("FFCA2587CFD4846E4CB975B503C9EB940F94566AA394E8BD571458B9DA5097D5")
+               signature=signer.sign(digest)
+               self.assertTrue(len(signature)>0)
+               verifier=PKey(pubkey=self.ec1pub)
+               self.assertTrue(verifier.verify(digest,signature))
 if __name__ == "__main__":
        unittest.main()