OLD | NEW |
1 # Author: Trevor Perrin | 1 # Author: Trevor Perrin |
2 # See the LICENSE file for legal information regarding use of this file. | 2 # See the LICENSE file for legal information regarding use of this file. |
3 | 3 |
4 """Abstract class for RSA.""" | 4 """Abstract class for RSA.""" |
5 | 5 |
6 from .cryptomath import * | 6 from .cryptomath import * |
7 | 7 |
8 | 8 |
9 class RSAKey(object): | 9 class RSAKey(object): |
10 """This is an abstract base class for RSA keys. | 10 """This is an abstract base class for RSA keys. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
53 This requires the key to have a private component. It performs | 53 This requires the key to have a private component. It performs |
54 a PKCS1-SHA1 signature on the passed-in data. | 54 a PKCS1-SHA1 signature on the passed-in data. |
55 | 55 |
56 @type bytes: str or L{bytearray} of unsigned bytes | 56 @type bytes: str or L{bytearray} of unsigned bytes |
57 @param bytes: The value which will be hashed and signed. | 57 @param bytes: The value which will be hashed and signed. |
58 | 58 |
59 @rtype: L{bytearray} of unsigned bytes. | 59 @rtype: L{bytearray} of unsigned bytes. |
60 @return: A PKCS1-SHA1 signature on the passed-in data. | 60 @return: A PKCS1-SHA1 signature on the passed-in data. |
61 """ | 61 """ |
62 hashBytes = SHA1(bytearray(bytes)) | 62 hashBytes = SHA1(bytearray(bytes)) |
63 prefixedHashBytes = self._addPKCS1SHA1Prefix(hashBytes) | 63 prefixedHashBytes = self.addPKCS1SHA1Prefix(hashBytes) |
64 sigBytes = self.sign(prefixedHashBytes) | 64 sigBytes = self.sign(prefixedHashBytes) |
65 return sigBytes | 65 return sigBytes |
66 | 66 |
67 def hashAndVerify(self, sigBytes, bytes): | 67 def hashAndVerify(self, sigBytes, bytes): |
68 """Hash and verify the passed-in bytes with the signature. | 68 """Hash and verify the passed-in bytes with the signature. |
69 | 69 |
70 This verifies a PKCS1-SHA1 signature on the passed-in data. | 70 This verifies a PKCS1-SHA1 signature on the passed-in data. |
71 | 71 |
72 @type sigBytes: L{bytearray} of unsigned bytes | 72 @type sigBytes: L{bytearray} of unsigned bytes |
73 @param sigBytes: A PKCS1-SHA1 signature. | 73 @param sigBytes: A PKCS1-SHA1 signature. |
74 | 74 |
75 @type bytes: str or L{bytearray} of unsigned bytes | 75 @type bytes: str or L{bytearray} of unsigned bytes |
76 @param bytes: The value which will be hashed and verified. | 76 @param bytes: The value which will be hashed and verified. |
77 | 77 |
78 @rtype: bool | 78 @rtype: bool |
79 @return: Whether the signature matches the passed-in data. | 79 @return: Whether the signature matches the passed-in data. |
80 """ | 80 """ |
81 hashBytes = SHA1(bytearray(bytes)) | 81 hashBytes = SHA1(bytearray(bytes)) |
82 | 82 |
83 # Try it with/without the embedded NULL | 83 # Try it with/without the embedded NULL |
84 prefixedHashBytes1 = self._addPKCS1SHA1Prefix(hashBytes, False) | 84 prefixedHashBytes1 = self.addPKCS1SHA1Prefix(hashBytes, False) |
85 prefixedHashBytes2 = self._addPKCS1SHA1Prefix(hashBytes, True) | 85 prefixedHashBytes2 = self.addPKCS1SHA1Prefix(hashBytes, True) |
86 result1 = self.verify(sigBytes, prefixedHashBytes1) | 86 result1 = self.verify(sigBytes, prefixedHashBytes1) |
87 result2 = self.verify(sigBytes, prefixedHashBytes2) | 87 result2 = self.verify(sigBytes, prefixedHashBytes2) |
88 return (result1 or result2) | 88 return (result1 or result2) |
89 | 89 |
90 def sign(self, bytes): | 90 def sign(self, bytes): |
91 """Sign the passed-in bytes. | 91 """Sign the passed-in bytes. |
92 | 92 |
93 This requires the key to have a private component. It performs | 93 This requires the key to have a private component. It performs |
94 a PKCS1 signature on the passed-in data. | 94 a PKCS1 signature on the passed-in data. |
95 | 95 |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 @rtype: L{tlslite.utils.RSAKey.RSAKey} | 214 @rtype: L{tlslite.utils.RSAKey.RSAKey} |
215 """ | 215 """ |
216 raise NotImplementedError() | 216 raise NotImplementedError() |
217 generate = staticmethod(generate) | 217 generate = staticmethod(generate) |
218 | 218 |
219 | 219 |
220 # ************************************************************************** | 220 # ************************************************************************** |
221 # Helper Functions for RSA Keys | 221 # Helper Functions for RSA Keys |
222 # ************************************************************************** | 222 # ************************************************************************** |
223 | 223 |
224 def _addPKCS1SHA1Prefix(self, bytes, withNULL=True): | 224 @staticmethod |
| 225 def addPKCS1SHA1Prefix(bytes, withNULL=True): |
225 # There is a long history of confusion over whether the SHA1 | 226 # There is a long history of confusion over whether the SHA1 |
226 # algorithmIdentifier should be encoded with a NULL parameter or | 227 # algorithmIdentifier should be encoded with a NULL parameter or |
227 # with the parameter omitted. While the original intention was | 228 # with the parameter omitted. While the original intention was |
228 # apparently to omit it, many toolkits went the other way. TLS 1.2 | 229 # apparently to omit it, many toolkits went the other way. TLS 1.2 |
229 # specifies the NULL should be included, and this behavior is also | 230 # specifies the NULL should be included, and this behavior is also |
230 # mandated in recent versions of PKCS #1, and is what tlslite has | 231 # mandated in recent versions of PKCS #1, and is what tlslite has |
231 # always implemented. Anyways, verification code should probably | 232 # always implemented. Anyways, verification code should probably |
232 # accept both. However, nothing uses this code yet, so this is | 233 # accept both. |
233 # all fairly moot. | |
234 if not withNULL: | 234 if not withNULL: |
235 prefixBytes = bytearray(\ | 235 prefixBytes = bytearray(\ |
236 [0x30,0x1f,0x30,0x07,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x04,0x14])
| 236 [0x30,0x1f,0x30,0x07,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x04,0x14])
|
237 else: | 237 else: |
238 prefixBytes = bytearray(\ | 238 prefixBytes = bytearray(\ |
239 [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x
04,0x14]) | 239 [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x
04,0x14]) |
240 prefixedBytes = prefixBytes + bytes | 240 prefixedBytes = prefixBytes + bytes |
241 return prefixedBytes | 241 return prefixedBytes |
242 | 242 |
243 def _addPKCS1Padding(self, bytes, blockType): | 243 def _addPKCS1Padding(self, bytes, blockType): |
244 padLength = (numBytes(self.n) - (len(bytes)+3)) | 244 padLength = (numBytes(self.n) - (len(bytes)+3)) |
245 if blockType == 1: #Signature padding | 245 if blockType == 1: #Signature padding |
246 pad = [0xFF] * padLength | 246 pad = [0xFF] * padLength |
247 elif blockType == 2: #Encryption padding | 247 elif blockType == 2: #Encryption padding |
248 pad = bytearray(0) | 248 pad = bytearray(0) |
249 while len(pad) < padLength: | 249 while len(pad) < padLength: |
250 padBytes = getRandomBytes(padLength * 2) | 250 padBytes = getRandomBytes(padLength * 2) |
251 pad = [b for b in padBytes if b != 0] | 251 pad = [b for b in padBytes if b != 0] |
252 pad = pad[:padLength] | 252 pad = pad[:padLength] |
253 else: | 253 else: |
254 raise AssertionError() | 254 raise AssertionError() |
255 | 255 |
256 padding = bytearray([0,blockType] + pad + [0]) | 256 padding = bytearray([0,blockType] + pad + [0]) |
257 paddedBytes = padding + bytes | 257 paddedBytes = padding + bytes |
258 return paddedBytes | 258 return paddedBytes |
OLD | NEW |