]> www.wagner.pp.ru Git - oss/ctypescrypto.git/commitdiff
Added pkey serialization (untested) and started to implement x509
authorVictor Wagner <wagner@atlas-card.ru>
Fri, 6 Jun 2014 13:43:20 +0000 (17:43 +0400)
committerVictor Wagner <wagner@atlas-card.ru>
Fri, 6 Jun 2014 13:43:20 +0000 (17:43 +0400)
ctypescrypto/pkey.py
ctypescrypto/x509.py

index a561ddf23df08bbb7daea0e777ffe00c690b9595..e4c8c0257c27924e22f458a529a374517a46c372 100644 (file)
@@ -175,6 +175,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 public 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,_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 +273,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,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)
index 28c587c1673e879c6a5263cdc967695fe7dd5128..9005fc29f788111f7f64d3c60c2e0a7c49a6158a 100644 (file)
@@ -1,20 +1,28 @@
 from ctypes import c_void_p
 from ctypescrypto.bio import Membio
+from ctypescrypto.pkey import Pkey
 from ctypescrypto.exception import LibCryptoError
 from crypescrypto import libcrypto
 
+class X509Error(LibCryptoError):
+       pass
+
+
 class X509Name:
        def __init__(self,ptr):
                self.ptr=ptr
        def __del__(self):
                libcrypto.X509_NAME_free(self.ptr)
        def __str__(self):
+               b=Membio()
+               libcrypto.X509_NAME_print_ex(b.bio,self.ptr,0,PRING_FLAG)
+               return str(b).decode("utf-8")
 
        def __len__(self):
                return libcrypto.X509_NAME_entry_count(self.ptr)
 
        def __getattr__(self,key):
-         
+               
        def __setattr__(self,key,val):
 
 class X509_extlist:
@@ -36,21 +44,33 @@ class X509_extlist:
 
 
 class X509:
-       def __init__(self,ptr):
-               self.cert = ptr
+       def __init__(self,data=None,ptr=None,format="PEM"):
+               if ptr is not None:
+                       if data is not None: 
+                               raise TypeError("Cannot use data and ptr simultaneously")
+                       self.cert = ptr
+               elif data is None:
+                               raise TypeError("data argument is required")
+                       b=Membio(data)
+                       if format == "PEM":
+                               self.cert=libcrypto.PEM_read_bio_X509(b.bio,None,None,None)
+                       else:
+                               self.cert=libcrypto.d2i_X509_bio(b.bio,None)
+                       if self.cert is None:
+                               raise X509Error("error reading certificate")
        def __del__(self):
                libcrypto.X509_free(self.cert)
        def __str__(self):
                """ Returns der string of the certificate """
+               b=Membio()
+               if libcrypto.i2d_X509_bio(b.bio,self.cert)==0:
+                       raise X509Error("error serializing certificate")
        def pubkey(self):
                """ Returns EVP PKEy object of certificate public key"""
-               return PKey(libcrypto.X509_get_pubkey(self.cert,False)
+               return PKey(ptr=libcrypto.X509_get_pubkey(self.cert,False))
        def verify(self,key):   
                """ Verify self on given issuer key """
-       def frompem(s):
-               """ Create X509 object from pem string """
-       def fromder(s):
-               """ Create X509 object from der string """
+
        def subject(self):
                return X509Name(libcrypto.X509_get_subject_name(self.cert))
        def issuer(self):