]> www.wagner.pp.ru Git - oss/ctypescrypto.git/blobdiff - ctypescrypto/pkey.py
Fixed most pylint warning.
[oss/ctypescrypto.git] / ctypescrypto / pkey.py
index 1e7078463820f9d9011ba4526fddf4ad888e6057..59da723f7b93f926a44b2d766c19c00842ea939a 100644 (file)
@@ -5,297 +5,354 @@ PKey object of this module is wrapper around OpenSSL EVP_PKEY object.
 """
 
 
-from ctypes import c_char_p,c_void_p,byref,c_int,c_long, c_longlong, create_string_buffer,CFUNCTYPE,POINTER
+from ctypes import 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.exception import LibCryptoError,clear_err_stack
+from ctypescrypto.exception import LibCryptoError, clear_err_stack
 from ctypescrypto.bio import Membio
-import sys
 
-__all__ = ['PKeyError','password_callback','PKey']
+__all__ = ['PKeyError', 'password_callback', 'PKey', 'PW_CALLBACK_FUNC']
 class PKeyError(LibCryptoError):
+    """ Exception thrown if libcrypto finctions return an error """
     pass
 
-CALLBACK_FUNC=CFUNCTYPE(c_int,c_char_p,c_int,c_int,c_char_p)
-def password_callback(buf,length,rwflag,u):
+PW_CALLBACK_FUNC = CFUNCTYPE(c_int, c_char_p, c_int, c_int, c_char_p)
+""" Function type for pem password callback """
+
+def password_callback(buf, length, rwflag, userdata):
     """
-    Example password callback for private key. Assumes that 
-    password is store in the userdata parameter, so allows to pass password
+    Example password callback for private key. Assumes that
+    password is stored 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
-    memmove(buf,u,cnt)
+    cnt = len(userdata)
+    if length < cnt:
+        cnt = length
+    memmove(buf, userdata, cnt)
     return cnt
 
-_cb=CALLBACK_FUNC(password_callback)
+_cb = PW_CALLBACK_FUNC(password_callback)
 
 class PKey(object):
-    def __init__(self,ptr=None,privkey=None,pubkey=None,format="PEM",cansign=False,password=None):
+    """
+    Represents public/private key pair. Wrapper around EVP_PKEY
+    libcrypto object.
+
+    May contain either both private and public key (such objects can be
+    used for signing, deriving shared key as well as verifying or public
+    key only, which can be used for verifying or as peer key when
+    deriving.
+
+    @var cansign is true key has private part.
+    @var key contain pointer to EVP_PKEY and should be passed to various
+         libcrypto routines
+    """
+    def __init__(self, ptr=None, privkey=None, pubkey=None, format="PEM",
+                 cansign=False, password=None, callback=_cb):
         if not ptr is None:
-            self.key=ptr
-            self.cansign=cansign
+            self.key = ptr
+            self.cansign = cansign
             if not privkey is None or not pubkey is None:
-                raise TypeError("Just one of ptr, 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 ptr, pubkey or privkey can be specified")
-            b=Membio(privkey)
-            self.cansign=True
+                raise TypeError("Just one of ptr, pubkey or privkey can " +
+                                "be specified")
+            bio = Membio(privkey)
+            self.cansign = True
             if format == "PEM":
-                self.key=libcrypto.PEM_read_bio_PrivateKey(b.bio,None,_cb,c_char_p(password))
-            else: 
-                self.key=libcrypto.d2i_PrivateKey_bio(b.bio,None)
+                self.key = libcrypto.PEM_read_bio_PrivateKey(bio.bio, None,
+                                                             callback,
+                                                             c_char_p(password))
+            else:
+                self.key = libcrypto.d2i_PrivateKey_bio(bio.bio, None)
             if self.key is None:
                 raise PKeyError("error parsing private key")
         elif not pubkey is None:
-            b=Membio(pubkey)
-            self.cansign=False
+            bio = Membio(pubkey)
+            self.cansign = False
             if format == "PEM":
-                self.key=libcrypto.PEM_read_bio_PUBKEY(b.bio,None,_cb,None)
+                self.key = libcrypto.PEM_read_bio_PUBKEY(bio.bio, None,
+                                                         callback,
+                                                         c_char_p(password))
             else:
-                self.key=libcrypto.d2i_PUBKEY_bio(b.bio,None)
+                self.key = libcrypto.d2i_PUBKEY_bio(bio.bio, None)
             if self.key is None:
                 raise PKeyError("error parsing public key")
         else:
             raise TypeError("Neither public, nor private key is specified")
