]> www.wagner.pp.ru Git - oss/ctypescrypto.git/blobdiff - ctypescrypto/pkey.py
Implemented minimal cert extension support
[oss/ctypescrypto.git] / ctypescrypto / pkey.py
index a561ddf23df08bbb7daea0e777ffe00c690b9595..59a53486f9f62e877cf1748fc5e6c83f5f15a063 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
+
+__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
+       """
        cnt=len(u)
        if length<cnt:
                cnt=length
@@ -175,6 +189,42 @@ class PKey:
                        raise PKeyError("Error generating key")
                libcrypto.EVP_PKEY_CTX_free(ctx)
                return PKey(ptr=key,cansign=True)
+       def exportpub(self,format="PEM"):
+               """
+                       Returns public key as PEM or DER structure.
+               """
+               b=Membio()
+               if format == "PEM":
+                       r=libcrypto.PEM_write_bio_PUBKEY(b.bio,self.key)
+               else:
+                       r=libcrypto.i2d_PUBKEY_bio(b.bio,self.key)
+               if r==0:
+                       raise PKeyError("error serializing public key")
+               return str(b)
+       def exportpriv(self,format="PEM",password=None,cipher=None):
+               """
+                       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()
+               if cipher is None:
+                       evp_cipher=None
+               else:
+                       if password is None:
+                               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,None,0,_cb,
+                               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:
+                       raise PKeyError("error serializing private key")
+               return str(b)
        @staticmethod
        def _configure_context(ctx,opts,skip=[]):
                """
@@ -237,4 +287,7 @@ 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)