diff options
author | Legrandin <gooksankoo@hoiptorrow.mailexpire.com> | 2011-09-21 20:54:17 +0200 |
---|---|---|
committer | Legrandin <gooksankoo@hoiptorrow.mailexpire.com> | 2011-09-21 20:54:17 +0200 |
commit | 51a760b18506ddfd11a692e7848178be63ee471a (patch) | |
tree | 90a68626e53b84b0c68b7e8de8518fce8a652314 | |
parent | b8dc2d95ea146d4ed77e48c33c1d731ff6ee5d50 (diff) | |
download | pycrypto-51a760b18506ddfd11a692e7848178be63ee471a.tar.gz |
Added support for export of public RSA keys in OpenSSH format
-rw-r--r-- | lib/Crypto/PublicKey/RSA.py | 22 | ||||
-rw-r--r-- | lib/Crypto/SelfTest/PublicKey/test_importKey.py | 7 |
2 files changed, 24 insertions, 5 deletions
diff --git a/lib/Crypto/PublicKey/RSA.py b/lib/Crypto/PublicKey/RSA.py index a148d7c..908ec68 100644 --- a/lib/Crypto/PublicKey/RSA.py +++ b/lib/Crypto/PublicKey/RSA.py @@ -33,7 +33,7 @@ __revision__ = "$Id$" __all__ = ['generate', 'construct', 'error', 'importKey' ] from Crypto.Util.python_compat import * -from Crypto.Util.number import getRandomRange, bytes_to_long +from Crypto.Util.number import getRandomRange, bytes_to_long, long_to_bytes from Crypto.PublicKey import _RSA, _slowmath, pubkey from Crypto import Random @@ -172,6 +172,7 @@ class _RSAobj(pubkey.pubkey): :Parameter format: The encoding to use to wrap the key. - *'DER'* for PKCS#1 + - *'OpenSSH'* for OpenSSH public keys (no private key) - *'PEM'* for RFC1421 :Type format: string @@ -179,6 +180,17 @@ class _RSAobj(pubkey.pubkey): :Raise ValueError: When the format is unknown. """ + if format=='OpenSSH': + eb = long_to_bytes(self.e) + nb = long_to_bytes(self.n) + if ord(eb[0]) & 0x80: eb='\x00'+nb + if ord(nb[0]) & 0x80: nb='\x00'+nb + keyparts = [ 'ssh-rsa', eb, nb ] + keystring = ''.join([ struct.pack(">I",len(kp))+kp for kp in keyparts]) + return 'ssh-rsa '+binascii.b2a_base64(keystring)[:-1] + + # PKCS#1 is a direct DER encoding. PEM uses it as well, but + # wraps in an ASCII envelope. der = DerSequence() if self.has_private(): keyType = "RSA PRIVATE" @@ -389,10 +401,10 @@ class RSAImplementation(object): # This is probably an OpenSSH key keystring = binascii.a2b_base64(externKey.split(' ')[1]) keyparts = [] - while keystring: - len = struct.unpack(">I",keystring[:4])[0] - keyparts.append(keystring[4:4+len]) - keystring = keystring[4+len:] + while len(keystring)>4: + l = struct.unpack(">I",keystring[:4])[0] + keyparts.append(keystring[4:4+l]) + keystring = keystring[4+l:] e = bytes_to_long(keyparts[1]) n = bytes_to_long(keyparts[2]) return self.construct([n, e]) diff --git a/lib/Crypto/SelfTest/PublicKey/test_importKey.py b/lib/Crypto/SelfTest/PublicKey/test_importKey.py index 4edc243..018754d 100644 --- a/lib/Crypto/SelfTest/PublicKey/test_importKey.py +++ b/lib/Crypto/SelfTest/PublicKey/test_importKey.py @@ -150,6 +150,13 @@ Lr7UkvEtFrRhDDKMtuIIq19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQ== pemKey = key.exportKey("PEM") self.assertEqual(pemKey, self.rsaPublicKeyPEM) + def testExportKey5(self): + key = self.rsa.construct([self.n, self.e]) + openssh_1 = key.exportKey("OpenSSH").split() + openssh_2 = self.rsaPublicKeyOpenSSH.split() + self.assertEqual(openssh_1[0], openssh_2[0]) + self.assertEqual(openssh_1[1], openssh_2[1]) + class ImportKeyTestsSlow(ImportKeyTests): def setUp(self): self.rsa = RSA.RSAImplementation(use_fast_math=0) |