]> www.wagner.pp.ru Git - oss/ctypescrypto.git/blobdiff - ctypescrypto/pkey.py
fixed derive for GOST2001
[oss/ctypescrypto.git] / ctypescrypto / pkey.py
index f011443a2173ede8058e21c4323ba2967462ace2..56e8746ecb919201bf5fcdde568c91f3225c24e7 100644 (file)
@@ -1,26 +1,27 @@
 """
-low-level private/public keypair operation
+This module provides interface for low-level private/public keypair operation
 
 PKey object of this module is wrapper around OpenSSL EVP_PKEY object.
 """
 
-This module provides interface for 
 
 from ctypes import c_char_p,c_void_p,byref,c_int,c_long, c_longlong, create_string_buffer,CFUNCTYPE,POINTER
 from ctypescrypto import libcrypto
 from ctypescrypto.exception import LibCryptoError,clear_err_stack
 from ctypescrypto.bio import Membio
 import sys
+
+__all__ = ['PKeyError','password_callback','PKey']
 class PKeyError(LibCryptoError):
        pass
 
 CALLBACK_FUNC=CFUNCTYPE(c_int,c_char_p,c_int,c_int,c_char_p)
 def password_callback(buf,length,rwflag,u):
-"""
-Example password callback for private key. Assumes that 
-password is store in the userdata parameter, so allows to pass password
-from constructor arguments to the libcrypto keyloading functions
-"""
+       """
+       Example password callback for private key. Assumes that 
+       password is store in the userdata parameter, so allows to pass password
+       from constructor arguments to the libcrypto keyloading functions
+       """
        cnt=len(u)
        if length<cnt:
                cnt=length
@@ -29,16 +30,16 @@ from constructor arguments to the libcrypto keyloading functions
 
 _cb=CALLBACK_FUNC(password_callback)
 
-class PKey:
+class PKey(object):
        def __init__(self,ptr=None,privkey=None,pubkey=None,format="PEM",cansign=False,password=None):
                if not ptr is None:
                        self.key=ptr
                        self.cansign=cansign
                        if not privkey is None or not pubkey is None:
-                               raise TypeError("Just one of pubkey or privkey can be specified")
+                               raise TypeError("Just one of ptr, pubkey or privkey can be specified")
                elif not privkey is None:
                        if not pubkey is None:
-                               raise TypeError("Just one of pubkey or privkey can be specified")
+                               raise TypeError("Just one of ptr, pubkey or privkey can be specified")
                        b=Membio(privkey)
                        self.cansign=True
                        if format == "PEM":
@@ -128,17 +129,22 @@ class PKey:
                        raise PKeyError("Initailizing derive context")
                if libcrypto.EVP_PKEY_derive_init(ctx)<1:
                        raise PKeyError("derive_init")
-               self._configure_context(self,ctx,kwargs)
+
+               
+               self._configure_context(ctx,kwargs,["ukm"])
                if libcrypto.EVP_PKEY_derive_set_peer(ctx,peerkey.key)<=0:
                        raise PKeyError("Cannot set peer key")
+               if "ukm" in kwargs:
+                        if libcrypto.EVP_PKEY_CTX_ctrl(ctx,-1,1<<10,8,8,kwargs["ukm"])<=0:
+                               raise PKeyError("Cannot set UKM")
                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)
+               buf=create_string_buffer(keylen.value)
                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]
+               return buf.raw[:keylen.value]
        @staticmethod
        def generate(algorithm,**kwargs):
                """
@@ -151,7 +157,7 @@ class PKey:
                        rsa_keygen_bits=number - size of key to be generated
                        rsa_keygen_pubexp - RSA public expontent(default 65537)
 
-                       Algorithn specific parameters for DSA,DH and EC
+                       Algorithm specific parameters for DSA,DH and EC
 
                        paramsfrom=PKey object
 
@@ -171,7 +177,7 @@ class PKey:
                clear_err_stack()
                pkey_id=c_int(0)
                libcrypto.EVP_PKEY_asn1_get0_info(byref(pkey_id),None,None,None,None,ameth)
-               libcrypto.ENGINE_finish(tmpeng)
+               #libcrypto.ENGINE_finish(tmpeng)
                if "paramsfrom" in kwargs:
                        ctx=libcrypto.EVP_PKEY_CTX_new(kwargs["paramsfrom"].key,None)
                else:
@@ -202,7 +208,7 @@ class PKey:
                return str(b)
        def exportpriv(self,format="PEM",password=None,cipher=None):
                """
-                       Returns public key as PEM or DER Structure.
+                       Returns private key as PEM or DER Structure.
                        If password and cipher are specified, encrypts key
                        on given password, using given algorithm. Cipher must be
                        an ctypescrypto.cipher.CipherType object
@@ -215,7 +221,7 @@ class PKey:
                                raise NotImplementedError("Interactive password entry is not supported")
                        evp_cipher=cipher.cipher
                if format == "PEM":
-                       r=libcrypto.PEM_write_bio_PrivateKey(b.bio,self.key,evp_cipher,_cb,
+                       r=libcrypto.PEM_write_bio_PrivateKey(b.bio,self.key,evp_cipher,None,0,_cb,
                                password)
                else:
                        if cipher is not None:
@@ -240,9 +246,9 @@ class PKey:
                                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:
-                               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
@@ -261,7 +267,9 @@ libcrypto.EVP_PKEY_asn1_get0_info.argtypes=(POINTER(c_int),POINTER(c_int),POINTE
 libcrypto.EVP_PKEY_cmp.restype=c_int
 libcrypto.EVP_PKEY_cmp.argtypes=(c_void_p,c_void_p)
 libcrypto.EVP_PKEY_CTX_ctrl_str.restype=c_int
-libcrypto.EVP_PKEY_CTX_ctrl_str.argtypes=(c_void_p,)
+libcrypto.EVP_PKEY_CTX_ctrl_str.argtypes=(c_void_p,c_void_p,c_void_p)
+libcrypto.EVP_PKEY_CTX_ctrl.restype=c_int
+libcrypto.EVP_PKEY_CTX_ctrl.argtypes=(c_void_p,c_int,c_int,c_int,c_int,c_void_p)
 libcrypto.EVP_PKEY_CTX_free.argtypes=(c_void_p,)
 libcrypto.EVP_PKEY_CTX_new.restype=c_void_p
 libcrypto.EVP_PKEY_CTX_new.argtypes=(c_void_p,c_void_p)
@@ -286,7 +294,8 @@ libcrypto.EVP_PKEY_verify.restype=c_int
 libcrypto.EVP_PKEY_verify.argtypes=(c_void_p,c_char_p,c_long,c_char_p,c_long)
 libcrypto.EVP_PKEY_verify_init.restype=c_int
 libcrypto.EVP_PKEY_verify_init.argtypes=(c_void_p,)
-libcrypto.PEM_write_bio_PrivateKey.argtypes=(c_void_p,c_void_p,CALLBACK_FUNC,c_char_p)
+libcrypto.PEM_write_bio_PrivateKey.argtypes=(c_void_p,c_void_p,c_void_p,c_char_p,c_int,CALLBACK_FUNC,c_char_p)
 libcrypto.PEM_write_bio_PUBKEY.argtypes=(c_void_p,c_void_p)
 libcrypto.i2d_PUBKEY_bio.argtypes=(c_void_p,c_void_p)
 libcrypto.i2d_PrivateKey_bio.argtypes=(c_void_p,c_void_p)
+libcrypto.ENGINE_finish.argtypes=(c_void_p,)