-            
+
 
     def __del__(self):
+        """ Frees EVP_PKEY object (note, it is reference counted) """
         libcrypto.EVP_PKEY_free(self.key)
-    def __eq__(self,other):
+
+    def __eq__(self, other):
         """ Compares two public keys. If one has private key and other
             doesn't it doesn't affect result of comparation
         """
-        return libcrypto.EVP_PKEY_cmp(self.key,other.key)==1
-    def __ne__(self,other):
+        return libcrypto.EVP_PKEY_cmp(self.key, other.key) == 1
+
+    def __ne__(self, other):
+        """ Compares two public key for not-equality """
         return not self.__eq__(other)
+
     def __str__(self):
-        """ printable representation of public key """  
-        b=Membio()
-        libcrypto.EVP_PKEY_print_public(b.bio,self.key,0,None)
-        return str(b)
+        """ printable representation of public key """
+        bio = Membio()
+        libcrypto.EVP_PKEY_print_public(bio.bio, self.key, 0, None)
+        return str(bio)
 
-    def sign(self,digest,**kwargs):
+    def sign(self, digest, **kwargs):
         """
-            Signs given digest and retirns signature
-            Keyword arguments allows to set various algorithm-specific
-            parameters. See pkeyutl(1) manual.
+        Signs given digest and retirns signature
+        Keyword arguments allows to set various algorithm-specific
+        parameters. See pkeyutl(1) manual.
         """
-        ctx=libcrypto.EVP_PKEY_CTX_new(self.key,None)
+        ctx = libcrypto.EVP_PKEY_CTX_new(self.key, None)
         if ctx is None:
             raise PKeyError("Initailizing sign context")
-        if libcrypto.EVP_PKEY_sign_init(ctx)<1:
+        if libcrypto.EVP_PKEY_sign_init(ctx) < 1:
             raise PKeyError("sign_init")
-        self._configure_context(ctx,kwargs)
+        self._configure_context(ctx, kwargs)
         # Find out signature size
-        siglen=c_long(0)
-        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(siglen),digest,len(digest))
+        siglen = c_long(0)
+        if libcrypto.EVP_PKEY_sign(ctx, None, byref(siglen), digest,
+                                   len(digest)) < 1:
+            raise PKeyError("computing signature length")
+        sig = create_string_buffer(siglen.value)
+        if libcrypto.EVP_PKEY_sign(ctx, sig, byref(siglen), digest,
+                                   len(digest)) < 1:
+            raise PKeyError("signing")
         libcrypto.EVP_PKEY_CTX_free(ctx)
-        return sig.raw[:siglen.value]
+        return sig.raw[:int(siglen.value)]
 
-    def verify(self,digest,signature,**kwargs):
+    def verify(self, digest, signature, **kwargs):
         """
-            Verifies given signature on given digest
-            Returns True if Ok, False if don't match
-            Keyword arguments allows to set algorithm-specific
-            parameters
+        Verifies given signature on given digest
+        Returns True if Ok, False if don't match
+        Keyword arguments allows to set algorithm-specific
+        parameters
         """
-        ctx=libcrypto.EVP_PKEY_CTX_new(self.key,None)
+        ctx = libcrypto.EVP_PKEY_CTX_new(self.key, None)
         if ctx is None:
             raise PKeyError("Initailizing verify context")
-        if libcrypto.EVP_PKEY_verify_init(ctx)<1:
+        if libcrypto.EVP_PKEY_verify_init(ctx) < 1:
             raise PKeyError("verify_init")
-        self._configure_context(ctx,kwargs)
-        rv=libcrypto.EVP_PKEY_verify(ctx,signature,len(signature),digest,len(digest))
-        if rv<0:
+        self._configure_context(ctx, kwargs)
+        ret = libcrypto.EVP_PKEY_verify(ctx, signature, len(signature), digest,
+                                        len(digest))
+        if ret < 0:
             raise PKeyError("Signature verification")
         libcrypto.EVP_PKEY_CTX_free(ctx)
-        return rv>0
-    def derive(self,peerkey,**kwargs):
+        return ret > 0
+
+    def derive(self, peerkey, **kwargs):
         """
-            Derives shared key (DH,ECDH,VKO 34.10). Requires
-            private key available
+        Derives shared key (DH,ECDH,VKO 34.10). Requires
+        private key available
 
-            @param peerkey - other key (may be public only)
+        @param peerkey - other key (may be public only)
 
-            Keyword parameters are algorithm-specific
+        Keyword parameters are algorithm-specific
         """
