From cdcc48b064f298f7ea53b651ca726ed7f0aef81c Mon Sep 17 00:00:00 2001 From: Legrandin Date: Fri, 18 May 2012 20:44:42 +0200 Subject: Add ability to import RSAPublicKey objects (encoded in DER or PEM) --- lib/Crypto/PublicKey/RSA.py | 18 ++++++++++++------ lib/Crypto/SelfTest/PublicKey/test_importKey.py | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/lib/Crypto/PublicKey/RSA.py b/lib/Crypto/PublicKey/RSA.py index db109a9..99d851d 100644 --- a/lib/Crypto/PublicKey/RSA.py +++ b/lib/Crypto/PublicKey/RSA.py @@ -557,6 +557,9 @@ class RSAImplementation(object): # Keep on trying PKCS#1, but now for a public key if len(der)==2: + # 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 'algorithm' (or 'algorithmIdentifier') SEQUENCE and a 'subjectPublicKey' BIT STRING. # 'algorithm' takes the value given a few lines above. @@ -590,13 +593,16 @@ class RSAImplementation(object): :Parameter externKey: The RSA key to import, encoded as a string. - The key can be in any of the following formats: + An RSA public key can be in any of the following formats: - - X.509 `subjectPublicKeyInfo` DER SEQUENCE (binary, public key only) - - X.509 `subjectPublicKeyInfo` DER SEQUENCE (PEM encoding, public key only) - - `PKCS#1`_ `RSAPrivateKey` DER SEQUENCE (binary, private key only) - - `PKCS#8`_ `PrivateKeyInfo` DER SEQUENCE (binary, private key only) - - PKCS#8 `PrivateKeyInfo` DER SEQUENCE (PEM encoding, private key only) + - X.509 `subjectPublicKeyInfo` DER SEQUENCE (binary or PEM encoding) + - `PKCS#1`_ `RSAPublicKey` DER SEQUENCE (binary or PEM encoding) + - OpenSSH (textual public key only) + + An RSA private key can be in any of the following formats: + + - PKCS#1 `RSAPrivateKey` DER SEQUENCE (binary or PEM encoding) + - `PKCS#8`_ `PrivateKeyInfo` DER SEQUENCE (binary or PEM encoding) - OpenSSH (textual public key only) For details about the PEM encoding, see `RFC1421`_/`RFC1423`_. diff --git a/lib/Crypto/SelfTest/PublicKey/test_importKey.py b/lib/Crypto/SelfTest/PublicKey/test_importKey.py index 0fd59f7..28a7eee 100644 --- a/lib/Crypto/SelfTest/PublicKey/test_importKey.py +++ b/lib/Crypto/SelfTest/PublicKey/test_importKey.py @@ -30,6 +30,15 @@ from Crypto.PublicKey import RSA from Crypto.SelfTest.st_common import * from Crypto.Util.py3compat import * from Crypto.Util.number import inverse +from Crypto.Util import asn1 + +def der2pem(der, text='PUBLIC'): + import binascii + chunks = [ binascii.b2a_base64(der[i:i+48]) for i in range(0, len(der), 48) ] + pem = b('-----BEGIN %s KEY-----\n' % text) + pem += b('').join(chunks) + pem += b('-----END %s KEY-----' % text) + return pem class ImportKeyTests(unittest.TestCase): # 512-bit RSA key generated with openssl @@ -246,6 +255,21 @@ Lr7UkvEtFrRhDDKMtuIIq19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQ== self.assertEqual(key.p, self.p) self.assertEqual(key.q, self.q) + def testImportKey11(self): + """Verify import of RSAPublicKey DER SEQUENCE""" + der = asn1.DerSequence([17, 3]).encode() + key = self.rsa.importKey(der) + self.assertEqual(key.n, 17) + self.assertEqual(key.e, 3) + + def testImportKey12(self): + """Verify import of RSAPublicKey DER SEQUENCE, encoded with PEM""" + der = asn1.DerSequence([17, 3]).encode() + pem = der2pem(der) + key = self.rsa.importKey(pem) + self.assertEqual(key.n, 17) + self.assertEqual(key.e, 3) + ### def testExportKey1(self): key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) -- cgit v1.2.1