Skip to content

Commit 0366dc2

Browse files
authored
Add SHA1 as an allowed hash algorithm for ssh_key_fingerprint (#15134)
* Add SHA1 as an allowed hash algorithm for ssh_key_fingerprint * Add tests for SHA1 hashes of ssh_key_fingerprint Update docs to reflect SHA1 being an allowed hash algorithm for ssh_key_fingerprint * Linting fixes
1 parent 28195b8 commit 0366dc2

3 files changed

Lines changed: 41 additions & 6 deletions

File tree

docs/hazmat/primitives/asymmetric/serialization.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,8 +438,8 @@ DSA keys look almost identical but begin with ``ssh-dss`` rather than
438438
:param key: The public key to compute the fingerprint for.
439439
:type key: One of :data:`SSHPublicKeyTypes`
440440

441-
:param hash_algorithm: The hash algorithm to use, either ``MD5()`` or
442-
``SHA256()``.
441+
:param hash_algorithm: The hash algorithm to use, either ``MD5()``,
442+
``SHA1()``, or ``SHA256()``.
443443

444444
:return: The key fingerprint.
445445
:rtype: bytes

src/cryptography/hazmat/primitives/serialization/ssh.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1144,10 +1144,13 @@ def _parse_exts_opts(exts_opts: memoryview) -> dict[bytes, bytes]:
11441144

11451145
def ssh_key_fingerprint(
11461146
key: SSHPublicKeyTypes,
1147-
hash_algorithm: hashes.MD5 | hashes.SHA256,
1147+
hash_algorithm: hashes.MD5 | hashes.SHA1 | hashes.SHA256,
11481148
) -> bytes:
1149-
if not isinstance(hash_algorithm, (hashes.MD5, hashes.SHA256)):
1150-
raise TypeError("hash_algorithm must be either MD5 or SHA256")
1149+
if not isinstance(
1150+
hash_algorithm,
1151+
(hashes.MD5, hashes.SHA1, hashes.SHA256),
1152+
):
1153+
raise TypeError("hash_algorithm must be either MD5, SHA1, or SHA256")
11511154

11521155
key_type = _get_ssh_key_type(key)
11531156
kformat = _lookup_kformat(key_type)

tests/hazmat/primitives/test_ssh.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1864,6 +1864,16 @@ def test_ssh_key_fingerprint_rsa_md5(self):
18641864
fingerprint = ssh_key_fingerprint(public_key, hashes.MD5())
18651865
assert fingerprint == b"\x10G\xc2es\xd6QIH\x0b\x81\x1f6\x04{R"
18661866

1867+
def test_ssh_key_fingerprint_rsa_sha1(self):
1868+
ssh_key = load_vectors_from_file(
1869+
os.path.join("asymmetric", "OpenSSH", "rsa-nopsw.key.pub"),
1870+
lambda f: f.read(),
1871+
mode="rb",
1872+
)
1873+
public_key = load_ssh_public_key(ssh_key)
1874+
fingerprint = ssh_key_fingerprint(public_key, hashes.SHA1())
1875+
assert fingerprint == b"cQ{L\xf8V\xb5N\x8c\x8e^ni?\xb7(1\xc4\xba\xc5"
1876+
18671877
def test_ssh_key_fingerprint_rsa_sha256(self):
18681878
ssh_key = load_vectors_from_file(
18691879
os.path.join("asymmetric", "OpenSSH", "rsa-nopsw.key.pub"),
@@ -1891,6 +1901,16 @@ def test_ssh_key_fingerprint_ed25519_md5(self):
18911901
fingerprint = ssh_key_fingerprint(public_key, hashes.MD5())
18921902
assert fingerprint == b"\xe5R=\x01\x9e\xa0\xc1\xe9\x8c?L|\xc5\x94W\x85"
18931903

1904+
def test_ssh_key_fingerprint_ed25519_sha1(self):
1905+
ssh_key = load_vectors_from_file(
1906+
os.path.join("asymmetric", "OpenSSH", "ed25519-nopsw.key.pub"),
1907+
lambda f: f.read(),
1908+
mode="rb",
1909+
)
1910+
public_key = load_ssh_public_key(ssh_key)
1911+
fingerprint = ssh_key_fingerprint(public_key, hashes.SHA1())
1912+
assert fingerprint == b"$\x8a\x8d~p` <\xc4\xdb\x80\xf7*\xaf{)-RX{"
1913+
18941914
def test_ssh_key_fingerprint_ed25519_sha256(self):
18951915
ssh_key = load_vectors_from_file(
18961916
os.path.join("asymmetric", "OpenSSH", "ed25519-nopsw.key.pub"),
@@ -1918,6 +1938,18 @@ def test_ssh_key_fingerprint_ecdsa_md5(self):
19181938
fingerprint = ssh_key_fingerprint(public_key, hashes.MD5())
19191939
assert fingerprint == b"\re\xf2-\xfaGq\x8c^\x16\xb05+\x06\x1b7"
19201940

1941+
def test_ssh_key_fingerprint_ecdsa_sha1(self):
1942+
ssh_key = load_vectors_from_file(
1943+
os.path.join("asymmetric", "OpenSSH", "ecdsa-nopsw.key.pub"),
1944+
lambda f: f.read(),
1945+
mode="rb",
1946+
)
1947+
public_key = load_ssh_public_key(ssh_key)
1948+
fingerprint = ssh_key_fingerprint(public_key, hashes.SHA1())
1949+
assert fingerprint == (
1950+
b"\xdd\xa58\x87cl\x8f\x89\xd9\xd2\x836~\xd1R\xd7\xd7\xf2\x87\xa9"
1951+
)
1952+
19211953
def test_ssh_key_fingerprint_ecdsa_sha256(self):
19221954
ssh_key = load_vectors_from_file(
19231955
os.path.join("asymmetric", "OpenSSH", "ecdsa-nopsw.key.pub"),
@@ -1939,7 +1971,7 @@ def test_ssh_key_fingerprint_unsupported_hash(self):
19391971
)
19401972
public_key = load_ssh_public_key(ssh_key)
19411973
with pytest.raises(TypeError):
1942-
ssh_key_fingerprint(public_key, hashes.SHA1()) # type: ignore[arg-type]
1974+
ssh_key_fingerprint(public_key, hashes.SM3()) # type: ignore[arg-type]
19431975

19441976
def test_ssh_key_fingerprint_unsupported_key(self):
19451977
with pytest.raises(ValueError):

0 commit comments

Comments
 (0)