-        ctx=libcrypto.EVP_PKEY_CTX_new(self.key,None)
+        if not self.cansign:
+            raise ValueError("No private key available")
+        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:
+        if libcrypto.EVP_PKEY_derive_init(ctx) < 1:
             raise PKeyError("derive_init")
 
-        
-        self._configure_context(ctx,kwargs,["ukm"])
-        if libcrypto.EVP_PKEY_derive_set_peer(ctx,peerkey.key)<=0:
+        # This is workaround around missing functionality in GOST engine
+        # it provides only numeric control command to set UKM, not
+        # string one.
+        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:
+            # We just hardcode numeric command to set UKM here
+            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:
+        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.value)
-        if libcrypto.EVP_PKEY_derive(ctx,buf,byref(keylen))<=0:
+        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.value]
+        return buf.raw[:int(keylen.value)]
+
     @staticmethod
-    def generate(algorithm,**kwargs):
+    def generate(algorithm, **kwargs):
         """
-            Generates new private-public key pair for given algorithm
-            (string like 'rsa','ec','gost2001') and algorithm-specific
-            parameters.
+        Generates new private-public key pair for given algorithm
+        (string like 'rsa','ec','gost2001') and algorithm-specific
+        parameters.
 
-            Algorithm specific paramteers for RSA:
+        Algorithm specific paramteers for RSA:
 
-            rsa_keygen_bits=number - size of key to be generated
-            rsa_keygen_pubexp - RSA public expontent(default 65537)
+        rsa_keygen_bits=number - size of key to be generated
+        rsa_keygen_pubexp - RSA public expontent(default 65537)
 
-            Algorithm specific parameters for DSA,DH and EC
+        Algorithm specific parameters for DSA,DH and EC
 
-            paramsfrom=PKey object
+        paramsfrom=PKey object
 
-            copy parameters of newly generated key from existing key
+        copy parameters of newly generated key from existing key
 
-            Algorithm specific parameters for GOST2001
+        Algorithm specific parameters for GOST2001
 
-            paramset= paramset name where name is one of
-            'A','B','C','XA','XB','test'
+        paramset= paramset name where name is one of
+        'A','B','C','XA','XB','test'
 
-            paramsfrom does work too
+        paramsfrom does work too
         """
-        tmpeng=c_void_p(None)
-        ameth=libcrypto.EVP_PKEY_asn1_find_str(byref(tmpeng),algorithm,-1)
+        tmpeng = c_void_p(None)
+        ameth = libcrypto.EVP_PKEY_asn1_find_str(byref(tmpeng), algorithm, -1)
         if ameth is None:
-            raise PKeyError("Algorithm %s not foind\n"%(algname))
+            raise PKeyError("Algorithm %s not foind\n"%(algorithm))
         clear_err_stack()
-        pkey_id=c_int(0)
-        libcrypto.EVP_PKEY_asn1_get0_info(byref(pkey_id),None,None,None,None,ameth)
+        pkey_id = c_int(0)
+        libcrypto.EVP_PKEY_asn1_get0_info(byref(pkey_id), None, None, None,
+                                          None, ameth)
         #libcrypto.ENGINE_finish(tmpeng)
         if "paramsfrom" in kwargs:
-            ctx=libcrypto.EVP_PKEY_CTX_new(kwargs["paramsfrom"].key,None)
+            ctx = libcrypto.EVP_PKEY_CTX_new(kwargs["paramsfrom"].key, None)
         else:
-            ctx=libcrypto.EVP_PKEY_CTX_new_id(pkey_id,None)
+            ctx = libcrypto.EVP_PKEY_CTX_new_id(pkey_id, None)
         # FIXME support EC curve as keyword param by invoking paramgen
         # operation
         if ctx is None:
-            raise PKeyError("Creating context for key type %d"%(pkey_id.value)) 
-        if libcrypto.EVP_PKEY_keygen_init(ctx) <=:
+            raise PKeyError("Creating context for key type %d"%(pkey_id.value))
+        if libcrypto.EVP_PKEY_keygen_init(ctx) <= 0:
             raise PKeyError("keygen_init")
