OLD | NEW |
| (Empty) |
1 """OpenSSL/M2Crypto RSA implementation.""" | |
2 | |
3 from cryptomath import * | |
4 | |
5 from RSAKey import * | |
6 from Python_RSAKey import Python_RSAKey | |
7 | |
8 #copied from M2Crypto.util.py, so when we load the local copy of m2 | |
9 #we can still use it | |
10 def password_callback(v, prompt1='Enter private key passphrase:', | |
11 prompt2='Verify passphrase:'): | |
12 from getpass import getpass | |
13 while 1: | |
14 try: | |
15 p1=getpass(prompt1) | |
16 if v: | |
17 p2=getpass(prompt2) | |
18 if p1==p2: | |
19 break | |
20 else: | |
21 break | |
22 except KeyboardInterrupt: | |
23 return None | |
24 return p1 | |
25 | |
26 | |
27 if m2cryptoLoaded: | |
28 class OpenSSL_RSAKey(RSAKey): | |
29 def __init__(self, n=0, e=0): | |
30 self.rsa = None | |
31 self._hasPrivateKey = False | |
32 if (n and not e) or (e and not n): | |
33 raise AssertionError() | |
34 if n and e: | |
35 self.rsa = m2.rsa_new() | |
36 m2.rsa_set_n(self.rsa, numberToMPI(n)) | |
37 m2.rsa_set_e(self.rsa, numberToMPI(e)) | |
38 | |
39 def __del__(self): | |
40 if self.rsa: | |
41 m2.rsa_free(self.rsa) | |
42 | |
43 def __getattr__(self, name): | |
44 if name == 'e': | |
45 if not self.rsa: | |
46 return 0 | |
47 return mpiToNumber(m2.rsa_get_e(self.rsa)) | |
48 elif name == 'n': | |
49 if not self.rsa: | |
50 return 0 | |
51 return mpiToNumber(m2.rsa_get_n(self.rsa)) | |
52 else: | |
53 raise AttributeError | |
54 | |
55 def hasPrivateKey(self): | |
56 return self._hasPrivateKey | |
57 | |
58 def hash(self): | |
59 return Python_RSAKey(self.n, self.e).hash() | |
60 | |
61 def _rawPrivateKeyOp(self, m): | |
62 s = numberToString(m) | |
63 byteLength = numBytes(self.n) | |
64 if len(s)== byteLength: | |
65 pass | |
66 elif len(s) == byteLength-1: | |
67 s = '\0' + s | |
68 else: | |
69 raise AssertionError() | |
70 c = stringToNumber(m2.rsa_private_encrypt(self.rsa, s, | |
71 m2.no_padding)) | |
72 return c | |
73 | |
74 def _rawPublicKeyOp(self, c): | |
75 s = numberToString(c) | |
76 byteLength = numBytes(self.n) | |
77 if len(s)== byteLength: | |
78 pass | |
79 elif len(s) == byteLength-1: | |
80 s = '\0' + s | |
81 else: | |
82 raise AssertionError() | |
83 m = stringToNumber(m2.rsa_public_decrypt(self.rsa, s, | |
84 m2.no_padding)) | |
85 return m | |
86 | |
87 def acceptsPassword(self): return True | |
88 | |
89 def write(self, password=None): | |
90 bio = m2.bio_new(m2.bio_s_mem()) | |
91 if self._hasPrivateKey: | |
92 if password: | |
93 def f(v): return password | |
94 m2.rsa_write_key(self.rsa, bio, m2.des_ede_cbc(), f) | |
95 else: | |
96 def f(): pass | |
97 m2.rsa_write_key_no_cipher(self.rsa, bio, f) | |
98 else: | |
99 if password: | |
100 raise AssertionError() | |
101 m2.rsa_write_pub_key(self.rsa, bio) | |
102 s = m2.bio_read(bio, m2.bio_ctrl_pending(bio)) | |
103 m2.bio_free(bio) | |
104 return s | |
105 | |
106 def writeXMLPublicKey(self, indent=''): | |
107 return Python_RSAKey(self.n, self.e).write(indent) | |
108 | |
109 def generate(bits): | |
110 key = OpenSSL_RSAKey() | |
111 def f():pass | |
112 key.rsa = m2.rsa_generate_key(bits, 3, f) | |
113 key._hasPrivateKey = True | |
114 return key | |
115 generate = staticmethod(generate) | |
116 | |
117 def parse(s, passwordCallback=None): | |
118 if s.startswith("-----BEGIN "): | |
119 if passwordCallback==None: | |
120 callback = password_callback | |
121 else: | |
122 def f(v, prompt1=None, prompt2=None): | |
123 return passwordCallback() | |
124 callback = f | |
125 bio = m2.bio_new(m2.bio_s_mem()) | |
126 try: | |
127 m2.bio_write(bio, s) | |
128 key = OpenSSL_RSAKey() | |
129 if s.startswith("-----BEGIN RSA PRIVATE KEY-----"): | |
130 def f():pass | |
131 key.rsa = m2.rsa_read_key(bio, callback) | |
132 if key.rsa == None: | |
133 raise SyntaxError() | |
134 key._hasPrivateKey = True | |
135 elif s.startswith("-----BEGIN PUBLIC KEY-----"): | |
136 key.rsa = m2.rsa_read_pub_key(bio) | |
137 if key.rsa == None: | |
138 raise SyntaxError() | |
139 key._hasPrivateKey = False | |
140 else: | |
141 raise SyntaxError() | |
142 return key | |
143 finally: | |
144 m2.bio_free(bio) | |
145 else: | |
146 raise SyntaxError() | |
147 | |
148 parse = staticmethod(parse) | |
OLD | NEW |