Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / tlslite / tlslite / utils / rsakey.py
1 # Author: Trevor Perrin
2 # See the LICENSE file for legal information regarding use of this file.
3
4 """Abstract class for RSA."""
5
6 from .cryptomath import *
7
8
9 class RSAKey(object):
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
23     def __init__(self, n=0, e=0):
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
36     def __len__(self):
37         """Return the length of this key in bits.
38
39         @rtype: int
40         """
41         return numBits(self.n)
42
43     def hasPrivateKey(self):
44         """Return whether or not this key has a private component.
45
46         @rtype: bool
47         """
48         raise NotImplementedError()
49
50     def hashAndSign(self, bytes):
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
67     def hashAndVerify(self, sigBytes, bytes):
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         # Try it with/without the embedded NULL
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
136     def encrypt(self, bytes):
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
155     def decrypt(self, encBytes):
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         #Check first two bytes
178         if decBytes[0] != 0 or decBytes[1] != 2:
179             return None
180         #Scan through for zero separator
181         for x in range(1, len(decBytes)-1):
182             if decBytes[x]== 0:
183                 break
184         else:
185             return None
186         return decBytes[x+1:] #Return everything after the separator
187
188     def _rawPrivateKeyOp(self, m):
189         raise NotImplementedError()
190
191     def _rawPublicKeyOp(self, c):
192         raise NotImplementedError()
193
194     def acceptsPassword(self):
195         """Return True if the write() method accepts a password for use
196         in encrypting the private key.
197
198         @rtype: bool
199         """
200         raise NotImplementedError()
201
202     def write(self, password=None):
203         """Return a string containing the key.
204
205         @rtype: str
206         @return: A string describing the key, in whichever format (PEM)
207         is native to the implementation.
208         """
209         raise NotImplementedError()
210
211     def generate(bits):
212         """Generate a new key with the specified bit length.
213
214         @rtype: L{tlslite.utils.RSAKey.RSAKey}
215         """
216         raise NotImplementedError()
217     generate = staticmethod(generate)
218
219
220     # **************************************************************************
221     # Helper Functions for RSA Keys
222     # **************************************************************************
223
224     def _addPKCS1SHA1Prefix(self, bytes, withNULL=True):
225         # There is a long history of confusion over whether the SHA1 
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,0x04,0x14])            
240         prefixedBytes = prefixBytes + bytes
241         return prefixedBytes
242
243     def _addPKCS1Padding(self, bytes, blockType):
244         padLength = (numBytes(self.n) - (len(bytes)+3))
245         if blockType == 1: #Signature padding
246             pad = [0xFF] * padLength
247         elif blockType == 2: #Encryption padding
248             pad = bytearray(0)
249             while len(pad) < padLength:
250                 padBytes = getRandomBytes(padLength * 2)
251                 pad = [b for b in padBytes if b != 0]
252                 pad = pad[:padLength]
253         else:
254             raise AssertionError()
255
256         padding = bytearray([0,blockType] + pad + [0])
257         paddedBytes = padding + bytes
258         return paddedBytes