-        PKey._configure_context(ctx,kwargs,["paramsfrom"])
-        key=c_void_p(None)
-        if libcrypto.EVP_PKEY_keygen(ctx,byref(key))<=0:
+        PKey._configure_context(ctx, kwargs, ["paramsfrom"])
+        key = c_void_p(None)
+        if libcrypto.EVP_PKEY_keygen(ctx, byref(key)) <= 0:
             raise PKeyError("Error generating key")
         libcrypto.EVP_PKEY_CTX_free(ctx)
-        return PKey(ptr=key,cansign=True)
-    def exportpub(self,format="PEM"):
+        return PKey(ptr=key, cansign=True)
+
+    def exportpub(self, format="PEM"):
         """
-            Returns public key as PEM or DER structure.
+        Returns public key as PEM or DER structure.
         """
-        b=Membio()
+        bio = Membio()
         if format == "PEM":
-            r=libcrypto.PEM_write_bio_PUBKEY(b.bio,self.key)
+            retcode = libcrypto.PEM_write_bio_PUBKEY(bio.bio, self.key)
         else:
-            r=libcrypto.i2d_PUBKEY_bio(b.bio,self.key)
-        if r==0:
+            retcode = libcrypto.i2d_PUBKEY_bio(bio.bio, self.key)
+        if retcode == 0:
             raise PKeyError("error serializing public key")
-        return str(b)
-    def exportpriv(self,format="PEM",password=None,cipher=None):
+        return str(bio)
+
+    def exportpriv(self, format="PEM", password=None, cipher=None,
+                   callback=_cb):
         """
-            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
+        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
         """
-        b=Membio()
+        bio = Membio()
         if cipher is None:
-            evp_cipher=None
+            evp_cipher = None
         else:
-            if password is None:
-                raise NotImplementedError("Interactive password entry is not supported")
-            evp_cipher=cipher.cipher
+            evp_cipher = cipher.cipher
         if format == "PEM":
-            r=libcrypto.PEM_write_bio_PrivateKey(b.bio,self.key,evp_cipher,None,0,_cb,
-                password)
+            ret = libcrypto.PEM_write_bio_PrivateKey(bio.bio, self.key,
+                                                     evp_cipher, None, 0,
+                                                     callback,
+                                                     c_char_p(password))
         else:
-            if cipher is not None:
-                raise NotImplementedError("Der-formatted encrypted keys are not supported")
-            r=libcrypto.i2d_PrivateKey_bio(b.bio,self.key)
-        if r==0:
+            ret = libcrypto.i2d_PKCS8PrivateKey_bio(bio.bio, self.key,
+                                                    evp_cipher, None, 0,
+                                                    callback,
+                                                    c_char_p(password))
+        if ret == 0:
             raise PKeyError("error serializing private key")
-        return str(b)
+        return str(bio)
+
     @staticmethod
-    def _configure_context(ctx,opts,skip=[]):
+    def _configure_context(ctx, opts, skip=()):
         """
-            Configures context of public key operations
-            @param ctx - context to configure
-            @param opts - dictionary of options (from kwargs of calling
-                function)
-            @param skip - list of options which shouldn't be passed to
-                context
+        Configures context of public key operations
+        @param ctx - context to configure
+        @param opts - dictionary of options (from kwargs of calling
+            function)
+        @param skip - list of options which shouldn't be passed to
+            context
         """
 
         for oper in opts:
             if oper in skip:
                 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,))
