| OLD | NEW |
| 1 # Author: Trevor Perrin |
| 2 # See the LICENSE file for legal information regarding use of this file. |
| 3 |
| 1 """Abstract class for RSA.""" | 4 """Abstract class for RSA.""" |
| 2 | 5 |
| 3 from cryptomath import * | 6 from .cryptomath import * |
| 4 | 7 |
| 5 | 8 |
| 6 class RSAKey: | 9 class RSAKey(object): |
| 7 """This is an abstract base class for RSA keys. | 10 """This is an abstract base class for RSA keys. |
| 8 | 11 |
| 9 Particular implementations of RSA keys, such as | 12 Particular implementations of RSA keys, such as |
| 10 L{OpenSSL_RSAKey.OpenSSL_RSAKey}, | 13 L{openssl_rsakey.OpenSSL_RSAKey}, |
| 11 L{Python_RSAKey.Python_RSAKey}, and | 14 L{python_rsakey.Python_RSAKey}, and |
| 12 L{PyCrypto_RSAKey.PyCrypto_RSAKey}, | 15 L{pycrypto_rsakey.PyCrypto_RSAKey}, |
| 13 inherit from this. | 16 inherit from this. |
| 14 | 17 |
| 15 To create or parse an RSA key, don't use one of these classes | 18 To create or parse an RSA key, don't use one of these classes |
| 16 directly. Instead, use the factory functions in | 19 directly. Instead, use the factory functions in |
| 17 L{tlslite.utils.keyfactory}. | 20 L{tlslite.utils.keyfactory}. |
| 18 """ | 21 """ |
| 19 | 22 |
| 20 def __init__(self, n=0, e=0): | 23 def __init__(self, n=0, e=0): |
| 21 """Create a new RSA key. | 24 """Create a new RSA key. |
| 22 | 25 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 37 """ | 40 """ |
| 38 return numBits(self.n) | 41 return numBits(self.n) |
| 39 | 42 |
| 40 def hasPrivateKey(self): | 43 def hasPrivateKey(self): |
| 41 """Return whether or not this key has a private component. | 44 """Return whether or not this key has a private component. |
| 42 | 45 |
| 43 @rtype: bool | 46 @rtype: bool |
| 44 """ | 47 """ |
| 45 raise NotImplementedError() | 48 raise NotImplementedError() |
| 46 | 49 |
| 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): | 50 def hashAndSign(self, bytes): |
| 63 """Hash and sign the passed-in bytes. | 51 """Hash and sign the passed-in bytes. |
| 64 | 52 |
| 65 This requires the key to have a private component. It performs | 53 This requires the key to have a private component. It performs |
| 66 a PKCS1-SHA1 signature on the passed-in data. | 54 a PKCS1-SHA1 signature on the passed-in data. |
| 67 | 55 |
| 68 @type bytes: str or L{array.array} of unsigned bytes | 56 @type bytes: str or L{bytearray} of unsigned bytes |
| 69 @param bytes: The value which will be hashed and signed. | 57 @param bytes: The value which will be hashed and signed. |
| 70 | 58 |
| 71 @rtype: L{array.array} of unsigned bytes. | 59 @rtype: L{bytearray} of unsigned bytes. |
| 72 @return: A PKCS1-SHA1 signature on the passed-in data. | 60 @return: A PKCS1-SHA1 signature on the passed-in data. |
| 73 """ | 61 """ |
| 74 if not isinstance(bytes, type("")): | 62 hashBytes = SHA1(bytearray(bytes)) |
| 75 bytes = bytesToString(bytes) | |
| 76 hashBytes = stringToBytes(sha.sha(bytes).digest()) | |
| 77 prefixedHashBytes = self._addPKCS1SHA1Prefix(hashBytes) | 63 prefixedHashBytes = self._addPKCS1SHA1Prefix(hashBytes) |
| 78 sigBytes = self.sign(prefixedHashBytes) | 64 sigBytes = self.sign(prefixedHashBytes) |
| 79 return sigBytes | 65 return sigBytes |
| 80 | 66 |
| 81 def hashAndVerify(self, sigBytes, bytes): | 67 def hashAndVerify(self, sigBytes, bytes): |
| 82 """Hash and verify the passed-in bytes with the signature. | 68 """Hash and verify the passed-in bytes with the signature. |
| 83 | 69 |
| 84 This verifies a PKCS1-SHA1 signature on the passed-in data. | 70 This verifies a PKCS1-SHA1 signature on the passed-in data. |
| 85 | 71 |
| 86 @type sigBytes: L{array.array} of unsigned bytes | 72 @type sigBytes: L{bytearray} of unsigned bytes |
| 87 @param sigBytes: A PKCS1-SHA1 signature. | 73 @param sigBytes: A PKCS1-SHA1 signature. |
| 88 | 74 |
| 89 @type bytes: str or L{array.array} of unsigned bytes | 75 @type bytes: str or L{bytearray} of unsigned bytes |
| 90 @param bytes: The value which will be hashed and verified. | 76 @param bytes: The value which will be hashed and verified. |
| 91 | 77 |
| 92 @rtype: bool | 78 @rtype: bool |
| 93 @return: Whether the signature matches the passed-in data. | 79 @return: Whether the signature matches the passed-in data. |
| 94 """ | 80 """ |
| 95 if not isinstance(bytes, type("")): | 81 hashBytes = SHA1(bytearray(bytes)) |
| 96 bytes = bytesToString(bytes) | 82 |
| 97 hashBytes = stringToBytes(sha.sha(bytes).digest()) | 83 # Try it with/without the embedded NULL |
| 98 prefixedHashBytes = self._addPKCS1SHA1Prefix(hashBytes) | 84 prefixedHashBytes1 = self._addPKCS1SHA1Prefix(hashBytes, False) |
| 99 return self.verify(sigBytes, prefixedHashBytes) | 85 prefixedHashBytes2 = self._addPKCS1SHA1Prefix(hashBytes, True) |
| 86 result1 = self.verify(sigBytes, prefixedHashBytes1) |
| 87 result2 = self.verify(sigBytes, prefixedHashBytes2) |
| 88 return (result1 or result2) |
| 100 | 89 |
| 101 def sign(self, bytes): | 90 def sign(self, bytes): |
| 102 """Sign the passed-in bytes. | 91 """Sign the passed-in bytes. |
| 103 | 92 |
| 104 This requires the key to have a private component. It performs | 93 This requires the key to have a private component. It performs |
| 105 a PKCS1 signature on the passed-in data. | 94 a PKCS1 signature on the passed-in data. |
| 106 | 95 |
| 107 @type bytes: L{array.array} of unsigned bytes | 96 @type bytes: L{bytearray} of unsigned bytes |
| 108 @param bytes: The value which will be signed. | 97 @param bytes: The value which will be signed. |
| 109 | 98 |
| 110 @rtype: L{array.array} of unsigned bytes. | 99 @rtype: L{bytearray} of unsigned bytes. |
| 111 @return: A PKCS1 signature on the passed-in data. | 100 @return: A PKCS1 signature on the passed-in data. |
| 112 """ | 101 """ |
| 113 if not self.hasPrivateKey(): | 102 if not self.hasPrivateKey(): |
| 114 raise AssertionError() | 103 raise AssertionError() |
| 115 paddedBytes = self._addPKCS1Padding(bytes, 1) | 104 paddedBytes = self._addPKCS1Padding(bytes, 1) |
| 116 m = bytesToNumber(paddedBytes) | 105 m = bytesToNumber(paddedBytes) |
| 117 if m >= self.n: | 106 if m >= self.n: |
| 118 raise ValueError() | 107 raise ValueError() |
| 119 c = self._rawPrivateKeyOp(m) | 108 c = self._rawPrivateKeyOp(m) |
| 120 sigBytes = numberToBytes(c, numBytes(self.n)) | 109 sigBytes = numberToByteArray(c, numBytes(self.n)) |
| 121 return sigBytes | 110 return sigBytes |
| 122 | 111 |
| 123 def verify(self, sigBytes, bytes): | 112 def verify(self, sigBytes, bytes): |
| 124 """Verify the passed-in bytes with the signature. | 113 """Verify the passed-in bytes with the signature. |
| 125 | 114 |
| 126 This verifies a PKCS1 signature on the passed-in data. | 115 This verifies a PKCS1 signature on the passed-in data. |
| 127 | 116 |
| 128 @type sigBytes: L{array.array} of unsigned bytes | 117 @type sigBytes: L{bytearray} of unsigned bytes |
| 129 @param sigBytes: A PKCS1 signature. | 118 @param sigBytes: A PKCS1 signature. |
| 130 | 119 |
| 131 @type bytes: L{array.array} of unsigned bytes | 120 @type bytes: L{bytearray} of unsigned bytes |
| 132 @param bytes: The value which will be verified. | 121 @param bytes: The value which will be verified. |
| 133 | 122 |
| 134 @rtype: bool | 123 @rtype: bool |
| 135 @return: Whether the signature matches the passed-in data. | 124 @return: Whether the signature matches the passed-in data. |
| 136 """ | 125 """ |
| 126 if len(sigBytes) != numBytes(self.n): |
| 127 return False |
| 137 paddedBytes = self._addPKCS1Padding(bytes, 1) | 128 paddedBytes = self._addPKCS1Padding(bytes, 1) |
| 138 c = bytesToNumber(sigBytes) | 129 c = bytesToNumber(sigBytes) |
| 139 if c >= self.n: | 130 if c >= self.n: |
| 140 return False | 131 return False |
| 141 m = self._rawPublicKeyOp(c) | 132 m = self._rawPublicKeyOp(c) |
| 142 checkBytes = numberToBytes(m) | 133 checkBytes = numberToByteArray(m, numBytes(self.n)) |
| 143 return checkBytes == paddedBytes | 134 return checkBytes == paddedBytes |
| 144 | 135 |
| 145 def encrypt(self, bytes): | 136 def encrypt(self, bytes): |
| 146 """Encrypt the passed-in bytes. | 137 """Encrypt the passed-in bytes. |
| 147 | 138 |
| 148 This performs PKCS1 encryption of the passed-in data. | 139 This performs PKCS1 encryption of the passed-in data. |
| 149 | 140 |
| 150 @type bytes: L{array.array} of unsigned bytes | 141 @type bytes: L{bytearray} of unsigned bytes |
| 151 @param bytes: The value which will be encrypted. | 142 @param bytes: The value which will be encrypted. |
| 152 | 143 |
| 153 @rtype: L{array.array} of unsigned bytes. | 144 @rtype: L{bytearray} of unsigned bytes. |
| 154 @return: A PKCS1 encryption of the passed-in data. | 145 @return: A PKCS1 encryption of the passed-in data. |
| 155 """ | 146 """ |
| 156 paddedBytes = self._addPKCS1Padding(bytes, 2) | 147 paddedBytes = self._addPKCS1Padding(bytes, 2) |
| 157 m = bytesToNumber(paddedBytes) | 148 m = bytesToNumber(paddedBytes) |
| 158 if m >= self.n: | 149 if m >= self.n: |
| 159 raise ValueError() | 150 raise ValueError() |
| 160 c = self._rawPublicKeyOp(m) | 151 c = self._rawPublicKeyOp(m) |
| 161 encBytes = numberToBytes(c) | 152 encBytes = numberToByteArray(c, numBytes(self.n)) |
| 162 return encBytes | 153 return encBytes |
| 163 | 154 |
| 164 def decrypt(self, encBytes): | 155 def decrypt(self, encBytes): |
| 165 """Decrypt the passed-in bytes. | 156 """Decrypt the passed-in bytes. |
| 166 | 157 |
| 167 This requires the key to have a private component. It performs | 158 This requires the key to have a private component. It performs |
| 168 PKCS1 decryption of the passed-in data. | 159 PKCS1 decryption of the passed-in data. |
| 169 | 160 |
| 170 @type encBytes: L{array.array} of unsigned bytes | 161 @type encBytes: L{bytearray} of unsigned bytes |
| 171 @param encBytes: The value which will be decrypted. | 162 @param encBytes: The value which will be decrypted. |
| 172 | 163 |
| 173 @rtype: L{array.array} of unsigned bytes or None. | 164 @rtype: L{bytearray} of unsigned bytes or None. |
| 174 @return: A PKCS1 decryption of the passed-in data or None if | 165 @return: A PKCS1 decryption of the passed-in data or None if |
| 175 the data is not properly formatted. | 166 the data is not properly formatted. |
| 176 """ | 167 """ |
| 177 if not self.hasPrivateKey(): | 168 if not self.hasPrivateKey(): |
| 178 raise AssertionError() | 169 raise AssertionError() |
| 170 if len(encBytes) != numBytes(self.n): |
| 171 return None |
| 179 c = bytesToNumber(encBytes) | 172 c = bytesToNumber(encBytes) |
| 180 if c >= self.n: | 173 if c >= self.n: |
| 181 return None | 174 return None |
| 182 m = self._rawPrivateKeyOp(c) | 175 m = self._rawPrivateKeyOp(c) |
| 183 decBytes = numberToBytes(m) | 176 decBytes = numberToByteArray(m, numBytes(self.n)) |
| 184 if (len(decBytes) != numBytes(self.n)-1): #Check first byte | 177 #Check first two bytes |
| 178 if decBytes[0] != 0 or decBytes[1] != 2: |
| 185 return None | 179 return None |
| 186 if decBytes[0] != 2: #Check second byte | 180 #Scan through for zero separator |
| 187 return None | 181 for x in range(1, len(decBytes)-1): |
| 188 for x in range(len(decBytes)-1): #Scan through for zero separator | |
| 189 if decBytes[x]== 0: | 182 if decBytes[x]== 0: |
| 190 break | 183 break |
| 191 else: | 184 else: |
| 192 return None | 185 return None |
| 193 return decBytes[x+1:] #Return everything after the separator | 186 return decBytes[x+1:] #Return everything after the separator |
| 194 | 187 |
| 195 def _rawPrivateKeyOp(self, m): | 188 def _rawPrivateKeyOp(self, m): |
| 196 raise NotImplementedError() | 189 raise NotImplementedError() |
| 197 | 190 |
| 198 def _rawPublicKeyOp(self, c): | 191 def _rawPublicKeyOp(self, c): |
| 199 raise NotImplementedError() | 192 raise NotImplementedError() |
| 200 | 193 |
| 201 def acceptsPassword(self): | 194 def acceptsPassword(self): |
| 202 """Return True if the write() method accepts a password for use | 195 """Return True if the write() method accepts a password for use |
| 203 in encrypting the private key. | 196 in encrypting the private key. |
| 204 | 197 |
| 205 @rtype: bool | 198 @rtype: bool |
| 206 """ | 199 """ |
| 207 raise NotImplementedError() | 200 raise NotImplementedError() |
| 208 | 201 |
| 209 def write(self, password=None): | 202 def write(self, password=None): |
| 210 """Return a string containing the key. | 203 """Return a string containing the key. |
| 211 | 204 |
| 212 @rtype: str | 205 @rtype: str |
| 213 @return: A string describing the key, in whichever format (PEM | 206 @return: A string describing the key, in whichever format (PEM) |
| 214 or XML) is native to the implementation. | 207 is native to the implementation. |
| 215 """ | 208 """ |
| 216 raise NotImplementedError() | 209 raise NotImplementedError() |
| 217 | 210 |
| 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): | 211 def generate(bits): |
| 227 """Generate a new key with the specified bit length. | 212 """Generate a new key with the specified bit length. |
| 228 | 213 |
| 229 @rtype: L{tlslite.utils.RSAKey.RSAKey} | 214 @rtype: L{tlslite.utils.RSAKey.RSAKey} |
| 230 """ | 215 """ |
| 231 raise NotImplementedError() | 216 raise NotImplementedError() |
| 232 generate = staticmethod(generate) | 217 generate = staticmethod(generate) |
| 233 | 218 |
| 234 | 219 |
| 235 # ************************************************************************** | 220 # ************************************************************************** |
| 236 # Helper Functions for RSA Keys | 221 # Helper Functions for RSA Keys |
| 237 # ************************************************************************** | 222 # ************************************************************************** |
| 238 | 223 |
| 239 def _addPKCS1SHA1Prefix(self, bytes): | 224 def _addPKCS1SHA1Prefix(self, bytes, withNULL=True): |
| 240 prefixBytes = createByteArraySequence(\ | 225 # There is a long history of confusion over whether the SHA1 |
| 241 [48,33,48,9,6,5,43,14,3,2,26,5,0,4,20]) | 226 # algorithmIdentifier should be encoded with a NULL parameter or |
| 227 # with the parameter omitted. While the original intention was |
| 228 # 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 # mandated in recent versions of PKCS #1, and is what tlslite has |
| 231 # always implemented. Anyways, verification code should probably |
| 232 # accept both. However, nothing uses this code yet, so this is |
| 233 # all fairly moot. |
| 234 if not withNULL: |
| 235 prefixBytes = bytearray(\ |
| 236 [0x30,0x1f,0x30,0x07,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x04,0x14])
|
| 237 else: |
| 238 prefixBytes = bytearray(\ |
| 239 [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x
04,0x14]) |
| 242 prefixedBytes = prefixBytes + bytes | 240 prefixedBytes = prefixBytes + bytes |
| 243 return prefixedBytes | 241 return prefixedBytes |
| 244 | 242 |
| 245 def _addPKCS1Padding(self, bytes, blockType): | 243 def _addPKCS1Padding(self, bytes, blockType): |
| 246 padLength = (numBytes(self.n) - (len(bytes)+3)) | 244 padLength = (numBytes(self.n) - (len(bytes)+3)) |
| 247 if blockType == 1: #Signature padding | 245 if blockType == 1: #Signature padding |
| 248 pad = [0xFF] * padLength | 246 pad = [0xFF] * padLength |
| 249 elif blockType == 2: #Encryption padding | 247 elif blockType == 2: #Encryption padding |
| 250 pad = createByteArraySequence([]) | 248 pad = bytearray(0) |
| 251 while len(pad) < padLength: | 249 while len(pad) < padLength: |
| 252 padBytes = getRandomBytes(padLength * 2) | 250 padBytes = getRandomBytes(padLength * 2) |
| 253 pad = [b for b in padBytes if b != 0] | 251 pad = [b for b in padBytes if b != 0] |
| 254 pad = pad[:padLength] | 252 pad = pad[:padLength] |
| 255 else: | 253 else: |
| 256 raise AssertionError() | 254 raise AssertionError() |
| 257 | 255 |
| 258 #NOTE: To be proper, we should add [0,blockType]. However, | 256 padding = bytearray([0,blockType] + pad + [0]) |
| 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 | 257 paddedBytes = padding + bytes |
| 264 return paddedBytes | 258 return paddedBytes |
| OLD | NEW |