diff options
author | Sybren A. St?vel <sybren@stuvel.eu> | 2011-07-21 22:16:56 +0200 |
---|---|---|
committer | Sybren A. St?vel <sybren@stuvel.eu> | 2011-07-21 22:16:56 +0200 |
commit | 540464cb492b582b7a080497d03891c326f24b89 (patch) | |
tree | 1dc2ce204cf312b603d4df0424ebce92ad3e503a /rsa/key.py | |
parent | 68584a0901f33624e1b34a24cee25f9b7514f673 (diff) | |
download | rsa-540464cb492b582b7a080497d03891c326f24b89.tar.gz |
Moved key load/save to PrivateKey class
Diffstat (limited to 'rsa/key.py')
-rw-r--r-- | rsa/key.py | 216 |
1 files changed, 110 insertions, 106 deletions
@@ -131,6 +131,114 @@ class PrivateKey(object): def __ne__(self, other): return not (self == other) + @classmethod + def load_pkcs1_der(cls, keyfile): + r'''Loads a key in PKCS#1 DER format. + + @param keyfile: contents of a DER-encoded file that contains the private + key. + @return: a PrivateKey object + + First let's construct a DER encoded key: + + >>> import base64 + >>> b64der = 'MC4CAQACBQDeKYlRAgMBAAECBQDHn4npAgMA/icCAwDfxwIDANcXAgInbwIDAMZt' + >>> der = base64.decodestring(b64der) + + This loads the file: + + >>> PrivateKey.load_pkcs1_der(der) + PrivateKey(3727264081, 65537, 3349121513, 65063, 57287) + + ''' + + from pyasn1.codec.der import decoder + (priv, _) = decoder.decode(keyfile) + + # ASN.1 contents of DER encoded private key: + # + # RSAPrivateKey ::= SEQUENCE { + # version Version, + # modulus INTEGER, -- n + # publicExponent INTEGER, -- e + # privateExponent INTEGER, -- d + # prime1 INTEGER, -- p + # prime2 INTEGER, -- q + # exponent1 INTEGER, -- d mod (p-1) + # exponent2 INTEGER, -- d mod (q-1) + # coefficient INTEGER, -- (inverse of q) mod p + # otherPrimeInfos OtherPrimeInfos OPTIONAL + # } + + if priv[0] != 0: + raise ValueError('Unable to read this file, version %s != 0' % priv[0]) + + return cls(*priv[1:9]) + + def save_pkcs1_der(self): + '''Saves the private key in PKCS#1 DER format. + + @param priv_key: the private key to save + @returns: the DER-encoded private key. + ''' + + from pyasn1.type import univ, namedtype, tag + from pyasn1.codec.der import encoder + + class AsnPrivKey(univ.Sequence): + componentType = namedtype.NamedTypes( + namedtype.NamedType('version', univ.Integer()), + namedtype.NamedType('modulus', univ.Integer()), + namedtype.NamedType('publicExponent', univ.Integer()), + namedtype.NamedType('privateExponent', univ.Integer()), + namedtype.NamedType('prime1', univ.Integer()), + namedtype.NamedType('prime2', univ.Integer()), + namedtype.NamedType('exponent1', univ.Integer()), + namedtype.NamedType('exponent2', univ.Integer()), + namedtype.NamedType('coefficient', univ.Integer()), + ) + + # Create the ASN object + asn_key = AsnPrivKey() + asn_key.setComponentByName('version', 0) + asn_key.setComponentByName('modulus', self.n) + asn_key.setComponentByName('publicExponent', self.e) + asn_key.setComponentByName('privateExponent', self.d) + asn_key.setComponentByName('prime1', self.p) + asn_key.setComponentByName('prime2', self.q) + asn_key.setComponentByName('exponent1', self.exp1) + asn_key.setComponentByName('exponent2', self.exp2) + asn_key.setComponentByName('coefficient', self.coef) + + return encoder.encode(asn_key) + + @classmethod + def load_pkcs1_pem(cls, keyfile): + '''Loads a PKCS#1 PEM-encoded private key file. + + The contents of the file before the "-----BEGIN RSA PRIVATE KEY-----" and + after the "-----END RSA PRIVATE KEY-----" lines is ignored. + + @param keyfile: contents of a PEM-encoded file that contains the private + key. + @return: a PrivateKey object + ''' + + der = rsa.pem.load_pem(keyfile, 'RSA PRIVATE KEY') + return cls.load_pkcs1_der(der) + + def save_pkcs1_pem(self): + '''Saves a PKCS#1 PEM-encoded private key file. + + @param keyfile: a PrivateKey object + @return: contents of a PEM-encoded file that contains the private key. + ''' + + der = self.save_pkcs1_der() + return rsa.pem.save_pem(der, 'RSA PRIVATE KEY') + + + def extended_gcd(a, b): """Returns a tuple (r, i, j) such that r = gcd(a, b) = ia + jb """ @@ -245,112 +353,8 @@ def newkeys(nbits): PrivateKey(n, e, d, p, q) ) -def load_private_key_der(keyfile): - r'''Loads a key in DER format. - - @param keyfile: contents of a DER-encoded file that contains the private - key. - @return: a PrivateKey object - - First let's construct a DER encoded key: - - >>> import base64 - >>> b64der = 'MC4CAQACBQDeKYlRAgMBAAECBQDHn4npAgMA/icCAwDfxwIDANcXAgInbwIDAMZt' - >>> der = base64.decodestring(b64der) - - This loads the file: - - >>> load_private_key_der(der) - PrivateKey(3727264081, 65537, 3349121513, 65063, 57287) - - ''' - - from pyasn1.codec.der import decoder - (priv, _) = decoder.decode(keyfile) - - # ASN.1 contents of DER encoded private key: - # - # RSAPrivateKey ::= SEQUENCE { - # version Version, - # modulus INTEGER, -- n - # publicExponent INTEGER, -- e - # privateExponent INTEGER, -- d - # prime1 INTEGER, -- p - # prime2 INTEGER, -- q - # exponent1 INTEGER, -- d mod (p-1) - # exponent2 INTEGER, -- d mod (q-1) - # coefficient INTEGER, -- (inverse of q) mod p - # otherPrimeInfos OtherPrimeInfos OPTIONAL - # } - - if priv[0] != 0: - raise ValueError('Unable to read this file, version %s != 0' % priv[0]) - - return PrivateKey(*priv[1:9]) - -def save_private_key_der(priv_key): - '''Saves the private key in DER format. - - @param priv_key: the private key to save - @returns: the DER-encoded private key. - ''' - - from pyasn1.type import univ, namedtype, tag - from pyasn1.codec.der import encoder - - class AsnPrivKey(univ.Sequence): - componentType = namedtype.NamedTypes( - namedtype.NamedType('version', univ.Integer()), - namedtype.NamedType('modulus', univ.Integer()), - namedtype.NamedType('publicExponent', univ.Integer()), - namedtype.NamedType('privateExponent', univ.Integer()), - namedtype.NamedType('prime1', univ.Integer()), - namedtype.NamedType('prime2', univ.Integer()), - namedtype.NamedType('exponent1', univ.Integer()), - namedtype.NamedType('exponent2', univ.Integer()), - namedtype.NamedType('coefficient', univ.Integer()), - ) - - # Create the ASN object - asn_key = AsnPrivKey() - asn_key.setComponentByName('version', 0) - asn_key.setComponentByName('modulus', priv_key.n) - asn_key.setComponentByName('publicExponent', priv_key.e) - asn_key.setComponentByName('privateExponent', priv_key.d) - asn_key.setComponentByName('prime1', priv_key.p) - asn_key.setComponentByName('prime2', priv_key.q) - asn_key.setComponentByName('exponent1', priv_key.exp1) - asn_key.setComponentByName('exponent2', priv_key.exp2) - asn_key.setComponentByName('coefficient', priv_key.coef) - - return encoder.encode(asn_key) - -def load_private_key_pem(keyfile): - '''Loads a PEM-encoded private key file. - - The contents of the file before the "-----BEGIN RSA PRIVATE KEY-----" and - after the "-----END RSA PRIVATE KEY-----" lines is ignored. - - @param keyfile: contents of a PEM-encoded file that contains the private - key. - @return: a PrivateKey object - ''' - - der = rsa.pem.load_pem(keyfile, 'RSA PRIVATE KEY') - return load_private_key_der(der) - -def save_private_key_pem(priv_key): - '''Saves a PEM-encoded private key file. - - @param keyfile: a PrivateKey object - @return: contents of a PEM-encoded file that contains the private key. - ''' - - der = save_private_key_der(priv_key) - return rsa.pem.save_pem(der, 'RSA PRIVATE KEY') - - -__all__ = ['PublicKey', 'PrivateKey', 'newkeys', 'load'] +__all__ = ['PublicKey', 'PrivateKey', 'newkeys', 'load_private_key_der', + 'load_private_key_pem', 'save_private_key_der', 'save_private_key_pem'] if __name__ == '__main__': import doctest |