-            if rv<1:
-                raise PKeyError("Error setting parameter %s"%(oper,))
+            ret = libcrypto.EVP_PKEY_CTX_ctrl_str(ctx, oper, str(opts[oper]))
+            if ret == -2:
+                raise PKeyError("Parameter %s is not supported by key" % oper)
+            if ret < 1:
+                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
-libcrypto.PEM_read_bio_PrivateKey.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.d2i_PrivateKey_bio.restype=c_void_p
-libcrypto.d2i_PrivateKey_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)
-libcrypto.EVP_PKEY_asn1_find_str.restype=c_void_p
-libcrypto.EVP_PKEY_asn1_find_str.argtypes=(c_void_p,c_char_p,c_int)
-libcrypto.EVP_PKEY_asn1_get0_info.restype=c_int
-libcrypto.EVP_PKEY_asn1_get0_info.argtypes=(POINTER(c_int),POINTER(c_int),POINTER(c_int),POINTER(c_char_p), POINTER(c_char_p),c_void_p)
-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,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)
-libcrypto.EVP_PKEY_CTX_new_id.restype=c_void_p
-libcrypto.EVP_PKEY_CTX_new_id.argtypes=(c_int,c_void_p)
-libcrypto.EVP_PKEY_derive.restype=c_int
-libcrypto.EVP_PKEY_derive.argtypes=(c_void_p,c_char_p,POINTER(c_long))
-libcrypto.EVP_PKEY_derive_init.restype=c_int
-libcrypto.EVP_PKEY_derive_init.argtypes=(c_void_p,)
-libcrypto.EVP_PKEY_derive_set_peer.restype=c_int
-libcrypto.EVP_PKEY_derive_set_peer.argtypes=(c_void_p,c_void_p)
-libcrypto.EVP_PKEY_free.argtypes=(c_void_p,)
-libcrypto.EVP_PKEY_keygen.restype=c_int
-libcrypto.EVP_PKEY_keygen.argtypes=(c_void_p,c_void_p)
-libcrypto.EVP_PKEY_keygen_init.restype=c_int
-libcrypto.EVP_PKEY_keygen_init.argtypes=(c_void_p,)
-libcrypto.EVP_PKEY_sign.restype=c_int
-libcrypto.EVP_PKEY_sign.argtypes=(c_void_p,c_char_p,POINTER(c_long),c_char_p,c_long)
-libcrypto.EVP_PKEY_sign_init.restype=c_int
-libcrypto.EVP_PKEY_sign_init.argtypes=(c_void_p,)
-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,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,)
+libcrypto.EVP_PKEY_cmp.argtypes = (c_void_p, c_void_p)
+libcrypto.PEM_read_bio_PrivateKey.restype = c_void_p
+libcrypto.PEM_read_bio_PrivateKey.argtypes = (c_void_p, POINTER(c_void_p),
+                                              PW_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),
+                                          PW_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.d2i_PrivateKey_bio.restype = c_void_p
+libcrypto.d2i_PrivateKey_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)
+libcrypto.EVP_PKEY_asn1_find_str.restype = c_void_p
+libcrypto.EVP_PKEY_asn1_find_str.argtypes = (c_void_p, c_char_p, c_int)
+libcrypto.EVP_PKEY_asn1_get0_info.restype = c_int
+libcrypto.EVP_PKEY_asn1_get0_info.argtypes = (POINTER(c_int), POINTER(c_int),
+                                              POINTER(c_int), POINTER(c_char_p),
+                                              POINTER(c_char_p), c_void_p)
+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, 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)
+libcrypto.EVP_PKEY_CTX_new_id.restype = c_void_p
+libcrypto.EVP_PKEY_CTX_new_id.argtypes = (c_int, c_void_p)
+libcrypto.EVP_PKEY_derive.restype = c_int
+libcrypto.EVP_PKEY_derive.argtypes = (c_void_p, c_char_p, POINTER(c_long))
+libcrypto.EVP_PKEY_derive_init.restype = c_int
+libcrypto.EVP_PKEY_derive_init.argtypes = (c_void_p, )
+libcrypto.EVP_PKEY_derive_set_peer.restype = c_int
+libcrypto.EVP_PKEY_derive_set_peer.argtypes = (c_void_p, c_void_p)
+libcrypto.EVP_PKEY_free.argtypes = (c_void_p,)
+libcrypto.EVP_PKEY_keygen.restype = c_int
+libcrypto.EVP_PKEY_keygen.argtypes = (c_void_p, c_void_p)
+libcrypto.EVP_PKEY_keygen_init.restype = c_int
+libcrypto.EVP_PKEY_keygen_init.argtypes = (c_void_p, )
+libcrypto.EVP_PKEY_sign.restype = c_int
+libcrypto.EVP_PKEY_sign.argtypes = (c_void_p, c_char_p, POINTER(c_long),
+                                    c_char_p, c_long)
+libcrypto.EVP_PKEY_sign_init.restype = c_int
+libcrypto.EVP_PKEY_sign_init.argtypes = (c_void_p, )
+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, c_void_p,
+                                               c_char_p, c_int,
+                                               PW_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_PKCS8PrivateKey_bio.argtypes = (c_void_p, c_void_p, c_void_p,
+                                              c_char_p, c_int,
+                                              PW_CALLBACK_FUNC, c_char_p)
+libcrypto.ENGINE_finish.argtypes = (c_void_p, )