]> wagner.pp.ru Git - oss/ctypescrypto.git/blobdiff - ctypescrypto/pkey.py
Added support for MAC
[oss/ctypescrypto.git] / ctypescrypto / pkey.py
index e4c8c0257c27924e22f458a529a374517a46c372..510ffcaa85ea395723ecc07ad337119b6bc43e57 100644 (file)
@@ -1,13 +1,27 @@
+"""
+This module provides interface for low-level private/public keypair operation
+
+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 ctypescrypto import libcrypto
 from ctypescrypto.exception import LibCryptoError,clear_err_stack
 from ctypescrypto.bio import Membio
 import sys
 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):
 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
+       """
        cnt=len(u)
        if length<cnt:
                cnt=length
        cnt=len(u)
        if length<cnt:
                cnt=length
@@ -16,16 +30,16 @@ def password_callback(buf,length,rwflag,u):
 
 _cb=CALLBACK_FUNC(password_callback)
 
 
 _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:
        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:
                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":
                        b=Membio(privkey)
                        self.cansign=True
                        if format == "PEM":
@@ -138,7 +152,7 @@ class PKey:
                        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)
 
-                       Algorithn specific parameters for DSA,DH and EC
+                       Algorithm specific parameters for DSA,DH and EC
 
                        paramsfrom=PKey object
 
 
                        paramsfrom=PKey object
 
@@ -158,7 +172,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)
                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:
                if "paramsfrom" in kwargs:
                        ctx=libcrypto.EVP_PKEY_CTX_new(kwargs["paramsfrom"].key,None)
                else:
@@ -189,7 +203,7 @@ class PKey:
                return str(b)
        def exportpriv(self,format="PEM",password=None,cipher=None):
                """
                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
                        If password and cipher are specified, encrypts key
                        on given password, using given algorithm. Cipher must be
                        an ctypescrypto.cipher.CipherType object
@@ -202,7 +216,7 @@ class PKey:
                                raise NotImplementedError("Interactive password entry is not supported")
                        evp_cipher=cipher.cipher
                if format == "PEM":
                                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:
                                password)
                else:
                        if cipher is not None:
@@ -227,9 +241,9 @@ class PKey:
                                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
@@ -273,7 +287,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.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.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,)