diff options
Diffstat (limited to 'tests/test_pkey.py')
-rw-r--r-- | tests/test_pkey.py | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/tests/test_pkey.py b/tests/test_pkey.py index 0e60126a..18c27bbe 100644 --- a/tests/test_pkey.py +++ b/tests/test_pkey.py @@ -29,6 +29,9 @@ from hashlib import md5 from paramiko import RSAKey, DSSKey, ECDSAKey, Ed25519Key, Message, util from paramiko.py3compat import StringIO, byte_chr, b, bytes, PY2 +from cryptography.hazmat.primitives.asymmetric.rsa import RSAPrivateNumbers +from mock import patch + from .util import _support @@ -38,6 +41,11 @@ PUB_DSS = "ssh-dss AAAAB3NzaC1kc3MAAACBAOeBpgNnfRzr/twmAQRu2XwWAp3CFtrVnug6s6fgw PUB_ECDSA_256 = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJSPZm3ZWkvk/Zx8WP+fZRZ5/NBBHnGQwR6uIC6XHGPDIHuWUzIjAwA0bzqkOUffEsbLe+uQgKl5kbc/L8KA/eo=" # noqa PUB_ECDSA_384 = "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBBbGibQLW9AAZiGN2hEQxWYYoFaWKwN3PKSaDJSMqmIn1Z9sgRUuw8Y/w502OGvXL/wFk0i2z50l3pWZjD7gfMH7gX5TUiCzwrQkS+Hn1U2S9aF5WJp0NcIzYxXw2r4M2A==" # noqa PUB_ECDSA_521 = "ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACaOaFLZGuxa5AW16qj6VLypFbLrEWrt9AZUloCMefxO8bNLjK/O5g0rAVasar1TnyHE9qj4NwzANZASWjQNbc4MAG8vzqezFwLIn/kNyNTsXNfqEko9OgHZknlj2Z79dwTJcRAL4QLcT5aND0EHZLB2fAUDXiWIb2j4rg1mwPlBMiBXA==" # noqa +PUB_RSA_2K_OPENSSH = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDF+Dpr54DX0WdeTDpNAMdkCWEkl3OXtNgf58qlN1gX572OLBqLf0zT4bHstUEpU3piazph/rSWcUMuBoD46tZ6jiH7H9b9Pem2eYQWaELDDkM+v9BMbEy5rMbFRLol5OtEvPFqneyEAanPOgvd8t3yyhSev9QVusakzJ8j8LGgrA8huYZ+Srnw0shEWLG70KUKCh3rG0QIvA8nfhtUOisr2Gp+F0YxMGb5gwBlQYAYE5l6u1SjZ7hNjyNosjK+wRBFgFFBYVpkZKJgWoK9w4ijFyzMZTucnZMqKOKAjIJvHfKBf2/cEfYxSq1EndqTqjYsd9T7/s2vcn1OH5a0wkER" # noqa +RSA_2K_OPENSSH_P = 161773687847617758886803946572654778625119997081005961935077336594287351354258259920334554906235187683459069634729972458348855793639393524799865799559575414247668746919721196359908321800753913350455861871582087986355637886875933045224711827701526739934602161222599672381604211130651397331775901258858869418853 # noqa +RSA_2K_OPENSSH_Q = 154483416325630619558401349033571772244816915504195060221073502923720741119664820208064202825686848103224453777955988437823797692957091438442833606009978046057345917301441832647551208158342812551003395417862260727795454409459089912659057393394458150862012620127030757893820711157099494238156383382454310199869 # noqa +PUB_DSS_1K_OPENSSH = "ssh-dss AAAAB3NzaC1kc3MAAACBAL8XEx7F9xuwBNles+vWpNF+YcofrBhjX1r5QhpBe0eoYWLHRcroN6lxwCdGYRfgOoRjTncBiixQX/uUxAY96zDh3ir492s2BcJt4ihvNn/AY0I0OTuX/2IwGk9CGzafjaeZNVYxMa8lcVt0hSOTjkPQ7gVuk6bJzMInvie+VWKLAAAAFQDUgYdY+rhR0SkKbC09BS/SIHcB+wAAAIB44+4zpCNcd0CGvZlowH99zyPX8uxQtmTLQFuR2O8O0FgVVuCdDgD0D9W8CLOp32oatpM0jyyN89EdvSWzjHzZJ+L6H1FtZps7uhpDFWHdva1R25vyGecLMUuXjo5t/D7oCDih+HwHoSAxoi0QvsPd8/qqHQVznNJKtR6thUpXEwAAAIAG4DCBjbgTTgpBw0egRkJwBSz0oTt+1IcapNU2jA6N8urMSk9YXHEQHKN68BAF3YJ59q2Ujv3LOXmBqGd1T+kzwUszfMlgzq8MMu19Yfzse6AIK1Agn1Vj6F7YXLsXDN+T4KszX5+FJa7t/Zsp3nALWy6l0f4WKivEF5Y2QpEFcQ==" # noqa +PUB_EC_384_OPENSSH = "ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBIch5LXTq/L/TWsTGG6dIktxD8DIMh7EfvoRmWsks6CuNDTvFvbQNtY4QO1mn5OXegHbS0M5DPIS++wpKGFP3suDEH08O35vZQasLNrL0tO2jyyEnzB2ZEx3PPYci811yg==" # noqa FINGER_RSA = "1024 60:73:38:44:cb:51:86:65:7f:de:da:a2:2b:5a:57:d5" FINGER_DSS = "1024 44:78:f0:b9:a2:3c:c5:18:20:09:ff:75:5b:c1:d2:6c" @@ -45,6 +53,9 @@ FINGER_ECDSA_256 = "256 25:19:eb:55:e6:a1:47:ff:4f:38:d2:75:6f:a5:d5:60" FINGER_ECDSA_384 = "384 c1:8d:a0:59:09:47:41:8e:a8:a6:07:01:29:23:b4:65" FINGER_ECDSA_521 = "521 44:58:22:52:12:33:16:0e:ce:0e:be:2c:7c:7e:cc:1e" SIGNED_RSA = "20:d7:8a:31:21:cb:f7:92:12:f2:a4:89:37:f5:78:af:e6:16:b6:25:b9:97:3d:a2:cd:5f:ca:20:21:73:4c:ad:34:73:8f:20:77:28:e2:94:15:08:d8:91:40:7a:85:83:bf:18:37:95:dc:54:1a:9b:88:29:6c:73:ca:38:b4:04:f1:56:b9:f2:42:9d:52:1b:29:29:b4:4f:fd:c9:2d:af:47:d2:40:76:30:f3:63:45:0c:d9:1d:43:86:0f:1c:70:e2:93:12:34:f3:ac:c5:0a:2f:14:50:66:59:f1:88:ee:c1:4a:e9:d1:9c:4e:46:f0:0e:47:6f:38:74:f1:44:a8" # noqa +FINGER_RSA_2K_OPENSSH = "2048 68:d1:72:01:bf:c0:0c:66:97:78:df:ce:75:74:46:d6" +FINGER_DSS_1K_OPENSSH = "1024 cf:1d:eb:d7:61:d3:12:94:c6:c0:c6:54:35:35:b0:82" +FINGER_EC_384_OPENSSH = "384 72:14:df:c1:9a:c3:e6:0e:11:29:d6:32:18:7b:ea:9b" RSA_PRIVATE_OUT = """\ -----BEGIN RSA PRIVATE KEY----- @@ -437,6 +448,54 @@ class KeyTest(unittest.TestCase): pub = ECDSAKey(data=key.asbytes()) self.assertTrue(pub.verify_ssh_sig(b"ice weasels", msg)) + def test_load_openssh_format_RSA_key(self): + key = RSAKey.from_private_key_file( + _support("test_rsa_openssh.key"), b"television" + ) + self.assertEqual("ssh-rsa", key.get_name()) + self.assertEqual(PUB_RSA_2K_OPENSSH.split()[1], key.get_base64()) + self.assertEqual(2048, key.get_bits()) + exp_rsa = b(FINGER_RSA_2K_OPENSSH.split()[1].replace(":", "")) + my_rsa = hexlify(key.get_fingerprint()) + self.assertEqual(exp_rsa, my_rsa) + + def test_loading_openssh_RSA_keys_uses_correct_p_q(self): + # Re #1723 - not the most elegant test but given how deep it is... + with patch( + "paramiko.rsakey.rsa.RSAPrivateNumbers", wraps=RSAPrivateNumbers + ) as spy: + # Load key + RSAKey.from_private_key_file( + _support("test_rsa_openssh.key"), b"television" + ) + # Ensure spy saw the correct P and Q values as derived from + # hardcoded test private key value + kwargs = spy.call_args[1] + assert kwargs["p"] == RSA_2K_OPENSSH_P + assert kwargs["q"] == RSA_2K_OPENSSH_Q + + def test_load_openssh_format_DSS_key(self): + key = DSSKey.from_private_key_file( + _support("test_dss_openssh.key"), b"television" + ) + self.assertEqual("ssh-dss", key.get_name()) + self.assertEqual(PUB_DSS_1K_OPENSSH.split()[1], key.get_base64()) + self.assertEqual(1024, key.get_bits()) + exp_rsa = b(FINGER_DSS_1K_OPENSSH.split()[1].replace(":", "")) + my_rsa = hexlify(key.get_fingerprint()) + self.assertEqual(exp_rsa, my_rsa) + + def test_load_openssh_format_EC_key(self): + key = ECDSAKey.from_private_key_file( + _support("test_ecdsa_384_openssh.key"), b"television" + ) + self.assertEqual("ecdsa-sha2-nistp384", key.get_name()) + self.assertEqual(PUB_EC_384_OPENSSH.split()[1], key.get_base64()) + self.assertEqual(384, key.get_bits()) + exp_fp = b(FINGER_EC_384_OPENSSH.split()[1].replace(":", "")) + my_fp = hexlify(key.get_fingerprint()) + self.assertEqual(exp_fp, my_fp) + def test_salt_size(self): # Read an existing encrypted private key file_ = _support("test_rsa_password.key") @@ -455,6 +514,10 @@ class KeyTest(unittest.TestCase): finally: os.remove(newfile) + def test_load_openssh_format_RSA_nopad(self): + # check just not exploding with 'Invalid key' + RSAKey.from_private_key_file(_support("test_rsa_openssh_nopad.key")) + def test_stringification(self): key = RSAKey.from_private_key_file(_support("test_rsa.key")) comparable = TEST_KEY_BYTESTR_2 if PY2 else TEST_KEY_BYTESTR_3 |