tlslite.utils.keyfactory

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