]> www.wagner.pp.ru Git - oss/ctypescrypto.git/blob - ctypescrypto/pkey.py
Initial commit of modules
[oss/ctypescrypto.git] / ctypescrypto / pkey.py
1 from ctypes import byref,c_int,c_long, c_longlong, create_string_buffer
2 from ctypescrypto import libcrypto
3 from ctypescrypto.exception import LibCryptoErrors,clear_err_stack
4 from ctypescrypto.bio import Membio
5
6 class PKeyError(LibCryptoError):
7         pass
8
9 class PKey:
10         def __init__(self,ptr,cansign)
11                 self.key=ptr:
12                 self.cansign=cansign
13         def __del__(self):
14                 libcrypto.EVP_PKEY_free(self.key)
15         def __eq__(self,other):
16                 """ Compares two public keys. If one has private key and other
17                         doesn't it doesn't affect result of comparation
18                 """
19                 return libcrypto.EVP_PKEY_cmp(self.key,other.key)==1
20         def __ne__(self,other):
21                 return not self.__eq__(other)
22         def __str__(self):
23                 """ printable representation of public key """  
24                 b=Membio()
25                 libcrypto.EVP_PKEY_print_public(b.bio,self.key,0,NULL)
26                 return str(b)
27         def privpem(s,password=None):
28                 """ Class method for load from the pem string of private key """
29                 b=Membio(s)
30                 return PKey(libcrypto.PEM_read_bio_PrivateKey(b.bio,NULL,cb,c_char_p(password))
31
32         def privder(s):
33                 """ Class method for load from the binary ASN1 structure of private key """
34                 b=Membio(s)
35                 return PKey(libcrypto.d2i_PrivateKey_bio(b.bio,NULL),True)
36         def pubpem(s):
37                 """ Class method for load from public key pem string"""
38                 b=Membio(s)
39                 return PKey(libcrypto.PEM_read_bio_PUBKEY(b.bio,NULL,cb,c_char_p(password)),False)
40         def pubder(s):
41                 """ Class method for load from the binary ASN1 structure """
42                 b=Membio(s)
43                 return PKey(libcrypto.d2i_PUBKEY_bio(b.bio,NULL),False)
44         def sign(self,digest,**kwargs):
45                 """
46                         Signs given digest and retirns signature
47                         Keyword arguments allows to set various algorithm-specific
48                         parameters. See pkeyutl(1) manual.
49                 """
50                 ctx=libcrypto.EVP_PKEY_CTX_new(self.key,None)
51                 if ctx is None:
52                         raise PkeyError("Initailizing sign context")
53                 if libcrypto.EVP_PKEY_sign_init(ctx)<1:
54                         raise PkeyError("sign_init")
55                 for oper in kwargs:
56                         rv=libcrypto.EVP_PKEY_CTX_ctrl_str(ctx,oper,kwargs[oper])
57                         if rw=-2:
58                                 raise PKeyError("Parameter %s is not supported by key"%(oper))
59                         if rv<1:
60                                 raise PKeyError("Error setting parameter %s"(oper))
61                 # Find out signature size
62                 siglen=c_long(0)
63                 if libcrypto.EVP_PKEY_sign(ctx,None,byref(siglen),digest,len(digest))<1:
64                         raise PkeyError("signing")      
65                 sig=create_string_buffer(siglen.value)
66                 libcrypto.EVP_PKEY_sign(ctx,sig,byref(signlen),digest,len(digest)
67                 libcrypto.EVP_PKEY_CTX_free(ctx)
68                 return sig.value[:siglen.value]
69
70         def verify(self,digest,signature,**kwargs):
71                 """
72                         Verifies given signature on given digest
73                         Returns True if Ok, False if don't match
74                 """
75                 ctx=libcrypto.EVP_PKEY_CTX_new(self.key,None)
76                 if ctx is None:
77                         raise PkeyError("Initailizing verify context")
78                 if libcrypto.EVP_PKEY_verify_init(ctx)<1:
79                         raise PkeyError("verify_init")
80                 for oper in kwargs:
81                         rv=libcrypto.EVP_PKEY_CTX_ctrl_str(ctx,oper,kwargs[oper])
82                         if rw=-2:
83                                 raise PKeyError("Parameter %s is not supported by key"%(oper))
84                         if rv<1:
85                                 raise PKeyError("Error setting parameter %s"(oper))
86                 rv=libcrypto.EVP_PKEY_verify(ctx,signature,len(signature),digest,len(digest))
87                 if rv<0:
88                         raise PKeyError("Signature verification")
89                 libcrypto=EVP_PKEY_CTX_free(ctx)
90                 return rv>0
91         def generate(algorithm,**kwargs):
92                 """
93                         Generates new private-public key pair for given algorithm
94                         (string like 'rsa','ec','gost2001') and algorithm-specific
95                         parameters
96                 """
97                 tmpeng=c_void_p(None)
98                 ameth=libcrypto.EVP_PKEY_asn1_find_str(byref(tmpeng),algorithm,-1)
99                 if ameth is None:
100                         raise PKeyError("Algorithm %s not foind\n"%(algname))
101                 clear_err_stack()
102                 pkey_id=c_int(0)
103                 libcrypto.EVP_PKEY_asn1_get0_info(byref(pkey_id),None,None,None,None,ameth)
104                 libcrypto.ENGINE_finish(tmpeng)
105                 ctx=libcrypto.EVP_PKEY_CTX_new_id(pkey_id)
106                 if ctx is None:
107                         raise PKeyError("Creating context for key type %d"%(pkey_id.value)) 
108                 if libcrypto.EVP_PKEY_keygen_init(ctx) <=0 :
109                         raise PKeyError("keygen_init")
110                 for oper in kwargs:
111                         rv=libcrypto.EVP_PKEY_CTX_ctrl_str(ctx,oper,kwargs[oper])
112                         if rw=-2:
113                                 raise PKeyError("Parameter %s is not supported by key"%(oper))
114                         if rv<1:
115                                 raise PKeyError("Error setting parameter %s"(oper))
116                 key=c_void_p(None)
117                 if libcrypto.EVP_PKEY_keygen(ctx,byref(key))<=0:
118                         raise PKeyError("Error generating key")
119                 libcrypto.EVP_PKEY_CTX_free(ctx)
120                 return PKey(key,True)
121                         
122 class X509:
123         def __init__(self,ptr):
124                 self.cert = ptr
125         def __del__(self):
126                 libcrypto.X509_free(self.cert)
127         def __str__(self):
128                 """ Returns der string of the certificate """
129         def pubkey(self):
130                 """ Returns EVP PKEy object of certificate public key"""
131                 return PKey(libcrypto.X509_get_pubkey(self.cert,False)
132         def verify(self,key):   
133                 """ Verify self on given issuer key """
134         def frompem(s):
135                 """ Create X509 object from pem string """
136         def fromder(s):
137                 """ Create X509 object from der string """
138
139 class Verifier:
140         def __init__(self,filename):
141         
142         def verify_cert(self,cert):
143
144 class Signer:
145         def __init__(self,key):
146                 self.key = key
147         def sign(self,digest):
148                 if not self.key.cansign:
149                         raise ValueError("Current PKey doesn't contain private part")
150         def verify(self,signature,digest):
151