1
2
3
4 """Abstract class for RSA."""
5
6 from .cryptomath import *
7
8
10 """This is an abstract base class for RSA keys.
11
12 Particular implementations of RSA keys, such as
13 L{openssl_rsakey.OpenSSL_RSAKey},
14 L{python_rsakey.Python_RSAKey}, and
15 L{pycrypto_rsakey.PyCrypto_RSAKey},
16 inherit from this.
17
18 To create or parse an RSA key, don't use one of these classes
19 directly. Instead, use the factory functions in
20 L{tlslite.utils.keyfactory}.
21 """
22
24 """Create a new RSA key.
25
26 If n and e are passed in, the new key will be initialized.
27
28 @type n: int
29 @param n: RSA modulus.
30
31 @type e: int
32 @param e: RSA public exponent.
33 """
34 raise NotImplementedError()
35
37 """Return the length of this key in bits.
38
39 @rtype: int
40 """
41 return numBits(self.n)
42
44 """Return whether or not this key has a private component.
45
46 @rtype: bool
47 """
48 raise NotImplementedError()
49
51 """Hash and sign the passed-in bytes.
52
53 This requires the key to have a private component. It performs
54 a PKCS1-SHA1 signature on the passed-in data.
55
56 @type bytes: str or L{bytearray} of unsigned bytes
57 @param bytes: The value which will be hashed and signed.
58
59 @rtype: L{bytearray} of unsigned bytes.
60 @return: A PKCS1-SHA1 signature on the passed-in data.
61 """
62 hashBytes = SHA1(bytearray(bytes))
63 prefixedHashBytes = self._addPKCS1SHA1Prefix(hashBytes)
64 sigBytes = self.sign(prefixedHashBytes)
65 return sigBytes
66
68 """Hash and verify the passed-in bytes with the signature.
69
70 This verifies a PKCS1-SHA1 signature on the passed-in data.
71
72 @type sigBytes: L{bytearray} of unsigned bytes
73 @param sigBytes: A PKCS1-SHA1 signature.
74
75 @type bytes: str or L{bytearray} of unsigned bytes
76 @param bytes: The value which will be hashed and verified.
77
78 @rtype: bool
79 @return: Whether the signature matches the passed-in data.
80 """
81 hashBytes = SHA1(bytearray(bytes))
82
83
84 prefixedHashBytes1 = self._addPKCS1SHA1Prefix(hashBytes, False)
85 prefixedHashBytes2 = self._addPKCS1SHA1Prefix(hashBytes, True)
86 result1 = self.verify(sigBytes, prefixedHashBytes1)
87 result2 = self.verify(sigBytes, prefixedHashBytes2)
88 return (result1 or result2)
89
90 - def sign(self, bytes):
91 """Sign the passed-in bytes.
92
93 This requires the key to have a private component. It performs
94 a PKCS1 signature on the passed-in data.
95
96 @type bytes: L{bytearray} of unsigned bytes
97 @param bytes: The value which will be signed.
98
99 @rtype: L{bytearray} of unsigned bytes.
100 @return: A PKCS1 signature on the passed-in data.
101 """
102 if not self.hasPrivateKey():
103 raise AssertionError()
104 paddedBytes = self._addPKCS1Padding(bytes, 1)
105 m = bytesToNumber(paddedBytes)
106 if m >= self.n:
107 raise ValueError()
108 c = self._rawPrivateKeyOp(m)
109 sigBytes = numberToByteArray(c, numBytes(self.n))
110 return sigBytes
111
112 - def verify(self, sigBytes, bytes):
113 """Verify the passed-in bytes with the signature.
114
115 This verifies a PKCS1 signature on the passed-in data.
116
117 @type sigBytes: L{bytearray} of unsigned bytes
118 @param sigBytes: A PKCS1 signature.
119
120 @type bytes: L{bytearray} of unsigned bytes
121 @param bytes: The value which will be verified.
122
123 @rtype: bool
124 @return: Whether the signature matches the passed-in data.
125 """
126 if len(sigBytes) != numBytes(self.n):
127 return False
128 paddedBytes = self._addPKCS1Padding(bytes, 1)
129 c = bytesToNumber(sigBytes)
130 if c >= self.n:
131 return False
132 m = self._rawPublicKeyOp(c)
133 checkBytes = numberToByteArray(m, numBytes(self.n))
134 return checkBytes == paddedBytes
135
137 """Encrypt the passed-in bytes.
138
139 This performs PKCS1 encryption of the passed-in data.
140
141 @type bytes: L{bytearray} of unsigned bytes
142 @param bytes: The value which will be encrypted.
143
144 @rtype: L{bytearray} of unsigned bytes.
145 @return: A PKCS1 encryption of the passed-in data.
146 """
147 paddedBytes = self._addPKCS1Padding(bytes, 2)
148 m = bytesToNumber(paddedBytes)
149 if m >= self.n:
150 raise ValueError()
151 c = self._rawPublicKeyOp(m)
152 encBytes = numberToByteArray(c, numBytes(self.n))
153 return encBytes
154
156 """Decrypt the passed-in bytes.
157
158 This requires the key to have a private component. It performs
159 PKCS1 decryption of the passed-in data.
160
161 @type encBytes: L{bytearray} of unsigned bytes
162 @param encBytes: The value which will be decrypted.
163
164 @rtype: L{bytearray} of unsigned bytes or None.
165 @return: A PKCS1 decryption of the passed-in data or None if
166 the data is not properly formatted.
167 """
168 if not self.hasPrivateKey():
169 raise AssertionError()
170 if len(encBytes) != numBytes(self.n):
171 return None
172 c = bytesToNumber(encBytes)
173 if c >= self.n:
174 return None
175 m = self._rawPrivateKeyOp(c)
176 decBytes = numberToByteArray(m, numBytes(self.n))
177 if decBytes[0] != 0 or decBytes[1] != 2:
178 return None
179 for x in range(1, len(decBytes)-1):
180 if decBytes[x]== 0:
181 break
182 else:
183 return None
184 return decBytes[x+1:]
185
187 raise NotImplementedError()
188
190 raise NotImplementedError()
191
193 """Return True if the write() method accepts a password for use
194 in encrypting the private key.
195
196 @rtype: bool
197 """
198 raise NotImplementedError()
199
200 - def write(self, password=None):
201 """Return a string containing the key.
202
203 @rtype: str
204 @return: A string describing the key, in whichever format (PEM)
205 is native to the implementation.
206 """
207 raise NotImplementedError()
208
210 """Generate a new key with the specified bit length.
211
212 @rtype: L{tlslite.utils.RSAKey.RSAKey}
213 """
214 raise NotImplementedError()
215 generate = staticmethod(generate)
216
217
218
219
220
221
223
224
225
226
227
228
229
230
231
232 if not withNULL:
233 prefixBytes = bytearray(\
234 [0x30,0x1f,0x30,0x07,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x04,0x14])
235 else:
236 prefixBytes = bytearray(\
237 [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14])
238 prefixedBytes = prefixBytes + bytes
239 return prefixedBytes
240
242 padLength = (numBytes(self.n) - (len(bytes)+3))
243 if blockType == 1:
244 pad = [0xFF] * padLength
245 elif blockType == 2:
246 pad = bytearray(0)
247 while len(pad) < padLength:
248 padBytes = getRandomBytes(padLength * 2)
249 pad = [b for b in padBytes if b != 0]
250 pad = pad[:padLength]
251 else:
252 raise AssertionError()
253
254 padding = bytearray([0,blockType] + pad + [0])
255 paddedBytes = padding + bytes
256 return paddedBytes
257