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 if not isinstance(bytes, type("")):
63 bytes = bytesToString(bytes)
64 hashBytes = stringToBytes(sha1(bytes).digest())
65 prefixedHashBytes = self._addPKCS1SHA1Prefix(hashBytes)
66 sigBytes = self.sign(prefixedHashBytes)
67 return sigBytes
68
70 """Hash and verify the passed-in bytes with the signature.
71
72 This verifies a PKCS1-SHA1 signature on the passed-in data.
73
74 @type sigBytes: L{bytearray} of unsigned bytes
75 @param sigBytes: A PKCS1-SHA1 signature.
76
77 @type bytes: str or L{bytearray} of unsigned bytes
78 @param bytes: The value which will be hashed and verified.
79
80 @rtype: bool
81 @return: Whether the signature matches the passed-in data.
82 """
83 if not isinstance(bytes, type("")):
84 bytes = bytesToString(bytes)
85 hashBytes = stringToBytes(sha1(bytes).digest())
86 prefixedHashBytes = self._addPKCS1SHA1Prefix(hashBytes)
87 return self.verify(sigBytes, prefixedHashBytes)
88
89 - def sign(self, bytes):
90 """Sign the passed-in bytes.
91
92 This requires the key to have a private component. It performs
93 a PKCS1 signature on the passed-in data.
94
95 @type bytes: L{bytearray} of unsigned bytes
96 @param bytes: The value which will be signed.
97
98 @rtype: L{bytearray} of unsigned bytes.
99 @return: A PKCS1 signature on the passed-in data.
100 """
101 if not self.hasPrivateKey():
102 raise AssertionError()
103 paddedBytes = self._addPKCS1Padding(bytes, 1)
104 m = bytesToNumber(paddedBytes)
105 if m >= self.n:
106 raise ValueError()
107 c = self._rawPrivateKeyOp(m)
108 sigBytes = numberToBytes(c)
109 return sigBytes
110
111 - def verify(self, sigBytes, bytes):
112 """Verify the passed-in bytes with the signature.
113
114 This verifies a PKCS1 signature on the passed-in data.
115
116 @type sigBytes: L{bytearray} of unsigned bytes
117 @param sigBytes: A PKCS1 signature.
118
119 @type bytes: L{bytearray} of unsigned bytes
120 @param bytes: The value which will be verified.
121
122 @rtype: bool
123 @return: Whether the signature matches the passed-in data.
124 """
125 paddedBytes = self._addPKCS1Padding(bytes, 1)
126 c = bytesToNumber(sigBytes)
127 if c >= self.n:
128 return False
129 m = self._rawPublicKeyOp(c)
130 checkBytes = numberToBytes(m)
131 return checkBytes == paddedBytes
132
134 """Encrypt the passed-in bytes.
135
136 This performs PKCS1 encryption of the passed-in data.
137
138 @type bytes: L{bytearray} of unsigned bytes
139 @param bytes: The value which will be encrypted.
140
141 @rtype: L{bytearray} of unsigned bytes.
142 @return: A PKCS1 encryption of the passed-in data.
143 """
144 paddedBytes = self._addPKCS1Padding(bytes, 2)
145 m = bytesToNumber(paddedBytes)
146 if m >= self.n:
147 raise ValueError()
148 c = self._rawPublicKeyOp(m)
149 encBytes = numberToBytes(c)
150 return encBytes
151
153 """Decrypt the passed-in bytes.
154
155 This requires the key to have a private component. It performs
156 PKCS1 decryption of the passed-in data.
157
158 @type encBytes: L{bytearray} of unsigned bytes
159 @param encBytes: The value which will be decrypted.
160
161 @rtype: L{bytearray} of unsigned bytes or None.
162 @return: A PKCS1 decryption of the passed-in data or None if
163 the data is not properly formatted.
164 """
165 if not self.hasPrivateKey():
166 raise AssertionError()
167 c = bytesToNumber(encBytes)
168 if c >= self.n:
169 return None
170 m = self._rawPrivateKeyOp(c)
171 decBytes = numberToBytes(m)
172 if (len(decBytes) != numBytes(self.n)-1):
173 return None
174 if decBytes[0] != 2:
175 return None
176 for x in range(len(decBytes)-1):
177 if decBytes[x]== 0:
178 break
179 else:
180 return None
181 return decBytes[x+1:]
182
184 raise NotImplementedError()
185
187 raise NotImplementedError()
188
190 """Return True if the write() method accepts a password for use
191 in encrypting the private key.
192
193 @rtype: bool
194 """
195 raise NotImplementedError()
196
197 - def write(self, password=None):
198 """Return a string containing the key.
199
200 @rtype: str
201 @return: A string describing the key, in whichever format (PEM)
202 is native to the implementation.
203 """
204 raise NotImplementedError()
205
207 """Generate a new key with the specified bit length.
208
209 @rtype: L{tlslite.utils.RSAKey.RSAKey}
210 """
211 raise NotImplementedError()
212 generate = staticmethod(generate)
213
214
215
216
217
218
220
221
222
223
224
225
226
227
228
229 if not withNULL:
230 prefixBytes = createByteArraySequence(\
231 [0x30,0x1f,0x30,0x07,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x04,0x14])
232 else:
233 prefixBytes = createByteArraySequence(\
234 [0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00,0x04,0x14])
235 prefixedBytes = prefixBytes + bytes
236 return prefixedBytes
237
239 padLength = (numBytes(self.n) - (len(bytes)+3))
240 if blockType == 1:
241 pad = [0xFF] * padLength
242 elif blockType == 2:
243 pad = createByteArraySequence([])
244 while len(pad) < padLength:
245 padBytes = getRandomBytes(padLength * 2)
246 pad = [b for b in padBytes if b != 0]
247 pad = pad[:padLength]
248 else:
249 raise AssertionError()
250
251
252
253
254
255 padding = createByteArraySequence([blockType] + pad + [0])
256 paddedBytes = padding + bytes
257 return paddedBytes
258