summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLegrandin <gooksankoo@hoiptorrow.mailexpire.com>2012-05-18 20:44:42 +0200
committerLegrandin <gooksankoo@hoiptorrow.mailexpire.com>2012-05-18 22:54:57 +0200
commitcdcc48b064f298f7ea53b651ca726ed7f0aef81c (patch)
tree7a75b889bb248d092b3cf172f7aa3210e080bca8
parent6a8f175f86d60814df3d07bb23fa7a897107b553 (diff)
downloadpycrypto-cdcc48b064f298f7ea53b651ca726ed7f0aef81c.tar.gz
Add ability to import RSAPublicKey objects (encoded in DER or PEM)
-rw-r--r--lib/Crypto/PublicKey/RSA.py18
-rw-r--r--lib/Crypto/SelfTest/PublicKey/test_importKey.py24
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])