| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | # -*- coding: utf-8 -*- | 
					
						
							|  |  |  | # | 
					
						
							|  |  |  | #  PublicKey/RSA.py : RSA public key primitive | 
					
						
							|  |  |  | # | 
					
						
							| 
									
										
										
										
											2009-02-28 13:24:04 -05:00
										 |  |  | # Written in 2008 by Dwayne C. Litzenberger <dlitz@dlitz.net> | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2009-02-28 13:24:04 -05:00
										 |  |  | # =================================================================== | 
					
						
							|  |  |  | # The contents of this file are dedicated to the public domain.  To | 
					
						
							|  |  |  | # the extent that dedication to the public domain is not available, | 
					
						
							|  |  |  | # everyone is granted a worldwide, perpetual, royalty-free, | 
					
						
							|  |  |  | # non-exclusive license to exercise all rights associated with the | 
					
						
							|  |  |  | # contents of this file for any purpose whatsoever. | 
					
						
							|  |  |  | # No rights are reserved. | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | # | 
					
						
							| 
									
										
										
										
											2009-02-28 13:24:04 -05:00
										 |  |  | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 
					
						
							|  |  |  | # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 
					
						
							|  |  |  | # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 
					
						
							|  |  |  | # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | 
					
						
							|  |  |  | # BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | 
					
						
							|  |  |  | # ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | 
					
						
							|  |  |  | # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 
					
						
							|  |  |  | # SOFTWARE. | 
					
						
							|  |  |  | # =================================================================== | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-12 23:16:52 +02:00
										 |  |  | """RSA public-key cryptography algorithm (signature and encryption).
 | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-10 21:26:33 +02:00
										 |  |  | RSA_ is the most widespread and used public key algorithm. Its security is | 
					
						
							|  |  |  | based on the difficulty of factoring large integers. The algorithm has | 
					
						
							|  |  |  | withstood attacks for 30 years, and it is therefore considered reasonably | 
					
						
							|  |  |  | secure for new designs. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The algorithm can be used for both confidentiality (encryption) and | 
					
						
							|  |  |  | authentication (digital signature). It is worth noting that signing and | 
					
						
							|  |  |  | decryption are significantly slower than verification and encryption. | 
					
						
							| 
									
										
										
										
											2012-04-18 20:45:38 +02:00
										 |  |  | The cryptograhic strength is primarily linked to the length of the modulus *n*. | 
					
						
							| 
									
										
										
										
											2012-04-10 21:26:33 +02:00
										 |  |  | In 2012, a sufficient length is deemed to be 2048 bits. For more information, | 
					
						
							|  |  |  | see the most recent ECRYPT_ report. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-18 20:45:38 +02:00
										 |  |  | Both RSA ciphertext and RSA signature are as big as the modulus *n* (256 | 
					
						
							|  |  |  | bytes if *n* is 2048 bit long). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-10 21:26:33 +02:00
										 |  |  | This module provides facilities for generating fresh, new RSA keys, constructing | 
					
						
							|  |  |  | them from known components, exporting them, and importing them. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     >>> from Crypto.PublicKey import RSA | 
					
						
							|  |  |  |     >>> | 
					
						
							|  |  |  |     >>> key = RSA.generate(2048) | 
					
						
							|  |  |  |     >>> f = open('mykey.pem','w') | 
					
						
							| 
									
										
										
										
											2013-06-16 11:47:16 +02:00
										 |  |  |     >>> f.write(key.exportKey('PEM')) | 
					
						
							| 
									
										
										
										
											2012-04-10 21:26:33 +02:00
										 |  |  |     >>> f.close() | 
					
						
							|  |  |  |     ... | 
					
						
							|  |  |  |     >>> f = open('mykey.pem','r') | 
					
						
							|  |  |  |     >>> key = RSA.importKey(f.read()) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Even though you may choose to  directly use the methods of an RSA key object | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  | to perform the primitive cryptographic operations (e.g. `_RSAobj._encrypt`), | 
					
						
							| 
									
										
										
										
											2012-04-10 21:26:33 +02:00
										 |  |  | it is recommended to use one of the standardized schemes instead (like | 
					
						
							|  |  |  | `Crypto.Cipher.PKCS1_v1_5` or `Crypto.Signature.PKCS1_v1_5`). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .. _RSA: http://en.wikipedia.org/wiki/RSA_%28algorithm%29 | 
					
						
							|  |  |  | .. _ECRYPT: http://www.ecrypt.eu.org/documents/D.SPA.17.pdf | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  | :sort: generate,construct,importKey | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  | """
 | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  | __all__ = ['generate', 'construct', 'importKey', 'RSAImplementation', | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |     '_RSAobj', 'oid' , 'algorithmIdentifier' ] | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-12-28 16:26:52 -05:00
										 |  |  | from Crypto.Util.py3compat import * | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-21 20:14:10 +01:00
										 |  |  | import binascii | 
					
						
							| 
									
										
										
										
											2011-09-21 00:01:36 +02:00
										 |  |  | import struct | 
					
						
							| 
									
										
										
										
											2009-12-27 17:26:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-11 15:46:22 +02:00
										 |  |  | from Crypto import Random | 
					
						
							|  |  |  | from Crypto.IO import PKCS8, PEM | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | from Crypto.Util.asn1 import ( | 
					
						
							|  |  |  |                 DerNull, | 
					
						
							|  |  |  |                 DerSequence, | 
					
						
							|  |  |  |                 DerBitString, | 
					
						
							|  |  |  |                 DerObjectId, | 
					
						
							|  |  |  |                 newDerSequence, | 
					
						
							|  |  |  |                 newDerBitString | 
					
						
							|  |  |  |                 ) | 
					
						
							| 
									
										
										
										
											2011-01-16 21:44:10 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  | from Crypto.Math.Numbers import Integer | 
					
						
							|  |  |  | from Crypto.Math.Primality import (test_probable_prime, | 
					
						
							|  |  |  |                                 generate_probable_prime, COMPOSITE) | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  | def _decode_der(obj_class, binstr): | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |     """Instantiate a DER object class, decode a DER binary string in it, and
 | 
					
						
							|  |  |  |     return the object."""
 | 
					
						
							|  |  |  |     der = obj_class() | 
					
						
							|  |  |  |     der.decode(binstr) | 
					
						
							|  |  |  |     return der | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  | class _RSAobj(object): | 
					
						
							| 
									
										
										
										
											2012-04-10 21:26:33 +02:00
										 |  |  |     """Class defining an actual RSA key.
 | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-10 21:26:33 +02:00
										 |  |  |     :undocumented: __getstate__, __setstate__, __repr__, __getattr__ | 
					
						
							|  |  |  |     """
 | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  |     #: Dictionary of RSA parameters. | 
					
						
							|  |  |  |     #: | 
					
						
							|  |  |  |     #: A public key will only have the following entries: | 
					
						
							|  |  |  |     #: | 
					
						
							|  |  |  |     #:  - **n**, the modulus. | 
					
						
							|  |  |  |     #:  - **e**, the public exponent. | 
					
						
							|  |  |  |     #: | 
					
						
							|  |  |  |     #: A private key will also have: | 
					
						
							|  |  |  |     #: | 
					
						
							|  |  |  |     #:  - **d**, the private exponent. | 
					
						
							|  |  |  |     #:  - **p**, the first factor of n. | 
					
						
							|  |  |  |     #:  - **q**, the second factor of n. | 
					
						
							|  |  |  |     #:  - **u**, the CRT coefficient (1/p) mod q. | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  |     _keydata = ['n', 'e', 'd', 'p', 'q', 'u'] | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |     def __init__(self, key_dict, randfunc): | 
					
						
							|  |  |  |         input_set = set(key_dict.keys()) | 
					
						
							|  |  |  |         public_set = set(('n' , 'e')) | 
					
						
							|  |  |  |         private_set = public_set | set(('p' , 'q', 'd', 'u')) | 
					
						
							|  |  |  |         if input_set not in (private_set, public_set): | 
					
						
							|  |  |  |             raise ValueError("Some RSA components are missing") | 
					
						
							|  |  |  |         self._key = dict(key_dict) | 
					
						
							| 
									
										
										
										
											2011-02-21 21:11:21 -05:00
										 |  |  |         self._randfunc = randfunc | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __getattr__(self, attrname): | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         try: | 
					
						
							|  |  |  |             return int(self._key[attrname]) | 
					
						
							|  |  |  |         except KeyError: | 
					
						
							|  |  |  |             raise AttributeError(attrname) | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  |     def _encrypt(self, plaintext): | 
					
						
							|  |  |  |         if not 0 < plaintext < self.n: | 
					
						
							| 
									
										
										
										
											2014-05-07 12:20:46 +02:00
										 |  |  |             raise ValueError("Plaintext too large") | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         e, n = self._key['e'], self._key['n'] | 
					
						
							|  |  |  |         return int(pow(Integer(plaintext), e, n)) | 
					
						
							| 
									
										
										
										
											2011-02-21 21:11:21 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  |     def _decrypt(self, ciphertext): | 
					
						
							| 
									
										
										
										
											2014-05-07 12:20:46 +02:00
										 |  |  |         if not 0 < ciphertext < self.n: | 
					
						
							|  |  |  |             raise ValueError("Ciphertext too large") | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         if not self.has_private(): | 
					
						
							|  |  |  |             raise TypeError("This is not a private key") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         e, d, n, p, q, u = [self._key[comp] for comp in 'e', 'd', 'n', 'p', 'q', 'u'] | 
					
						
							| 
									
										
										
										
											2014-05-07 12:20:46 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-21 21:11:21 -05:00
										 |  |  |         # Blinded RSA decryption (to prevent timing attacks): | 
					
						
							|  |  |  |         # Step 1: Generate random secret blinding factor r, such that 0 < r < n-1 | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         r = Integer.random_range(min_inclusive=1, max_exclusive=n, randfunc=self._randfunc) | 
					
						
							| 
									
										
										
										
											2011-02-21 21:11:21 -05:00
										 |  |  |         # Step 2: Compute c' = c * r**e mod n | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         cp = Integer(ciphertext) * pow(r, e, n) % n | 
					
						
							| 
									
										
										
										
											2011-02-21 21:11:21 -05:00
										 |  |  |         # Step 3: Compute m' = c'**d mod n       (ordinary RSA decryption) | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         m1 = pow(cp, d % (p - 1), p) | 
					
						
							|  |  |  |         m2 = pow(cp, d % (q - 1), q) | 
					
						
							|  |  |  |         h = m2 - m1 | 
					
						
							|  |  |  |         while h < 0: | 
					
						
							|  |  |  |             h += q | 
					
						
							|  |  |  |         h = (h * u) % q | 
					
						
							|  |  |  |         mp = h * p + m1 | 
					
						
							| 
									
										
										
										
											2011-02-21 21:11:21 -05:00
										 |  |  |         # Step 4: Compute m = m**(r-1) mod n | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         return (r.inverse(n) * mp) % n | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def has_private(self): | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         return 'd' in self._key | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def size(self): | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         return self._key['p'].size_in_bits() - 1 | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  |     def publickey(self): | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         return _RSAobj(dict([(k, self._key[k]) for k in 'n', 'e']), self._randfunc) | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  |     def __eq__(self, other): | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         return self._key == other._key | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  |     def __ne__(self, other): | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         return self._key != other._key | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __getstate__(self): | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  |         # RSA key is not pickable | 
					
						
							|  |  |  |         from pickle import PicklingError | 
					
						
							|  |  |  |         raise PicklingError | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def __repr__(self): | 
					
						
							|  |  |  |         attrs = [] | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  |         for k in self._keydata: | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  |             if k == 'n': | 
					
						
							|  |  |  |                 attrs.append("n(%d)" % (self.size()+1,)) | 
					
						
							|  |  |  |             elif hasattr(self.key, k): | 
					
						
							|  |  |  |                 attrs.append(k) | 
					
						
							|  |  |  |         if self.has_private(): | 
					
						
							|  |  |  |             attrs.append("private") | 
					
						
							| 
									
										
										
										
											2010-12-28 16:26:52 -05:00
										 |  |  |         # PY3K: This is meant to be text, do not change to bytes (data) | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  |         return "<%s @0x%x %s>" % (self.__class__.__name__, id(self), ",".join(attrs)) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |     def exportKey(self, format='PEM', passphrase=None, pkcs=1, protection=None): | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  |         """Export this RSA key.
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |         :Parameters: | 
					
						
							|  |  |  |           format : string | 
					
						
							|  |  |  |             The format to use for wrapping the key: | 
					
						
							| 
									
										
										
										
											2011-01-16 22:05:54 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |             - *'DER'*. Binary encoding. | 
					
						
							| 
									
										
										
										
											2012-04-12 23:16:52 +02:00
										 |  |  |             - *'PEM'*. Textual encoding, done according to `RFC1421`_/`RFC1423`_. | 
					
						
							| 
									
										
										
										
											2011-10-10 08:11:31 +02:00
										 |  |  |             - *'OpenSSH'*. Textual encoding, done according to OpenSSH specification. | 
					
						
							|  |  |  |               Only suitable for public keys (not private keys). | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |           passphrase : string | 
					
						
							|  |  |  |             For private keys only. The pass phrase used for deriving the encryption | 
					
						
							|  |  |  |             key. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           pkcs : integer | 
					
						
							|  |  |  |             For *DER* and *PEM* format only. | 
					
						
							|  |  |  |             The PKCS standard to follow for assembling the components of the key. | 
					
						
							|  |  |  |             You have two choices: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             - **1** (default): the public key is embedded into | 
					
						
							|  |  |  |               an X.509 ``SubjectPublicKeyInfo`` DER SEQUENCE. | 
					
						
							|  |  |  |               The private key is embedded into a `PKCS#1`_ | 
					
						
							|  |  |  |               ``RSAPrivateKey`` DER SEQUENCE. | 
					
						
							|  |  |  |             - **8**: the private key is embedded into a `PKCS#8`_ | 
					
						
							|  |  |  |               ``PrivateKeyInfo`` DER SEQUENCE. This value cannot be used | 
					
						
							|  |  |  |               for public keys. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           protection : string | 
					
						
							|  |  |  |             The encryption scheme to use for protecting the private key. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             If ``None`` (default), the behavior depends on ``format``: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             - For *DER*, the *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC* | 
					
						
							|  |  |  |               scheme is used. The following operations are performed: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 1. A 16 byte Triple DES key is derived from the passphrase | 
					
						
							|  |  |  |                    using `Crypto.Protocol.KDF.PBKDF2` with 8 bytes salt, | 
					
						
							|  |  |  |                    and 1 000 iterations of `Crypto.Hash.HMAC`. | 
					
						
							|  |  |  |                 2. The private key is encrypted using CBC. | 
					
						
							|  |  |  |                 3. The encrypted key is encoded according to PKCS#8. | 
					
						
							| 
									
										
										
										
											2011-10-03 23:33:11 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |             - For *PEM*, the obsolete PEM encryption scheme is used. | 
					
						
							|  |  |  |               It is based on MD5 for key derivation, and Triple DES for encryption. | 
					
						
							| 
									
										
										
										
											2012-05-18 15:26:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |             Specifying a value for ``protection`` is only meaningful for PKCS#8 | 
					
						
							|  |  |  |             (that is, ``pkcs=8``) and only if a pass phrase is present too. | 
					
						
							| 
									
										
										
										
											2012-05-18 15:26:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |             The supported schemes for PKCS#8 are listed in the | 
					
						
							|  |  |  |             `Crypto.IO.PKCS8` module (see ``wrap_algo`` parameter). | 
					
						
							| 
									
										
										
										
											2011-10-10 08:11:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |         :Return: A byte string with the encoded public or private half | 
					
						
							|  |  |  |           of the key. | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  |         :Raise ValueError: | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |             When the format is unknown or when you try to encrypt a private | 
					
						
							|  |  |  |             key with *DER* format and PKCS#1. | 
					
						
							|  |  |  |         :attention: | 
					
						
							|  |  |  |             If you don't provide a pass phrase, the private key will be | 
					
						
							|  |  |  |             exported in the clear! | 
					
						
							| 
									
										
										
										
											2012-04-12 23:16:52 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-18 15:26:58 +02:00
										 |  |  |         .. _RFC1421:    http://www.ietf.org/rfc/rfc1421.txt | 
					
						
							|  |  |  |         .. _RFC1423:    http://www.ietf.org/rfc/rfc1423.txt | 
					
						
							|  |  |  |         .. _`PKCS#1`:   http://www.ietf.org/rfc/rfc3447.txt | 
					
						
							|  |  |  |         .. _`PKCS#8`:   http://www.ietf.org/rfc/rfc5208.txt | 
					
						
							| 
									
										
										
										
											2011-01-16 22:05:54 +01:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2011-10-18 23:20:26 +02:00
										 |  |  |         if passphrase is not None: | 
					
						
							|  |  |  |             passphrase = tobytes(passphrase) | 
					
						
							| 
									
										
										
										
											2011-09-21 20:54:17 +02:00
										 |  |  |         if format=='OpenSSH': | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |                eb, nb = [self._key[comp].to_bytes() for comp in 'e', 'n'] | 
					
						
							| 
									
										
										
										
											2011-10-18 23:20:26 +02:00
										 |  |  |                if bord(eb[0]) & 0x80: eb=bchr(0x00)+eb | 
					
						
							|  |  |  |                if bord(nb[0]) & 0x80: nb=bchr(0x00)+nb | 
					
						
							| 
									
										
										
										
											2012-05-28 13:19:22 +02:00
										 |  |  |                keyparts = [ b('ssh-rsa'), eb, nb ] | 
					
						
							|  |  |  |                keystring = b('').join([ struct.pack(">I",len(kp))+kp for kp in keyparts]) | 
					
						
							|  |  |  |                return b('ssh-rsa ')+binascii.b2a_base64(keystring)[:-1] | 
					
						
							| 
									
										
										
										
											2011-09-21 20:54:17 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-10 08:11:31 +02:00
										 |  |  |         # DER format is always used, even in case of PEM, which simply | 
					
						
							|  |  |  |         # encodes it into BASE64. | 
					
						
							| 
									
										
										
										
											2011-01-16 22:05:54 +01:00
										 |  |  |         if self.has_private(): | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |                 binary_key = newDerSequence( | 
					
						
							|  |  |  |                         0, | 
					
						
							|  |  |  |                         self.n, | 
					
						
							|  |  |  |                         self.e, | 
					
						
							|  |  |  |                         self.d, | 
					
						
							|  |  |  |                         self.p, | 
					
						
							|  |  |  |                         self.q, | 
					
						
							|  |  |  |                         self.d % (self.p-1), | 
					
						
							|  |  |  |                         self.d % (self.q-1), | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |                         Integer(self.q).inverse(self.p) | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |                     ).encode() | 
					
						
							|  |  |  |                 if pkcs==1: | 
					
						
							|  |  |  |                     keyType = 'RSA PRIVATE' | 
					
						
							|  |  |  |                     if format=='DER' and passphrase: | 
					
						
							|  |  |  |                         raise ValueError("PKCS#1 private key cannot be encrypted") | 
					
						
							|  |  |  |                 else: # PKCS#8 | 
					
						
							|  |  |  |                     if format=='PEM' and protection is None: | 
					
						
							|  |  |  |                         keyType = 'PRIVATE' | 
					
						
							|  |  |  |                         binary_key = PKCS8.wrap(binary_key, oid, None) | 
					
						
							|  |  |  |                     else: | 
					
						
							|  |  |  |                         keyType = 'ENCRYPTED PRIVATE' | 
					
						
							|  |  |  |                         if not protection: | 
					
						
							|  |  |  |                             protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC' | 
					
						
							|  |  |  |                         binary_key = PKCS8.wrap(binary_key, oid, passphrase, protection) | 
					
						
							|  |  |  |                         passphrase = None | 
					
						
							| 
									
										
										
										
											2011-01-16 22:05:54 +01:00
										 |  |  |         else: | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |                 keyType = "RSA PUBLIC" | 
					
						
							|  |  |  |                 binary_key = newDerSequence( | 
					
						
							|  |  |  |                     algorithmIdentifier, | 
					
						
							|  |  |  |                     newDerBitString( | 
					
						
							|  |  |  |                         newDerSequence( self.n, self.e ) | 
					
						
							|  |  |  |                         ) | 
					
						
							|  |  |  |                     ).encode() | 
					
						
							| 
									
										
										
										
											2011-01-16 22:05:54 +01:00
										 |  |  |         if format=='DER': | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |             return binary_key | 
					
						
							| 
									
										
										
										
											2011-01-16 22:05:54 +01:00
										 |  |  |         if format=='PEM': | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |             pem_str = PEM.encode(binary_key, keyType+" KEY", passphrase, self._randfunc) | 
					
						
							|  |  |  |             return tobytes(pem_str) | 
					
						
							| 
									
										
										
										
											2012-05-28 13:27:42 +02:00
										 |  |  |         raise ValueError("Unknown key format '%s'. Cannot export the RSA key." % format) | 
					
						
							| 
									
										
										
										
											2009-12-27 17:26:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | class RSAImplementation(object): | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  |     """
 | 
					
						
							|  |  |  |     An RSA key factory. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-12 00:49:32 +02:00
										 |  |  |     This class is only internally used to implement the methods of the `Crypto.PublicKey.RSA` module. | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     :sort: __init__,generate,construct,importKey | 
					
						
							|  |  |  |     :undocumented: _g*, _i* | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  |     def __init__(self, **kwargs): | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  |         """Create a new RSA key factory.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         :Keywords: | 
					
						
							|  |  |  |          default_randfunc : callable | 
					
						
							|  |  |  |                                 Specify how to collect random data: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                                 - *None* (default). Use Random.new().read(). | 
					
						
							| 
									
										
										
										
											2012-04-12 00:49:32 +02:00
										 |  |  |                                 - not *None* . Use the specified function directly. | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         self._default_randfunc = kwargs.get('default_randfunc', Random.new().read) | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-17 21:17:19 +01:00
										 |  |  |     def generate(self, bits, randfunc=None, progress_func=None, e=65537): | 
					
						
							| 
									
										
										
										
											2012-04-10 21:26:33 +02:00
										 |  |  |         """Randomly generate a fresh, new RSA key.
 | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         :Parameters: | 
					
						
							|  |  |  |          bits : int | 
					
						
							|  |  |  |                             Key length, or size (in bits) of the RSA modulus. | 
					
						
							|  |  |  |                             It must be a multiple of 256, and no smaller than 1024. | 
					
						
							| 
									
										
										
										
											2012-04-12 00:49:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  |          randfunc : callable | 
					
						
							|  |  |  |                             Random number generation function; it should accept | 
					
						
							|  |  |  |                             a single integer N and return a string of random data | 
					
						
							|  |  |  |                             N bytes long. | 
					
						
							| 
									
										
										
										
											2012-04-12 00:49:32 +02:00
										 |  |  |                             If not specified, a new one will be instantiated | 
					
						
							|  |  |  |                             from ``Crypto.Random``. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  |          progress_func : callable | 
					
						
							|  |  |  |                             Optional function that will be called with a short string | 
					
						
							|  |  |  |                             containing the key parameter currently being generated; | 
					
						
							|  |  |  |                             it's useful for interactive applications where a user is | 
					
						
							|  |  |  |                             waiting for a key to be generated. | 
					
						
							| 
									
										
										
										
											2012-04-12 00:49:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  |          e : int | 
					
						
							|  |  |  |                             Public RSA exponent. It must be an odd positive integer. | 
					
						
							|  |  |  |                             It is typically a small number with very few ones in its | 
					
						
							|  |  |  |                             binary representation. | 
					
						
							|  |  |  |                             The default value 65537 (= ``0b10000000000000001`` ) is a safe | 
					
						
							|  |  |  |                             choice: other common values are 5, 7, 17, and 257. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         :attention: You should always use a cryptographically secure random number generator, | 
					
						
							|  |  |  |             such as the one defined in the ``Crypto.Random`` module; **don't** just use the | 
					
						
							|  |  |  |             current time and the ``random`` module. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         :attention: Exponent 3 is also widely used, but it requires very special care when padding | 
					
						
							|  |  |  |             the message. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-10 21:26:33 +02:00
										 |  |  |         :Return: An RSA key object (`_RSAobj`). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  |         :Raise ValueError: | 
					
						
							|  |  |  |             When **bits** is too little or not a multiple of 256, or when | 
					
						
							|  |  |  |             **e** is not odd or smaller than 2. | 
					
						
							|  |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2010-08-27 00:13:44 -04:00
										 |  |  |         if bits < 1024 or (bits & 0xff) != 0: | 
					
						
							| 
									
										
										
										
											2011-01-16 21:44:10 +01:00
										 |  |  |             raise ValueError("RSA modulus length must be a multiple of 256 and >= 1024") | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  |         if e%2==0 or e<3: | 
					
						
							|  |  |  |             raise ValueError("RSA public exponent must be a positive, odd integer larger than 2.") | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         if randfunc is None: | 
					
						
							|  |  |  |             randfunc = self._default_randfunc | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         e = Integer(e) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Generate the prime factors of n | 
					
						
							|  |  |  |         if progress_func: | 
					
						
							|  |  |  |             progress_func('p,q\n') | 
					
						
							|  |  |  |         p = q = n = Integer(1) | 
					
						
							|  |  |  |         size_p = bits >> 1 | 
					
						
							|  |  |  |         size_q = bits - size_p | 
					
						
							|  |  |  |         while n.size_in_bits() != bits: | 
					
						
							|  |  |  |             # Note that q might be one bit longer than p if somebody specifies an odd | 
					
						
							|  |  |  |             # number of bits for the key. (Why would anyone do that?  You don't get | 
					
						
							|  |  |  |             # more security.) | 
					
						
							|  |  |  |             p = generate_probable_prime(exact_bits=size_p, | 
					
						
							|  |  |  |                                         randfunc=randfunc, | 
					
						
							|  |  |  |                                         totient_coprime_to=e) | 
					
						
							|  |  |  |             q = generate_probable_prime(exact_bits=size_q, | 
					
						
							|  |  |  |                                         randfunc=randfunc, | 
					
						
							|  |  |  |                                         totient_coprime_to=e) | 
					
						
							|  |  |  |             n = p * q | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # It's OK for p to be larger than q, but let's be | 
					
						
							|  |  |  |         # kind to the function that will invert it for | 
					
						
							|  |  |  |         # th calculation of u. | 
					
						
							|  |  |  |         if p > q: | 
					
						
							|  |  |  |             p, q = q, p | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if progress_func: | 
					
						
							|  |  |  |             progress_func('u\n') | 
					
						
							|  |  |  |         u = p.inverse(q) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if progress_func: | 
					
						
							|  |  |  |             progress_func('d\n') | 
					
						
							|  |  |  |         d = e.inverse((p - 1) * (q - 1)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         key_dict = dict(zip(('n', 'e', 'd', 'p', 'q', 'u'), | 
					
						
							|  |  |  |                             (n, e, d, p, q, u))) | 
					
						
							|  |  |  |         return _RSAobj(key_dict, randfunc) | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-11 15:46:22 +02:00
										 |  |  |     def construct(self, tup, consistency_check=True): | 
					
						
							| 
									
										
										
										
											2012-04-10 21:26:33 +02:00
										 |  |  |         """Construct an RSA key from a tuple of valid RSA components.
 | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |         The modulus **n** must be the product of two primes. | 
					
						
							|  |  |  |         The public exponent **e** must be odd and larger than 1. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         In case of a private key, the following equations must apply: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         - e != 1 | 
					
						
							|  |  |  |         - p*q = n | 
					
						
							|  |  |  |         - e*d = 1 mod (p-1)(q-1) | 
					
						
							|  |  |  |         - p*u = 1 mod q | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         :Parameters: | 
					
						
							|  |  |  |          tup : tuple | 
					
						
							| 
									
										
										
										
											2014-06-11 15:46:22 +02:00
										 |  |  |             A tuple of long integers, with at least 2 and no | 
					
						
							|  |  |  |             more than 6 items. The items come in the following order: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 1. RSA modulus (n). | 
					
						
							|  |  |  |                 2. Public exponent (e). | 
					
						
							|  |  |  |                 3. Private exponent (d). Only required if the key is private. | 
					
						
							|  |  |  |                 4. First factor of n (p). Optional, but factor q must also | 
					
						
							|  |  |  |                     be present. | 
					
						
							|  |  |  |                 5. Second factor of n (q). Optional. | 
					
						
							|  |  |  |                 6. CRT coefficient, (1/p) mod q (u). Optional. | 
					
						
							|  |  |  |          consistency_check : boolean | 
					
						
							|  |  |  |             If *True*, the library will verify that the provided components | 
					
						
							|  |  |  |             fulfil the main RSA properties. | 
					
						
							| 
									
										
										
										
											2013-06-17 23:25:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         :Raise ValueError: | 
					
						
							|  |  |  |             When the key being imported fails the most basic RSA validity checks. | 
					
						
							| 
									
										
										
										
											2012-04-10 21:26:33 +02:00
										 |  |  |         :Return: An RSA key object (`_RSAobj`). | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2013-06-17 23:25:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         comp_names = 'n', 'e', 'd', 'p', 'q', 'u' | 
					
						
							|  |  |  |         key_dict = dict(zip(comp_names, map(Integer, tup))) | 
					
						
							|  |  |  |         n, e, d, p, q, u = [key_dict.get(comp) for comp in comp_names] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if d is not None: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if None in (p, q): | 
					
						
							|  |  |  |                 # Compute factors p and q from the private exponent d. | 
					
						
							|  |  |  |                 # We assume that n has no more than two factors. | 
					
						
							|  |  |  |                 # See 8.2.2(i) in Handbook of Applied Cryptography. | 
					
						
							|  |  |  |                 ktot = d * e - 1 | 
					
						
							|  |  |  |                 # The quantity d*e-1 is a multiple of phi(n), even, | 
					
						
							|  |  |  |                 # and can be represented as t*2^s. | 
					
						
							|  |  |  |                 t = ktot | 
					
						
							|  |  |  |                 while t % 2 ==0: | 
					
						
							|  |  |  |                     t //= 2 | 
					
						
							|  |  |  |                 # Cycle through all multiplicative inverses in Zn. | 
					
						
							|  |  |  |                 # The algorithm is non-deterministic, but there is a 50% chance | 
					
						
							|  |  |  |                 # any candidate a leads to successful factoring. | 
					
						
							|  |  |  |                 # See "Digitalized Signatures and Public Key Functions as Intractable | 
					
						
							|  |  |  |                 # as Factorization", M. Rabin, 1979 | 
					
						
							| 
									
										
										
										
											2014-12-05 21:33:56 +01:00
										 |  |  |                 spotted = False | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |                 a = Integer(2) | 
					
						
							| 
									
										
										
										
											2014-12-05 21:33:56 +01:00
										 |  |  |                 while not spotted and a < 100: | 
					
						
							|  |  |  |                     k = Integer(t) | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |                     # Cycle through all values a^{t*2^i}=a^k | 
					
						
							|  |  |  |                     while k < ktot: | 
					
						
							|  |  |  |                         cand = pow(a, k, n) | 
					
						
							|  |  |  |                         # Check if a^k is a non-trivial root of unity (mod n) | 
					
						
							|  |  |  |                         if cand != 1 and cand != (n - 1) and pow(cand, 2, n) == 1: | 
					
						
							|  |  |  |                             # We have found a number such that (cand-1)(cand+1)=0 (mod n). | 
					
						
							|  |  |  |                             # Either of the terms divides n. | 
					
						
							|  |  |  |                             p = Integer(n).gcd(cand + 1) | 
					
						
							| 
									
										
										
										
											2014-12-05 21:33:56 +01:00
										 |  |  |                             spotted = True | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |                             break | 
					
						
							|  |  |  |                         k *= 2 | 
					
						
							|  |  |  |                     # This value was not any good... let's try another! | 
					
						
							|  |  |  |                     a += 2 | 
					
						
							|  |  |  |                 if not spotted: | 
					
						
							|  |  |  |                     raise ValueError("Unable to compute factors p and q from exponent d.") | 
					
						
							|  |  |  |                 # Found ! | 
					
						
							|  |  |  |                 assert ((n % p) == 0) | 
					
						
							|  |  |  |                 q = n // p | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             if u is None: | 
					
						
							|  |  |  |                 u = p.inverse(q) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             key_dict['p'] = p | 
					
						
							|  |  |  |             key_dict['q'] = q | 
					
						
							|  |  |  |             key_dict['u'] = u | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Build key object | 
					
						
							|  |  |  |         key = _RSAobj(key_dict, self._default_randfunc) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # Very consistency of the key | 
					
						
							| 
									
										
										
										
											2014-06-11 15:46:22 +02:00
										 |  |  |         fmt_error = False | 
					
						
							|  |  |  |         if consistency_check: | 
					
						
							|  |  |  |             # Modulus and public exponent must be coprime | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |             fmt_error = e <= 1 or e >= n | 
					
						
							|  |  |  |             fmt_error |= Integer(n).gcd(e) != 1 | 
					
						
							| 
									
										
										
										
											2014-06-11 15:46:22 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # For RSA, modulus must be odd | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |             fmt_error |= not n & 1 | 
					
						
							| 
									
										
										
										
											2014-06-11 15:46:22 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |             if not fmt_error and key.has_private(): | 
					
						
							| 
									
										
										
										
											2014-06-11 15:46:22 +02:00
										 |  |  |                 # Modulus and private exponent must be coprime | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |                 fmt_error = d <= 1 or d >= n | 
					
						
							|  |  |  |                 fmt_error |= Integer(n).gcd(d) != 1 | 
					
						
							| 
									
										
										
										
											2014-06-11 15:46:22 +02:00
										 |  |  |                 # Modulus must be product of 2 primes | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |                 fmt_error |= (p * q != n) | 
					
						
							|  |  |  |                 fmt_error |= test_probable_prime(p) == COMPOSITE | 
					
						
							|  |  |  |                 fmt_error |= test_probable_prime(q) == COMPOSITE | 
					
						
							| 
									
										
										
										
											2014-06-11 15:46:22 +02:00
										 |  |  |                 # See Carmichael theorem | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |                 phi = (p - 1) * (q - 1) | 
					
						
							|  |  |  |                 lcm = phi // (p - 1).gcd(q - 1) | 
					
						
							|  |  |  |                 fmt_error |= (e * d % int(lcm)) != 1 | 
					
						
							| 
									
										
										
										
											2014-06-11 15:46:22 +02:00
										 |  |  |                 if hasattr(key, 'u'): | 
					
						
							|  |  |  |                     # CRT coefficient | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |                     fmt_error |= u <= 1 or u >= q | 
					
						
							|  |  |  |                     fmt_error |= (p * u % q) != 1 | 
					
						
							| 
									
										
										
										
											2014-06-11 15:46:22 +02:00
										 |  |  |                 else: | 
					
						
							|  |  |  |                     fmt_error = True | 
					
						
							| 
									
										
										
										
											2013-06-17 23:25:21 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if fmt_error: | 
					
						
							|  |  |  |             raise ValueError("Invalid RSA key components") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |         return key | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-13 18:55:03 +02:00
										 |  |  |     def _importKeyDER(self, extern_key, passphrase, verify_x509_cert): | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  |         """Import an RSA key (public or private half), encoded in DER form.""" | 
					
						
							| 
									
										
										
										
											2011-10-10 08:11:31 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         try: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  |             der = _decode_der(DerSequence, extern_key) | 
					
						
							| 
									
										
										
										
											2011-10-10 08:11:31 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # Try PKCS#1 first, for a private key | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |             if len(der) == 9 and der.hasOnlyInts() and der[0] == 0: | 
					
						
							| 
									
										
										
										
											2011-01-16 22:05:54 +01:00
										 |  |  |                 # ASN.1 RSAPrivateKey element | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |                 del der[6:]     # Remove d mod (p-1), | 
					
						
							|  |  |  |                                 # d mod (q-1), and | 
					
						
							|  |  |  |                                 # q^{-1} mod p | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |                 der.append(Integer(der[4]).inverse(der[5]))  # Add p^{-1} mod q | 
					
						
							| 
									
										
										
										
											2011-01-16 22:05:54 +01:00
										 |  |  |                 del der[0]      # Remove version | 
					
						
							|  |  |  |                 return self.construct(der[:]) | 
					
						
							| 
									
										
										
										
											2011-10-10 08:11:31 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             # Keep on trying PKCS#1, but now for a public key | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |             if len(der) == 2: | 
					
						
							|  |  |  |                 try: | 
					
						
							|  |  |  |                     # The DER object is an RSAPublicKey SEQUENCE with | 
					
						
							|  |  |  |                     # two elements | 
					
						
							|  |  |  |                     if der.hasOnlyInts(): | 
					
						
							|  |  |  |                         return self.construct(der[:]) | 
					
						
							|  |  |  |                     # The DER object is a SubjectPublicKeyInfo SEQUENCE | 
					
						
							|  |  |  |                     # with two elements: an 'algorithmIdentifier' and a | 
					
						
							|  |  |  |                     # 'subjectPublicKey'BIT STRING. | 
					
						
							|  |  |  |                     # 'algorithmIdentifier' takes the value given at the | 
					
						
							|  |  |  |                     # module level. | 
					
						
							|  |  |  |                     # 'subjectPublicKey' encapsulates the actual ASN.1 | 
					
						
							|  |  |  |                     # RSAPublicKey element. | 
					
						
							|  |  |  |                     if der[0] == algorithmIdentifier: | 
					
						
							| 
									
										
										
										
											2014-06-16 21:42:39 +02:00
										 |  |  |                         bitmap = _decode_der(DerBitString, der[1]) | 
					
						
							|  |  |  |                         rsaPub = _decode_der(DerSequence, bitmap.value) | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |                         if len(rsaPub) == 2 and rsaPub.hasOnlyInts(): | 
					
						
							|  |  |  |                             return self.construct(rsaPub[:]) | 
					
						
							|  |  |  |                 except (ValueError, EOFError): | 
					
						
							|  |  |  |                     pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-13 18:55:03 +02:00
										 |  |  |             # Try to see if this is an X.509 DER certificate | 
					
						
							|  |  |  |             # (Certificate ASN.1 type) | 
					
						
							| 
									
										
										
										
											2014-07-11 22:58:47 +02:00
										 |  |  |             if len(der) == 3: | 
					
						
							| 
									
										
										
										
											2014-07-13 22:55:19 +02:00
										 |  |  |                 from Crypto.PublicKey import _extract_sp_info | 
					
						
							| 
									
										
										
										
											2014-07-11 22:58:47 +02:00
										 |  |  |                 try: | 
					
						
							| 
									
										
										
										
											2014-07-13 22:55:19 +02:00
										 |  |  |                     sp_info = _extract_sp_info(der) | 
					
						
							|  |  |  |                     if verify_x509_cert: | 
					
						
							|  |  |  |                         raise NotImplementedError("X.509 certificate validation is not supported") | 
					
						
							|  |  |  |                     return self._importKeyDER(sp_info, passphrase, False) | 
					
						
							|  |  |  |                 except ValueError: | 
					
						
							| 
									
										
										
										
											2014-07-11 22:58:47 +02:00
										 |  |  |                     pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |             # Try PKCS#8 (possibly encrypted) | 
					
						
							|  |  |  |             k = PKCS8.unwrap(extern_key, passphrase) | 
					
						
							|  |  |  |             if k[0] == oid: | 
					
						
							| 
									
										
										
										
											2014-07-13 18:55:03 +02:00
										 |  |  |                 return self._importKeyDER(k[1], passphrase, False) | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         except (ValueError, EOFError): | 
					
						
							| 
									
										
										
										
											2011-10-10 08:11:31 +02:00
										 |  |  |             pass | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-16 22:05:54 +01:00
										 |  |  |         raise ValueError("RSA key format is not supported") | 
					
						
							| 
									
										
										
										
											2009-12-27 17:26:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-13 18:55:03 +02:00
										 |  |  |     def importKey(self, extern_key, passphrase=None, verify_x509_cert=True): | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |         """Import an RSA key (public or private half), encoded in standard
 | 
					
						
							|  |  |  |         form. | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |         :Parameter extern_key: | 
					
						
							| 
									
										
										
										
											2014-07-13 18:55:03 +02:00
										 |  |  |             The RSA key to import, encoded as a byte string. | 
					
						
							| 
									
										
										
										
											2009-12-27 17:26:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-18 20:44:42 +02:00
										 |  |  |             An RSA public key can be in any of the following formats: | 
					
						
							| 
									
										
										
										
											2011-10-10 08:11:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-13 18:55:03 +02:00
										 |  |  |             - X.509 certificate (binary or PEM format) | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |             - X.509 ``subjectPublicKeyInfo`` DER SEQUENCE (binary or PEM | 
					
						
							|  |  |  |               encoding) | 
					
						
							|  |  |  |             - `PKCS#1`_ ``RSAPublicKey`` DER SEQUENCE (binary or PEM encoding) | 
					
						
							| 
									
										
										
										
											2012-05-18 20:44:42 +02:00
										 |  |  |             - OpenSSH (textual public key only) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             An RSA private key can be in any of the following formats: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |             - PKCS#1 ``RSAPrivateKey`` DER SEQUENCE (binary or PEM encoding) | 
					
						
							|  |  |  |             - `PKCS#8`_ ``PrivateKeyInfo`` or ``EncryptedPrivateKeyInfo`` | 
					
						
							|  |  |  |               DER SEQUENCE (binary or PEM encoding) | 
					
						
							| 
									
										
										
										
											2011-10-10 08:11:31 +02:00
										 |  |  |             - OpenSSH (textual public key only) | 
					
						
							| 
									
										
										
										
											2012-05-18 15:26:58 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             For details about the PEM encoding, see `RFC1421`_/`RFC1423`_. | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |             The private key may be encrypted by means of a certain pass phrase | 
					
						
							|  |  |  |             either at the PEM level or at the PKCS#8 level. | 
					
						
							|  |  |  |         :Type extern_key: string | 
					
						
							| 
									
										
										
										
											2011-01-16 21:44:10 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-03 23:33:11 +02:00
										 |  |  |         :Parameter passphrase: | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |             In case of an encrypted private key, this is the pass phrase from | 
					
						
							|  |  |  |             which the decryption key is derived. | 
					
						
							| 
									
										
										
										
											2011-10-03 23:33:11 +02:00
										 |  |  |         :Type passphrase: string | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-13 18:55:03 +02:00
										 |  |  |         :Parameter verify_x509_cert: | 
					
						
							|  |  |  |             When importing the public key from an X.509 certificate, whether | 
					
						
							|  |  |  |             the certificate should be validated. **Since verification is not | 
					
						
							|  |  |  |             yet supported, this value must always be set to False**. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             This value is ignored if an X.509 certificate is not passed. | 
					
						
							|  |  |  |         :Type verify_x509_cert: bool | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-04-10 21:26:33 +02:00
										 |  |  |         :Return: An RSA key object (`_RSAobj`). | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-10-03 23:33:11 +02:00
										 |  |  |         :Raise ValueError/IndexError/TypeError: | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |             When the given key cannot be parsed (possibly because the pass | 
					
						
							|  |  |  |             phrase is wrong). | 
					
						
							| 
									
										
										
										
											2012-04-12 23:16:52 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         .. _RFC1421: http://www.ietf.org/rfc/rfc1421.txt | 
					
						
							|  |  |  |         .. _RFC1423: http://www.ietf.org/rfc/rfc1423.txt | 
					
						
							| 
									
										
										
										
											2012-05-18 15:26:58 +02:00
										 |  |  |         .. _`PKCS#1`: http://www.ietf.org/rfc/rfc3447.txt | 
					
						
							|  |  |  |         .. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt | 
					
						
							| 
									
										
										
										
											2011-01-16 22:05:54 +01:00
										 |  |  |         """
 | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |         extern_key = tobytes(extern_key) | 
					
						
							| 
									
										
										
										
											2011-10-18 23:20:26 +02:00
										 |  |  |         if passphrase is not None: | 
					
						
							|  |  |  |             passphrase = tobytes(passphrase) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |         if extern_key.startswith(b('-----')): | 
					
						
							|  |  |  |             # This is probably a PEM encoded key. | 
					
						
							|  |  |  |             (der, marker, enc_flag) = PEM.decode(tostr(extern_key), passphrase) | 
					
						
							|  |  |  |             if enc_flag: | 
					
						
							|  |  |  |                 passphrase = None | 
					
						
							| 
									
										
										
										
											2014-07-13 18:55:03 +02:00
										 |  |  |             return self._importKeyDER(der, passphrase, verify_x509_cert) | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if extern_key.startswith(b('ssh-rsa ')): | 
					
						
							| 
									
										
										
										
											2011-09-21 00:01:36 +02:00
										 |  |  |                 # This is probably an OpenSSH key | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |                 keystring = binascii.a2b_base64(extern_key.split(b(' '))[1]) | 
					
						
							| 
									
										
										
										
											2011-09-21 00:01:36 +02:00
										 |  |  |                 keyparts = [] | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |                 while len(keystring) > 4: | 
					
						
							|  |  |  |                     l = struct.unpack(">I", keystring[:4])[0] | 
					
						
							|  |  |  |                     keyparts.append(keystring[4:4 + l]) | 
					
						
							|  |  |  |                     keystring = keystring[4 + l:] | 
					
						
							| 
									
										
										
										
											2014-12-05 08:12:51 -05:00
										 |  |  |                 e = Integer.from_bytes(keyparts[1]) | 
					
						
							|  |  |  |                 n = Integer.from_bytes(keyparts[2]) | 
					
						
							| 
									
										
										
										
											2011-09-21 00:01:36 +02:00
										 |  |  |                 return self.construct([n, e]) | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |         if bord(extern_key[0]) == 0x30: | 
					
						
							| 
									
										
										
										
											2011-01-16 22:05:54 +01:00
										 |  |  |                 # This is probably a DER encoded key | 
					
						
							| 
									
										
										
										
											2014-07-13 18:55:03 +02:00
										 |  |  |                 return self._importKeyDER(extern_key, passphrase, | 
					
						
							|  |  |  |                                           verify_x509_cert) | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-16 22:05:54 +01:00
										 |  |  |         raise ValueError("RSA key format is not supported") | 
					
						
							| 
									
										
										
										
											2009-12-27 17:26:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  | #: `Object ID`_ for the RSA encryption algorithm. This OID often indicates | 
					
						
							|  |  |  | #: a generic RSA key, even when such key will be actually used for digital | 
					
						
							|  |  |  | #: signatures. | 
					
						
							|  |  |  | #: | 
					
						
							|  |  |  | #: .. _`Object ID`: http://www.alvestrand.no/objectid/1.2.840.113549.1.1.1.html | 
					
						
							|  |  |  | oid = "1.2.840.113549.1.1.1" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #: This is the standard DER object that qualifies a cryptographic algorithm | 
					
						
							|  |  |  | #: in ASN.1-based data structures (e.g. X.509 certificates). | 
					
						
							| 
									
										
										
										
											2011-10-10 08:11:31 +02:00
										 |  |  | algorithmIdentifier = DerSequence( | 
					
						
							| 
									
										
										
										
											2013-06-15 23:25:49 +02:00
										 |  |  |   [DerObjectId(oid).encode(),      # algorithm field | 
					
						
							|  |  |  |   DerNull().encode()]              # parameters field | 
					
						
							| 
									
										
										
										
											2011-10-10 08:11:31 +02:00
										 |  |  |   ).encode() | 
					
						
							| 
									
										
										
										
											2013-06-17 23:25:21 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | _impl = RSAImplementation() | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  | #: | 
					
						
							|  |  |  | #: Randomly generate a fresh, new RSA key object. | 
					
						
							|  |  |  | #: | 
					
						
							|  |  |  | #: See `RSAImplementation.generate`. | 
					
						
							|  |  |  | #: | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | generate = _impl.generate | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  | #: | 
					
						
							|  |  |  | #: Construct an RSA key object from a tuple of valid RSA components. | 
					
						
							|  |  |  | #: | 
					
						
							|  |  |  | #: See `RSAImplementation.construct`. | 
					
						
							|  |  |  | #: | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | construct = _impl.construct | 
					
						
							| 
									
										
										
										
											2011-01-21 18:54:53 +01:00
										 |  |  | #: | 
					
						
							|  |  |  | #: Import an RSA key (public or private half), encoded in standard form. | 
					
						
							|  |  |  | #: | 
					
						
							|  |  |  | #: See `RSAImplementation.importKey`. | 
					
						
							|  |  |  | #: | 
					
						
							| 
									
										
										
										
											2009-12-27 17:26:59 +01:00
										 |  |  | importKey = _impl.importKey | 
					
						
							| 
									
										
										
										
											2008-09-18 21:42:28 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | # vim:set ts=4 sw=4 sts=4 expandtab: | 
					
						
							|  |  |  | 
 |