1 """Abstract class for RSA."""
3 from cryptomath import *
7 """This is an abstract base class for RSA keys.
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},
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}.
20 def __init__(self, n=0, e=0):
21 """Create a new RSA key.
23 If n and e are passed in, the new key will be initialized.
26 @param n: RSA modulus.
29 @param e: RSA public exponent.
31 raise NotImplementedError()
34 """Return the length of this key in bits.
38 return numBits(self.n)
40 def hasPrivateKey(self):
41 """Return whether or not this key has a private component.
45 raise NotImplementedError()
48 """Return the cryptoID <keyHash> value corresponding to this
53 raise NotImplementedError()
55 def getSigningAlgorithm(self):
56 """Return the cryptoID sigAlgo value corresponding to this key.
62 def hashAndSign(self, bytes):
63 """Hash and sign the passed-in bytes.
65 This requires the key to have a private component. It performs
66 a PKCS1-SHA1 signature on the passed-in data.
68 @type bytes: str or L{array.array} of unsigned bytes
69 @param bytes: The value which will be hashed and signed.
71 @rtype: L{array.array} of unsigned bytes.
72 @return: A PKCS1-SHA1 signature on the passed-in data.
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)
81 def hashAndVerify(self, sigBytes, bytes):
82 """Hash and verify the passed-in bytes with the signature.
84 This verifies a PKCS1-SHA1 signature on the passed-in data.
86 @type sigBytes: L{array.array} of unsigned bytes
87 @param sigBytes: A PKCS1-SHA1 signature.
89 @type bytes: str or L{array.array} of unsigned bytes
90 @param bytes: The value which will be hashed and verified.
93 @return: Whether the signature matches the passed-in data.
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)
101 def sign(self, bytes):
102 """Sign the passed-in bytes.
104 This requires the key to have a private component. It performs
105 a PKCS1 signature on the passed-in data.
107 @type bytes: L{array.array} of unsigned bytes
108 @param bytes: The value which will be signed.
110 @rtype: L{array.array} of unsigned bytes.
111 @return: A PKCS1 signature on the passed-in data.
113 if not self.hasPrivateKey():
114 raise AssertionError()
115 paddedBytes = self._addPKCS1Padding(bytes, 1)
116 m = bytesToNumber(paddedBytes)
119 c = self._rawPrivateKeyOp(m)
120 sigBytes = numberToBytes(c)
123 def verify(self, sigBytes, bytes):
124 """Verify the passed-in bytes with the signature.
126 This verifies a PKCS1 signature on the passed-in data.
128 @type sigBytes: L{array.array} of unsigned bytes
129 @param sigBytes: A PKCS1 signature.
131 @type bytes: L{array.array} of unsigned bytes
132 @param bytes: The value which will be verified.
135 @return: Whether the signature matches the passed-in data.
137 paddedBytes = self._addPKCS1Padding(bytes, 1)
138 c = bytesToNumber(sigBytes)
141 m = self._rawPublicKeyOp(c)
142 checkBytes = numberToBytes(m)
143 return checkBytes == paddedBytes
145 def encrypt(self, bytes):
146 """Encrypt the passed-in bytes.
148 This performs PKCS1 encryption of the passed-in data.
150 @type bytes: L{array.array} of unsigned bytes
151 @param bytes: The value which will be encrypted.
153 @rtype: L{array.array} of unsigned bytes.
154 @return: A PKCS1 encryption of the passed-in data.
156 paddedBytes = self._addPKCS1Padding(bytes, 2)
157 m = bytesToNumber(paddedBytes)
160 c = self._rawPublicKeyOp(m)
161 encBytes = numberToBytes(c)
164 def decrypt(self, encBytes):
165 """Decrypt the passed-in bytes.
167 This requires the key to have a private component. It performs
168 PKCS1 decryption of the passed-in data.
170 @type encBytes: L{array.array} of unsigned bytes
171 @param encBytes: The value which will be decrypted.
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.
177 if not self.hasPrivateKey():
178 raise AssertionError()
179 c = bytesToNumber(encBytes)
182 m = self._rawPrivateKeyOp(c)
183 decBytes = numberToBytes(m)
184 if (len(decBytes) != numBytes(self.n)-1): #Check first byte
186 if decBytes[0] != 2: #Check second byte
188 for x in range(len(decBytes)-1): #Scan through for zero separator
193 return decBytes[x+1:] #Return everything after the separator
195 def _rawPrivateKeyOp(self, m):
196 raise NotImplementedError()
198 def _rawPublicKeyOp(self, c):
199 raise NotImplementedError()
201 def acceptsPassword(self):
202 """Return True if the write() method accepts a password for use
203 in encrypting the private key.
207 raise NotImplementedError()
209 def write(self, password=None):
210 """Return a string containing the key.
213 @return: A string describing the key, in whichever format (PEM
214 or XML) is native to the implementation.
216 raise NotImplementedError()
218 def writeXMLPublicKey(self, indent=''):
219 """Return a string containing the key.
222 @return: A string describing the public key, in XML format.
224 return Python_RSAKey(self.n, self.e).write(indent)
227 """Generate a new key with the specified bit length.
229 @rtype: L{tlslite.utils.RSAKey.RSAKey}
231 raise NotImplementedError()
232 generate = staticmethod(generate)
235 # **************************************************************************
236 # Helper Functions for RSA Keys
237 # **************************************************************************
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
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]
256 raise AssertionError()
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