Skip to content

Commit

Permalink
Test rest of new/modified PKey members
Browse files Browse the repository at this point in the history
Includes more migrations from test_pkey to pkey
  • Loading branch information
bitprophet committed May 25, 2023
1 parent e366e07 commit 6137821
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 51 deletions.
2 changes: 1 addition & 1 deletion paramiko/rsakey.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def __init__(

@classmethod
def identifiers(cls):
return cls.HASHES.keys()
return list(cls.HASHES.keys())

@property
def size(self):
Expand Down
6 changes: 4 additions & 2 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,11 +158,13 @@ def keys(request):
bag.path = Path(_support(f"{short_type}.key"))
with bag.path.open() as fd:
bag.pkey = key_class.from_private_key(fd)
# Second copy for things like equality-but-not-identity testing
with bag.path.open() as fd:
bag.pkey2 = key_class.from_private_key(fd)
bag.expected_fp = fingerprint
# Also tack on the cert-bearing variant for some tests
cert = bag.path.with_suffix(".key-cert.pub")
if cert.exists():
bag.pkey_with_cert = PKey.from_path(cert)
bag.pkey_with_cert = PKey.from_path(cert) if cert.exists() else None
# Safety checks
assert bag.pkey.fingerprint == fingerprint
yield bag
73 changes: 70 additions & 3 deletions tests/pkey.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@

from cryptography.hazmat.primitives.asymmetric.ed448 import Ed448PrivateKey
from paramiko import (
PKey,
DSSKey,
ECDSAKey,
Ed25519Key,
RSAKey,
UnknownKeyType,
Message,
PKey,
PublicBlob,
RSAKey,
UnknownKeyType,
)

from ._util import _support
Expand Down Expand Up @@ -159,3 +161,68 @@ def loading_cert_of_different_type_from_key_raises_ValueError(self):
err = "PublicBlob type ssh-rsa-cert-v01@openssh.com incompatible with key type ssh-ed25519" # noqa
with raises(ValueError, match=err):
edkey.load_certificate(_support("rsa.key-cert.pub"))

def fingerprint(self, keys):
# NOTE: Hardcoded fingerprint expectation stored in fixture.
assert keys.pkey.fingerprint == keys.expected_fp

def algorithm_name(self, keys):
key = keys.pkey
if isinstance(key, RSAKey):
assert key.algorithm_name == "RSA"
elif isinstance(key, DSSKey):
assert key.algorithm_name == "DSS"
elif isinstance(key, ECDSAKey):
assert key.algorithm_name == "ECDSA"
elif isinstance(key, Ed25519Key):
assert key.algorithm_name == "ED25519"
# TODO: corner case: AgentKey, whose .name can be cert-y (due to the
# value of the name field passed via agent protocol) and thus
# algorithm_name is eg "RSA-CERT" - keys loaded directly from disk will
# never look this way, even if they have a .public_blob attached.

class equality_and_hashing:
def same_key_is_equal_to_itself(self, keys):
assert keys.pkey == keys.pkey2

def same_key_same_hash(self, keys):
# NOTE: this isn't a great test due to hashseed randomization under
# Python 3 preventing use of static values, but it does still prove
# that __hash__ is implemented/doesn't explode & works across
# instances
assert hash(keys.pkey) == hash(keys.pkey2)

def keys_are_not_equal_to_other_types(self, keys):
for value in [None, True, ""]:
assert keys.pkey != value

class identifiers_classmethods:
def default_is_class_name_attribute(self):
# NOTE: not all classes _have_ this, only the ones that don't
# customize identifiers().
class MyKey(PKey):
name = "it me"
assert MyKey.identifiers() == ["it me"]

def rsa_is_all_combos_of_cert_and_sha_type(self):
assert RSAKey.identifiers() == [
"ssh-rsa",
"ssh-rsa-cert-v01@openssh.com",
"rsa-sha2-256",
"rsa-sha2-256-cert-v01@openssh.com",
"rsa-sha2-512",
"rsa-sha2-512-cert-v01@openssh.com",
]

def dss_is_protocol_name(self):
assert DSSKey.identifiers() == ["ssh-dss"]

def ed25519_is_protocol_name(self):
assert Ed25519Key.identifiers() == ["ssh-ed25519"]

def ecdsa_is_all_curve_names(self):
assert ECDSAKey.identifiers() == [
"ecdsa-sha2-nistp256",
"ecdsa-sha2-nistp384",
"ecdsa-sha2-nistp521",
]
45 changes: 0 additions & 45 deletions tests/test_pkey.py
Original file line number Diff line number Diff line change
Expand Up @@ -610,51 +610,6 @@ def test_ed25519_32bit_collision(self):
)
assert original != generated

# TODO: use keys fixture
def keys(self):
for key_class, filename in [
(RSAKey, "rsa.key"),
(DSSKey, "dss.key"),
(ECDSAKey, "ecdsa-256.key"),
(Ed25519Key, "ed25519.key"),
]:
key1 = key_class.from_private_key_file(_support(filename))
key2 = key_class.from_private_key_file(_support(filename))
yield key1, key2

def test_keys_are_comparable(self):
for key1, key2 in self.keys():
assert key1 == key2

def test_keys_are_not_equal_to_other(self):
for value in [None, True, ""]:
for key1, _ in self.keys():
assert key1 != value

def test_keys_are_hashable(self):
# NOTE: this isn't a great test due to hashseed randomization under
# Python 3 preventing use of static values, but it does still prove
# that __hash__ is implemented/doesn't explode & works across instances
for key1, key2 in self.keys():
assert hash(key1) == hash(key2)

# TODO: use keys fixture
def test_new_fingerprint(self):
# Assumes the RSA, DSS, ECDSA, Ed25519 order seen in 'def keys'.
fingerprints = [x.fingerprint for x, _ in self.keys()]
assert fingerprints == [
"SHA256:OhNL391d/beeFnxxg18AwWVYTAHww+D4djEE7Co0Yng",
"SHA256:uHwwykG099f4M4kfzvFpKCTino0/P03DRbAidpAmPm0",
"SHA256:BrQG04oNKUETjKCeL4ifkARASg3yxS/pUHl3wWM26Yg",
"SHA256:J6VESFdD3xSChn8y9PzWzeF+1tl892mOy2TqkMLO4ow",
]

# TODO: use keys fixture
def test_algorithm_property(self):
# Assumes the RSA, DSS, ECDSA, Ed25519 order seen in 'def keys'.
algorithms = [x.algorithm_name for x, _ in self.keys()]
assert algorithms == ["RSA", "DSS", "ECDSA", "ED25519"]

def test_ed25519_nonbytes_password(self):
# https://github.com/paramiko/paramiko/issues/1039
Ed25519Key.from_private_key_file(
Expand Down

0 comments on commit 6137821

Please sign in to comment.