1
2
3
4 """OpenSSL/M2Crypto RSA implementation."""
5
6 from .cryptomath import *
7
8 from .rsakey import *
9 from .python_rsakey import Python_RSAKey
10
11
12
13 -def password_callback(v, prompt1='Enter private key passphrase:',
14 prompt2='Verify passphrase:'):
15 from getpass import getpass
16 while 1:
17 try:
18 p1=getpass(prompt1)
19 if v:
20 p2=getpass(prompt2)
21 if p1==p2:
22 break
23 else:
24 break
25 except KeyboardInterrupt:
26 return None
27 return p1
28
29
30 if m2cryptoLoaded:
33 self.rsa = None
34 self._hasPrivateKey = False
35 if (n and not e) or (e and not n):
36 raise AssertionError()
37 if n and e:
38 self.rsa = m2.rsa_new()
39 m2.rsa_set_n(self.rsa, numberToMPI(n))
40 m2.rsa_set_e(self.rsa, numberToMPI(e))
41
43 if self.rsa:
44 m2.rsa_free(self.rsa)
45
47 if name == 'e':
48 if not self.rsa:
49 return 0
50 return mpiToNumber(m2.rsa_get_e(self.rsa))
51 elif name == 'n':
52 if not self.rsa:
53 return 0
54 return mpiToNumber(m2.rsa_get_n(self.rsa))
55 else:
56 raise AttributeError
57
59 return self._hasPrivateKey
60
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
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
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
107 key = OpenSSL_RSAKey()
108 def f():pass
109 key.rsa = m2.rsa_generate_key(bits, 3, f)
110 key._hasPrivateKey = True
111 return key
112 generate = staticmethod(generate)
113
114 - def parse(s, passwordCallback=None):
115
116 start = s.find("-----BEGIN ")
117 if start == -1:
118 raise SyntaxError()
119 s = s[start:]
120 if s.startswith("-----BEGIN "):
121 if passwordCallback==None:
122 callback = password_callback
123 else:
124 def f(v, prompt1=None, prompt2=None):
125 return passwordCallback()
126 callback = f
127 bio = m2.bio_new(m2.bio_s_mem())
128 try:
129 m2.bio_write(bio, s)
130 key = OpenSSL_RSAKey()
131 if s.startswith("-----BEGIN RSA PRIVATE KEY-----"):
132 def f():pass
133 key.rsa = m2.rsa_read_key(bio, callback)
134 if key.rsa == None:
135 raise SyntaxError()
136 key._hasPrivateKey = True
137 elif s.startswith("-----BEGIN PUBLIC KEY-----"):
138 key.rsa = m2.rsa_read_pub_key(bio)
139 if key.rsa == None:
140 raise SyntaxError()
141 key._hasPrivateKey = False
142 else:
143 raise SyntaxError()
144 return key
145 finally:
146 m2.bio_free(bio)
147 else:
148 raise SyntaxError()
149
150 parse = staticmethod(parse)
151