aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMark Adams <mark@markadams.me>2014-12-12 23:13:12 -0600
committerMark Adams <mark@markadams.me>2014-12-13 08:38:11 -0600
commit78a7d1c4c63737c4eae0c22207a00141a44402d3 (patch)
tree99b63769c2260fd888450e49ec8d25e26c1566d8 /src
parentbe42d096746ca211d0e1b21874017e75765dc40b (diff)
downloadcryptography-78a7d1c4c63737c4eae0c22207a00141a44402d3.tar.gz
cryptography-78a7d1c4c63737c4eae0c22207a00141a44402d3.tar.bz2
cryptography-78a7d1c4c63737c4eae0c22207a00141a44402d3.zip
Added load_ssh_rsa_public_key to hazmat.primitives.serialization to allow for loading of OpenSSH RSA public keys
Also added load_ssh_public_key as a generic method that can be later extended to support more public key algorithms.
Diffstat (limited to 'src')
-rw-r--r--src/cryptography/hazmat/primitives/serialization.py47
1 files changed, 47 insertions, 0 deletions
diff --git a/src/cryptography/hazmat/primitives/serialization.py b/src/cryptography/hazmat/primitives/serialization.py
index b9cf5967..0f07e41f 100644
--- a/src/cryptography/hazmat/primitives/serialization.py
+++ b/src/cryptography/hazmat/primitives/serialization.py
@@ -4,9 +4,13 @@
from __future__ import absolute_import, division, print_function
+import base64
+import struct
import warnings
from cryptography import utils
+from cryptography.exceptions import UnsupportedAlgorithm
+from cryptography.hazmat.primitives.asymmetric.rsa import RSAPublicNumbers
def load_pem_traditional_openssl_private_key(data, password, backend):
@@ -39,3 +43,46 @@ def load_pem_private_key(data, password, backend):
def load_pem_public_key(data, backend):
return backend.load_pem_public_key(data)
+
+
+def load_ssh_public_key(data, backend):
+ if not data.startswith(b'ssh-'):
+ raise ValueError('SSH-formatted keys must begin with ssh-')
+
+ if not data.startswith(b'ssh-rsa'):
+ raise UnsupportedAlgorithm('Only RSA keys are currently supported.')
+
+ return load_ssh_rsa_public_key(data, backend)
+
+
+def load_ssh_rsa_public_key(data, backend):
+ if not data.startswith(b'ssh-rsa '):
+ raise ValueError('SSH-formatted RSA keys must begin with ssh-rsa')
+
+ parts = data.split(b' ')
+ data = base64.b64decode(parts[1])
+
+ cert_data = []
+
+ while len(data) > 0:
+ str_len = struct.unpack('>I', data[0:4])[0]
+ cert_data.append(data[4:4 + str_len])
+ data = data[4 + str_len:]
+
+ e = _bytes_to_int(cert_data[1])
+ n = _bytes_to_int(cert_data[2])
+ return backend.load_rsa_public_numbers(RSAPublicNumbers(e, n))
+
+
+def _bytes_to_int(data):
+ if len(data) % 4 != 0:
+ # Pad the bytes with 0x00 to a block size of 4
+ data = (b'\x00' * (4 - (len(data) % 4))) + data
+
+ result = 0
+
+ while len(data) > 0:
+ result = (result << 32) + struct.unpack('>I', data[0:4])[0]
+ data = data[4:]
+
+ return result