aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/hazmat/primitives/asymmetric/serialization.rst13
-rw-r--r--src/cryptography/hazmat/primitives/serialization.py21
-rw-r--r--tests/hazmat/primitives/test_serialization.py8
3 files changed, 27 insertions, 15 deletions
diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst
index a9392c7b..b523c342 100644
--- a/docs/hazmat/primitives/asymmetric/serialization.rst
+++ b/docs/hazmat/primitives/asymmetric/serialization.rst
@@ -201,8 +201,8 @@ OpenSSH Public Key
The format used by OpenSSH to store public keys, as specified in :rfc:`4253`.
-Currently, only RSA public keys are supported. Any other type of key will
-result in an exception being thrown.
+Currently, only RSA and DSA public keys are supported. Any other type of key
+will result in an exception being thrown.
An example RSA key in OpenSSH format (line breaks added for formatting
purposes)::
@@ -215,6 +215,9 @@ purposes)::
///ImSCGHQRvhwariN2tvZ6CBNSLh3iQgeB0AkyJlng7MXB2qYq/Ci2FUOryCX
2MzHvnbv testkey@localhost
+DSA keys look almost identical but begin with ``ssh-dss`` rather than
+``ssh-rsa``.
+
.. function:: load_ssh_public_key(data, backend)
.. versionadded:: 0.7
@@ -224,8 +227,10 @@ purposes)::
:param bytes data: The OpenSSH encoded key data.
- :param backend: An
- :class:`~cryptography.hazmat.backends.interfaces.RSABackend` provider.
+ :param backend: A backend providing
+ :class:`~cryptography.hazmat.backends.interfaces.RSABackend` or
+ :class:`~cryptography.hazmat.backends.interfaces.DSABackend` depending
+ on key type.
:returns: A new instance of a public key type.
diff --git a/src/cryptography/hazmat/primitives/serialization.py b/src/cryptography/hazmat/primitives/serialization.py
index 1949b111..61a69a5d 100644
--- a/src/cryptography/hazmat/primitives/serialization.py
+++ b/src/cryptography/hazmat/primitives/serialization.py
@@ -58,20 +58,23 @@ def load_ssh_public_key(data, backend):
key_type = key_parts[0]
key_body = key_parts[1]
+ try:
+ decoded_data = base64.b64decode(key_body)
+ except TypeError:
+ raise ValueError('Key is not in the proper format.')
+
if key_type.startswith(b'ssh-rsa'):
- return _load_ssh_rsa_public_key(key_body, backend)
+ return _load_ssh_rsa_public_key(decoded_data, backend)
elif key_type.startswith(b'ssh-dss'):
- return _load_ssh_dss_public_key(key_body, backend)
+ return _load_ssh_dss_public_key(decoded_data, backend)
else:
raise UnsupportedAlgorithm(
'Only RSA and DSA keys are currently supported.'
)
-def _load_ssh_rsa_public_key(key_body, backend):
- data = base64.b64decode(key_body)
-
- key_type, rest = _read_next_string(data)
+def _load_ssh_rsa_public_key(decoded_data, backend):
+ key_type, rest = _read_next_string(decoded_data)
e, rest = _read_next_mpint(rest)
n, rest = _read_next_mpint(rest)
@@ -85,10 +88,8 @@ def _load_ssh_rsa_public_key(key_body, backend):
return backend.load_rsa_public_numbers(RSAPublicNumbers(e, n))
-def _load_ssh_dss_public_key(key_body, backend):
- data = base64.b64decode(key_body)
-
- key_type, rest = _read_next_string(data)
+def _load_ssh_dss_public_key(decoded_data, backend):
+ key_type, rest = _read_next_string(decoded_data)
p, rest = _read_next_mpint(rest)
q, rest = _read_next_mpint(rest)
g, rest = _read_next_mpint(rest)
diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py
index de0ca702..91db318c 100644
--- a/tests/hazmat/primitives/test_serialization.py
+++ b/tests/hazmat/primitives/test_serialization.py
@@ -690,11 +690,17 @@ class TestPKCS8Serialization(object):
@pytest.mark.requires_backend_interface(interface=RSABackend)
class TestRSASSHSerialization(object):
def test_load_ssh_public_key_unsupported(self, backend):
- ssh_key = b'ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTY...'
+ ssh_key = b'ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTY='
with pytest.raises(UnsupportedAlgorithm):
load_ssh_public_key(ssh_key, backend)
+ def test_load_ssh_public_key_bad_format(self, backend):
+ ssh_key = b'ssh-rsa not-a-real-key'
+
+ with pytest.raises(ValueError):
+ load_ssh_public_key(ssh_key, backend)
+
def test_load_ssh_public_key_rsa_too_short(self, backend):
ssh_key = b'ssh-rsa'