| 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 |