Package tlslite :: Package utils :: Module keyfactory
[hide private]
[frames] | no frames]

Source Code for Module tlslite.utils.keyfactory

  1  # Author: Trevor Perrin 
  2  # See the LICENSE file for legal information regarding use of this file. 
  3   
  4  """Factory functions for asymmetric cryptography. 
  5  @sort: generateRSAKey, parsePEMKey, parseAsPublicKey 
  6  """ 
  7   
  8  from .compat import * 
  9   
 10  from .rsakey import RSAKey 
 11  from .python_rsakey import Python_RSAKey 
 12  from tlslite.utils import cryptomath 
 13   
 14  if cryptomath.m2cryptoLoaded: 
 15      from .openssl_rsakey import OpenSSL_RSAKey 
 16   
 17  if cryptomath.pycryptoLoaded: 
 18      from .pycrypto_rsakey import PyCrypto_RSAKey 
 19   
 20  # ************************************************************************** 
 21  # Factory Functions for RSA Keys 
 22  # ************************************************************************** 
 23   
24 -def generateRSAKey(bits, implementations=["openssl", "python"]):
25 """Generate an RSA key with the specified bit length. 26 27 @type bits: int 28 @param bits: Desired bit length of the new key's modulus. 29 30 @rtype: L{tlslite.utils.rsakey.RSAKey} 31 @return: A new RSA private key. 32 """ 33 for implementation in implementations: 34 if implementation == "openssl" and cryptomath.m2cryptoLoaded: 35 return OpenSSL_RSAKey.generate(bits) 36 elif implementation == "python": 37 return Python_RSAKey.generate(bits) 38 raise ValueError("No acceptable implementations")
39 40 #Parse as an OpenSSL or Python key
41 -def parsePEMKey(s, private=False, public=False, passwordCallback=None, 42 implementations=["openssl", "python"]):
43 """Parse a PEM-format key. 44 45 The PEM format is used by OpenSSL and other tools. The 46 format is typically used to store both the public and private 47 components of a key. For example:: 48 49 -----BEGIN RSA PRIVATE KEY----- 50 MIICXQIBAAKBgQDYscuoMzsGmW0pAYsmyHltxB2TdwHS0dImfjCMfaSDkfLdZY5+ 51 dOWORVns9etWnr194mSGA1F0Pls/VJW8+cX9+3vtJV8zSdANPYUoQf0TP7VlJxkH 52 dSRkUbEoz5bAAs/+970uos7n7iXQIni+3erUTdYEk2iWnMBjTljfgbK/dQIDAQAB 53 AoGAJHoJZk75aKr7DSQNYIHuruOMdv5ZeDuJvKERWxTrVJqE32/xBKh42/IgqRrc 54 esBN9ZregRCd7YtxoL+EVUNWaJNVx2mNmezEznrc9zhcYUrgeaVdFO2yBF1889zO 55 gCOVwrO8uDgeyj6IKa25H6c1N13ih/o7ZzEgWbGG+ylU1yECQQDv4ZSJ4EjSh/Fl 56 aHdz3wbBa/HKGTjC8iRy476Cyg2Fm8MZUe9Yy3udOrb5ZnS2MTpIXt5AF3h2TfYV 57 VoFXIorjAkEA50FcJmzT8sNMrPaV8vn+9W2Lu4U7C+K/O2g1iXMaZms5PC5zV5aV 58 CKXZWUX1fq2RaOzlbQrpgiolhXpeh8FjxwJBAOFHzSQfSsTNfttp3KUpU0LbiVvv 59 i+spVSnA0O4rq79KpVNmK44Mq67hsW1P11QzrzTAQ6GVaUBRv0YS061td1kCQHnP 60 wtN2tboFR6lABkJDjxoGRvlSt4SOPr7zKGgrWjeiuTZLHXSAnCY+/hr5L9Q3ZwXG 61 6x6iBdgLjVIe4BZQNtcCQQDXGv/gWinCNTN3MPWfTW/RGzuMYVmyBFais0/VrgdH 62 h1dLpztmpQqfyH/zrBXQ9qL/zR4ojS6XYneO/U18WpEe 63 -----END RSA PRIVATE KEY----- 64 65 To generate a key like this with OpenSSL, run:: 66 67 openssl genrsa 2048 > key.pem 68 69 This format also supports password-encrypted private keys. TLS 70 Lite can only handle password-encrypted private keys when OpenSSL 71 and M2Crypto are installed. In this case, passwordCallback will be 72 invoked to query the user for the password. 73 74 @type s: str 75 @param s: A string containing a PEM-encoded public or private key. 76 77 @type private: bool 78 @param private: If True, a L{SyntaxError} will be raised if the 79 private key component is not present. 80 81 @type public: bool 82 @param public: If True, the private key component (if present) will 83 be discarded, so this function will always return a public key. 84 85 @type passwordCallback: callable 86 @param passwordCallback: This function will be called, with no 87 arguments, if the PEM-encoded private key is password-encrypted. 88 The callback should return the password string. If the password is 89 incorrect, SyntaxError will be raised. If no callback is passed 90 and the key is password-encrypted, a prompt will be displayed at 91 the console. 92 93 @rtype: L{tlslite.utils.RSAKey.RSAKey} 94 @return: An RSA key. 95 96 @raise SyntaxError: If the key is not properly formatted. 97 """ 98 for implementation in implementations: 99 if implementation == "openssl" and cryptomath.m2cryptoLoaded: 100 key = OpenSSL_RSAKey.parse(s, passwordCallback) 101 break 102 elif implementation == "python": 103 key = Python_RSAKey.parsePEM(s) 104 break 105 else: 106 raise ValueError("No acceptable implementations") 107 108 return _parseKeyHelper(key, private, public)
109 110
111 -def _parseKeyHelper(key, private, public):
112 if private: 113 if not key.hasPrivateKey(): 114 raise SyntaxError("Not a private key!") 115 116 if public: 117 return _createPublicKey(key) 118 119 if private: 120 if hasattr(key, "d"): 121 return _createPrivateKey(key) 122 else: 123 return key 124 125 return key
126
127 -def parseAsPublicKey(s):
128 """Parse a PEM-formatted public key. 129 130 @type s: str 131 @param s: A string containing a PEM-encoded public or private key. 132 133 @rtype: L{tlslite.utils.rsakey.RSAKey} 134 @return: An RSA public key. 135 136 @raise SyntaxError: If the key is not properly formatted. 137 """ 138 return parsePEMKey(s, public=True)
139
140 -def parsePrivateKey(s):
141 """Parse a PEM-formatted private key. 142 143 @type s: str 144 @param s: A string containing a PEM-encoded private key. 145 146 @rtype: L{tlslite.utils.rsakey.RSAKey} 147 @return: An RSA private key. 148 149 @raise SyntaxError: If the key is not properly formatted. 150 """ 151 return parsePEMKey(s, private=True)
152
153 -def _createPublicKey(key):
154 """ 155 Create a new public key. Discard any private component, 156 and return the most efficient key possible. 157 """ 158 if not isinstance(key, RSAKey): 159 raise AssertionError() 160 return _createPublicRSAKey(key.n, key.e)
161
162 -def _createPrivateKey(key):
163 """ 164 Create a new private key. Return the most efficient key possible. 165 """ 166 if not isinstance(key, RSAKey): 167 raise AssertionError() 168 if not key.hasPrivateKey(): 169 raise AssertionError() 170 return _createPrivateRSAKey(key.n, key.e, key.d, key.p, key.q, key.dP, 171 key.dQ, key.qInv)
172
173 -def _createPublicRSAKey(n, e, implementations = ["openssl", "pycrypto", 174 "python"]):
175 for implementation in implementations: 176 if implementation == "openssl" and cryptomath.m2cryptoLoaded: 177 return OpenSSL_RSAKey(n, e) 178 elif implementation == "pycrypto" and cryptomath.pycryptoLoaded: 179 return PyCrypto_RSAKey(n, e) 180 elif implementation == "python": 181 return Python_RSAKey(n, e) 182 raise ValueError("No acceptable implementations")
183
184 -def _createPrivateRSAKey(n, e, d, p, q, dP, dQ, qInv, 185 implementations = ["pycrypto", "python"]):
186 for implementation in implementations: 187 if implementation == "pycrypto" and cryptomath.pycryptoLoaded: 188 return PyCrypto_RSAKey(n, e, d, p, q, dP, dQ, qInv) 189 elif implementation == "python": 190 return Python_RSAKey(n, e, d, p, q, dP, dQ, qInv) 191 raise ValueError("No acceptable implementations")
192