diff options
Diffstat (limited to 'src/cryptography/hazmat/primitives/serialization.py')
-rw-r--r-- | src/cryptography/hazmat/primitives/serialization.py | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/src/cryptography/hazmat/primitives/serialization.py b/src/cryptography/hazmat/primitives/serialization.py index d848e5d4..992fd42f 100644 --- a/src/cryptography/hazmat/primitives/serialization.py +++ b/src/cryptography/hazmat/primitives/serialization.py @@ -59,7 +59,7 @@ def load_ssh_public_key(data, backend): except TypeError: raise ValueError('Key is not in the proper format.') - inner_key_type, rest = _read_next_string(decoded_data) + inner_key_type, rest = _ssh_read_next_string(decoded_data) if inner_key_type != key_type: raise ValueError( @@ -70,8 +70,8 @@ def load_ssh_public_key(data, backend): def _load_ssh_rsa_public_key(key_type, decoded_data, backend): - e, rest = _read_next_mpint(decoded_data) - n, rest = _read_next_mpint(rest) + e, rest = _ssh_read_next_mpint(decoded_data) + n, rest = _ssh_read_next_mpint(rest) if rest: raise ValueError('Key body contains extra bytes.') @@ -80,10 +80,10 @@ def _load_ssh_rsa_public_key(key_type, decoded_data, backend): def _load_ssh_dss_public_key(key_type, decoded_data, backend): - p, rest = _read_next_mpint(decoded_data) - q, rest = _read_next_mpint(rest) - g, rest = _read_next_mpint(rest) - y, rest = _read_next_mpint(rest) + p, rest = _ssh_read_next_mpint(decoded_data) + q, rest = _ssh_read_next_mpint(rest) + g, rest = _ssh_read_next_mpint(rest) + y, rest = _ssh_read_next_mpint(rest) if rest: raise ValueError('Key body contains extra bytes.') @@ -95,8 +95,8 @@ def _load_ssh_dss_public_key(key_type, decoded_data, backend): def _load_ssh_ecdsa_public_key(expected_key_type, decoded_data, backend): - curve_name, rest = _read_next_string(decoded_data) - data, rest = _read_next_string(rest) + curve_name, rest = _ssh_read_next_string(decoded_data) + data, rest = _ssh_read_next_string(rest) if expected_key_type != b"ecdsa-sha2-" + curve_name: raise ValueError( @@ -121,7 +121,7 @@ def _load_ssh_ecdsa_public_key(expected_key_type, decoded_data, backend): return numbers.public_key(backend) -def _read_next_string(data): +def _ssh_read_next_string(data): """ Retrieves the next RFC 4251 string value from the data. @@ -137,22 +137,34 @@ def _read_next_string(data): return data[4:4 + str_len], data[4 + str_len:] -def _read_next_mpint(data): +def _ssh_read_next_mpint(data): """ Reads the next mpint from the data. Currently, all mpints are interpreted as unsigned. """ - mpint_data, rest = _read_next_string(data) + mpint_data, rest = _ssh_read_next_string(data) return ( utils.int_from_bytes(mpint_data, byteorder='big', signed=False), rest ) +def _ssh_write_string(data): + return struct.pack(">I", len(data)) + data + + +def _ssh_write_mpint(value): + data = utils.int_to_bytes(value) + if six.indexbytes(data, 0) & 0x80: + data = b"\x00" + data + return _ssh_write_string(data) + + class Encoding(Enum): PEM = "PEM" DER = "DER" + OpenSSH = "OpenSSH" class PrivateFormat(Enum): @@ -163,6 +175,7 @@ class PrivateFormat(Enum): class PublicFormat(Enum): SubjectPublicKeyInfo = "X.509 subjectPublicKeyInfo with PKCS#1" PKCS1 = "Raw PKCS#1" + OpenSSH = "OpenSSH" @six.add_metaclass(abc.ABCMeta) |