OLD | NEW |
| (Empty) |
1 """Abstract class for RSA.""" | |
2 | |
3 from cryptomath import * | |
4 | |
5 | |
6 class RSAKey: | |
7 """This is an abstract base class for RSA keys. | |
8 | |
9 Particular implementations of RSA keys, such as | |
10 L{OpenSSL_RSAKey.OpenSSL_RSAKey}, | |
11 L{Python_RSAKey.Python_RSAKey}, and | |
12 L{PyCrypto_RSAKey.PyCrypto_RSAKey}, | |
13 inherit from this. | |
14 | |
15 To create or parse an RSA key, don't use one of these classes | |
16 directly. Instead, use the factory functions in | |
17 L{tlslite.utils.keyfactory}. | |
18 """ | |
19 | |
20 def __init__(self, n=0, e=0): | |
21 """Create a new RSA key. | |
22 | |
23 If n and e are passed in, the new key will be initialized. | |
24 | |
25 @type n: int | |
26 @param n: RSA modulus. | |
27 | |
28 @type e: int | |
29 @param e: RSA public exponent. | |
30 """ | |
31 raise NotImplementedError() | |
32 | |
33 def __len__(self): | |
34 """Return the length of this key in bits. | |
35 | |
36 @rtype: int | |
37 """ | |
38 return numBits(self.n) | |
39 | |
40 def hasPrivateKey(self): | |
41 """Return whether or not this key has a private component. | |
42 | |
43 @rtype: bool | |
44 """ | |
45 raise NotImplementedError() | |
46 | |
47 def hash(self): | |
48 """Return the cryptoID <keyHash> value corresponding to this | |
49 key. | |
50 | |
51 @rtype: str | |
52 """ | |
53 raise NotImplementedError() | |
54 | |
55 def getSigningAlgorithm(self): | |
56 """Return the cryptoID sigAlgo value corresponding to this key. | |
57 | |
58 @rtype: str | |
59 """ | |
60 return "pkcs1-sha1" | |
61 | |
62 def hashAndSign(self, bytes): | |
63 """Hash and sign the passed-in bytes. | |
64 | |
65 This requires the key to have a private component. It performs | |
66 a PKCS1-SHA1 signature on the passed-in data. | |
67 | |
68 @type bytes: str or L{array.array} of unsigned bytes | |
69 @param bytes: The value which will be hashed and signed. | |
70 | |
71 @rtype: L{array.array} of unsigned bytes. | |
72 @return: A PKCS1-SHA1 signature on the passed-in data. | |
73 """ | |
74 if not isinstance(bytes, type("")): | |
75 bytes = bytesToString(bytes) | |
76 hashBytes = stringToBytes(sha.sha(bytes).digest()) | |
77 prefixedHashBytes = self._addPKCS1SHA1Prefix(hashBytes) | |
78 sigBytes = self.sign(prefixedHashBytes) | |
79 return sigBytes | |
80 | |
81 def hashAndVerify(self, sigBytes, bytes): | |
82 """Hash and verify the passed-in bytes with the signature. | |
83 | |
84 This verifies a PKCS1-SHA1 signature on the passed-in data. | |
85 | |
86 @type sigBytes: L{array.array} of unsigned bytes | |
87 @param sigBytes: A PKCS1-SHA1 signature. | |
88 | |
89 @type bytes: str or L{array.array} of unsigned bytes | |
90 @param bytes: The value which will be hashed and verified. | |
91 | |
92 @rtype: bool | |
93 @return: Whether the signature matches the passed-in data. | |
94 """ | |
95 if not isinstance(bytes, type("")): | |
96 bytes = bytesToString(bytes) | |
97 hashBytes = stringToBytes(sha.sha(bytes).digest()) | |
98 prefixedHashBytes = self._addPKCS1SHA1Prefix(hashBytes) | |
99 return self.verify(sigBytes, prefixedHashBytes) | |
100 | |
101 def sign(self, bytes): | |
102 """Sign the passed-in bytes. | |
103 | |
104 This requires the key to have a private component. It performs | |
105 a PKCS1 signature on the passed-in data. | |
106 | |
107 @type bytes: L{array.array} of unsigned bytes | |
108 @param bytes: The value which will be signed. | |
109 | |
110 @rtype: L{array.array} of unsigned bytes. | |
111 @return: A PKCS1 signature on the passed-in data. | |
112 """ | |
113 if not self.hasPrivateKey(): | |
114 raise AssertionError() | |
115 paddedBytes = self._addPKCS1Padding(bytes, 1) | |
116 m = bytesToNumber(paddedBytes) | |
117 if m >= self.n: | |
118 raise ValueError() | |
119 c = self._rawPrivateKeyOp(m) | |
120 sigBytes = numberToBytes(c, numBytes(self.n)) | |
121 return sigBytes | |
122 | |
123 def verify(self, sigBytes, bytes): | |
124 """Verify the passed-in bytes with the signature. | |
125 | |
126 This verifies a PKCS1 signature on the passed-in data. | |
127 | |
128 @type sigBytes: L{array.array} of unsigned bytes | |
129 @param sigBytes: A PKCS1 signature. | |
130 | |
131 @type bytes: L{array.array} of unsigned bytes | |
132 @param bytes: The value which will be verified. | |
133 | |
134 @rtype: bool | |
135 @return: Whether the signature matches the passed-in data. | |
136 """ | |
137 paddedBytes = self._addPKCS1Padding(bytes, 1) | |
138 c = bytesToNumber(sigBytes) | |
139 if c >= self.n: | |
140 return False | |
141 m = self._rawPublicKeyOp(c) | |
142 checkBytes = numberToBytes(m) | |
143 return checkBytes == paddedBytes | |
144 | |
145 def encrypt(self, bytes): | |
146 """Encrypt the passed-in bytes. | |
147 | |
148 This performs PKCS1 encryption of the passed-in data. | |
149 | |
150 @type bytes: L{array.array} of unsigned bytes | |
151 @param bytes: The value which will be encrypted. | |
152 | |
153 @rtype: L{array.array} of unsigned bytes. | |
154 @return: A PKCS1 encryption of the passed-in data. | |
155 """ | |
156 paddedBytes = self._addPKCS1Padding(bytes, 2) | |
157 m = bytesToNumber(paddedBytes) | |
158 if m >= self.n: | |
159 raise ValueError() | |
160 c = self._rawPublicKeyOp(m) | |
161 encBytes = numberToBytes(c) | |
162 return encBytes | |
163 | |
164 def decrypt(self, encBytes): | |
165 """Decrypt the passed-in bytes. | |
166 | |
167 This requires the key to have a private component. It performs | |
168 PKCS1 decryption of the passed-in data. | |
169 | |
170 @type encBytes: L{array.array} of unsigned bytes | |
171 @param encBytes: The value which will be decrypted. | |
172 | |
173 @rtype: L{array.array} of unsigned bytes or None. | |
174 @return: A PKCS1 decryption of the passed-in data or None if | |
175 the data is not properly formatted. | |
176 """ | |
177 if not self.hasPrivateKey(): | |
178 raise AssertionError() | |
179 c = bytesToNumber(encBytes) | |
180 if c >= self.n: | |
181 return None | |
182 m = self._rawPrivateKeyOp(c) | |
183 decBytes = numberToBytes(m) | |
184 if (len(decBytes) != numBytes(self.n)-1): #Check first byte | |
185 return None | |
186 if decBytes[0] != 2: #Check second byte | |
187 return None | |
188 for x in range(len(decBytes)-1): #Scan through for zero separator | |
189 if decBytes[x]== 0: | |
190 break | |
191 else: | |
192 return None | |
193 return decBytes[x+1:] #Return everything after the separator | |
194 | |
195 def _rawPrivateKeyOp(self, m): | |
196 raise NotImplementedError() | |
197 | |
198 def _rawPublicKeyOp(self, c): | |
199 raise NotImplementedError() | |
200 | |
201 def acceptsPassword(self): | |
202 """Return True if the write() method accepts a password for use | |
203 in encrypting the private key. | |
204 | |
205 @rtype: bool | |
206 """ | |
207 raise NotImplementedError() | |
208 | |
209 def write(self, password=None): | |
210 """Return a string containing the key. | |
211 | |
212 @rtype: str | |
213 @return: A string describing the key, in whichever format (PEM | |
214 or XML) is native to the implementation. | |
215 """ | |
216 raise NotImplementedError() | |
217 | |
218 def writeXMLPublicKey(self, indent=''): | |
219 """Return a string containing the key. | |
220 | |
221 @rtype: str | |
222 @return: A string describing the public key, in XML format. | |
223 """ | |
224 return Python_RSAKey(self.n, self.e).write(indent) | |
225 | |
226 def generate(bits): | |
227 """Generate a new key with the specified bit length. | |
228 | |
229 @rtype: L{tlslite.utils.RSAKey.RSAKey} | |
230 """ | |
231 raise NotImplementedError() | |
232 generate = staticmethod(generate) | |
233 | |
234 | |
235 # ************************************************************************** | |
236 # Helper Functions for RSA Keys | |
237 # ************************************************************************** | |
238 | |
239 def _addPKCS1SHA1Prefix(self, bytes): | |
240 prefixBytes = createByteArraySequence(\ | |
241 [48,33,48,9,6,5,43,14,3,2,26,5,0,4,20]) | |
242 prefixedBytes = prefixBytes + bytes | |
243 return prefixedBytes | |
244 | |
245 def _addPKCS1Padding(self, bytes, blockType): | |
246 padLength = (numBytes(self.n) - (len(bytes)+3)) | |
247 if blockType == 1: #Signature padding | |
248 pad = [0xFF] * padLength | |
249 elif blockType == 2: #Encryption padding | |
250 pad = createByteArraySequence([]) | |
251 while len(pad) < padLength: | |
252 padBytes = getRandomBytes(padLength * 2) | |
253 pad = [b for b in padBytes if b != 0] | |
254 pad = pad[:padLength] | |
255 else: | |
256 raise AssertionError() | |
257 | |
258 #NOTE: To be proper, we should add [0,blockType]. However, | |
259 #the zero is lost when the returned padding is converted | |
260 #to a number, so we don't even bother with it. Also, | |
261 #adding it would cause a misalignment in verify() | |
262 padding = createByteArraySequence([blockType] + pad + [0]) | |
263 paddedBytes = padding + bytes | |
264 return paddedBytes | |
OLD | NEW |