summaryrefslogtreecommitdiffhomepage
path: root/tests/test_pkey.py
diff options
context:
space:
mode:
authorJeff Forcier <jeff@bitprophet.org>2017-06-06 12:31:57 -0700
committerJeff Forcier <jeff@bitprophet.org>2017-06-06 12:31:57 -0700
commita2da21d46bb9a441dbb8da570262bb424e1f9450 (patch)
tree8e1c7bdd402fb640f75b061bc2051f5fe6eba676 /tests/test_pkey.py
parent79fcbdad812cc3be39afbf8375c11e0581eeb86e (diff)
parentd285b80ecb6102b0ad501b74d02e04d61e8ec632 (diff)
Merge branch '2.0' into 667-int
Diffstat (limited to 'tests/test_pkey.py')
-rw-r--r--tests/test_pkey.py199
1 files changed, 182 insertions, 17 deletions
diff --git a/tests/test_pkey.py b/tests/test_pkey.py
index ec128140..24d78c3e 100644
--- a/tests/test_pkey.py
+++ b/tests/test_pkey.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
# Copyright (C) 2003-2009 Robey Pointer <robeypointer@gmail.com>
#
# This file is part of paramiko.
@@ -24,20 +25,25 @@ import unittest
import os
from binascii import hexlify
from hashlib import md5
+import base64
from paramiko import RSAKey, DSSKey, ECDSAKey, Message, util
-from paramiko.py3compat import StringIO, byte_chr, b, bytes
+from paramiko.py3compat import StringIO, byte_chr, b, bytes, PY2
from tests.util import test_path
# from openssh's ssh-keygen
PUB_RSA = 'ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAIEA049W6geFpmsljTwfvI1UmKWWJPNFI74+vNKTk4dmzkQY2yAMs6FhlvhlI8ysU4oj71ZsRYMecHbBbxdN79+JRFVYTKaLqjwGENeTd+yv4q+V2PvZv3fLnzApI3l7EJCqhWwJUHJ1jAkZzqDx0tyOL4uoZpww3nmE0kb3y21tH4c='
PUB_DSS = 'ssh-dss AAAAB3NzaC1kc3MAAACBAOeBpgNnfRzr/twmAQRu2XwWAp3CFtrVnug6s6fgwj/oLjYbVtjAy6pl/h0EKCWx2rf1IetyNsTxWrniA9I6HeDj65X1FyDkg6g8tvCnaNB8Xp/UUhuzHuGsMIipRxBxw9LF608EqZcj1E3ytktoW5B5OcjrkEoz3xG7C+rpIjYvAAAAFQDwz4UnmsGiSNu5iqjn3uTzwUpshwAAAIEAkxfFeY8P2wZpDjX0MimZl5wkoFQDL25cPzGBuB4OnB8NoUk/yjAHIIpEShw8V+LzouMK5CTJQo5+Ngw3qIch/WgRmMHy4kBq1SsXMjQCte1So6HBMvBPIW5SiMTmjCfZZiw4AYHK+B/JaOwaG9yRg2Ejg4Ok10+XFDxlqZo8Y+wAAACARmR7CCPjodxASvRbIyzaVpZoJ/Z6x7dAumV+ysrV1BVYd0lYukmnjO1kKBWApqpH1ve9XDQYN8zgxM4b16L21kpoWQnZtXrY3GZ4/it9kUgyB7+NwacIBlXa8cMDL7Q/69o0d54U0X/NeX5QxuYR6OMJlrkQB7oiW/P/1mwjQgE='
-PUB_ECDSA = 'ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJSPZm3ZWkvk/Zx8WP+fZRZ5/NBBHnGQwR6uIC6XHGPDIHuWUzIjAwA0bzqkOUffEsbLe+uQgKl5kbc/L8KA/eo='
+PUB_ECDSA_256 = 'ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJSPZm3ZWkvk/Zx8WP+fZRZ5/NBBHnGQwR6uIC6XHGPDIHuWUzIjAwA0bzqkOUffEsbLe+uQgKl5kbc/L8KA/eo='
+PUB_ECDSA_384 = 'ecdsa-sha2-nistp384 AAAAE2VjZHNhLXNoYTItbmlzdHAzODQAAAAIbmlzdHAzODQAAABhBBbGibQLW9AAZiGN2hEQxWYYoFaWKwN3PKSaDJSMqmIn1Z9sgRUuw8Y/w502OGvXL/wFk0i2z50l3pWZjD7gfMH7gX5TUiCzwrQkS+Hn1U2S9aF5WJp0NcIzYxXw2r4M2A=='
+PUB_ECDSA_521 = 'ecdsa-sha2-nistp521 AAAAE2VjZHNhLXNoYTItbmlzdHA1MjEAAAAIbmlzdHA1MjEAAACFBACaOaFLZGuxa5AW16qj6VLypFbLrEWrt9AZUloCMefxO8bNLjK/O5g0rAVasar1TnyHE9qj4NwzANZASWjQNbc4MAG8vzqezFwLIn/kNyNTsXNfqEko9OgHZknlj2Z79dwTJcRAL4QLcT5aND0EHZLB2fAUDXiWIb2j4rg1mwPlBMiBXA=='
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'
-FINGER_ECDSA = '256 25:19:eb:55:e6:a1:47:ff:4f:38:d2:75:6f:a5:d5:60'
+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'
RSA_PRIVATE_OUT = """\
@@ -73,7 +79,7 @@ h9pT9XHqn+1rZ4bK+QGA
-----END DSA PRIVATE KEY-----
"""
-ECDSA_PRIVATE_OUT = """\
+ECDSA_PRIVATE_OUT_256 = """\
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIKB6ty3yVyKEnfF/zprx0qwC76MsMlHY4HXCnqho2eKioAoGCCqGSM49
AwEHoUQDQgAElI9mbdlaS+T9nHxY/59lFnn80EEecZDBHq4gLpccY8Mge5ZTMiMD
@@ -81,8 +87,30 @@ ADRvOqQ5R98Sxst765CAqXmRtz8vwoD96g==
-----END EC PRIVATE KEY-----
"""
+ECDSA_PRIVATE_OUT_384 = """\
+-----BEGIN EC PRIVATE KEY-----
+MIGkAgEBBDBDdO8IXvlLJgM7+sNtPl7tI7FM5kzuEUEEPRjXIPQM7mISciwJPBt+
+y43EuG8nL4mgBwYFK4EEACKhZANiAAQWxom0C1vQAGYhjdoREMVmGKBWlisDdzyk
+mgyUjKpiJ9WfbIEVLsPGP8OdNjhr1y/8BZNIts+dJd6VmYw+4HzB+4F+U1Igs8K0
+JEvh59VNkvWheViadDXCM2MV8Nq+DNg=
+-----END EC PRIVATE KEY-----
+"""
+
+ECDSA_PRIVATE_OUT_521 = """\
+-----BEGIN EC PRIVATE KEY-----
+MIHcAgEBBEIAprQtAS3OF6iVUkT8IowTHWicHzShGgk86EtuEXvfQnhZFKsWm6Jo
+iqAr1yEaiuI9LfB3Xs8cjuhgEEfbduYr/f6gBwYFK4EEACOhgYkDgYYABACaOaFL
+ZGuxa5AW16qj6VLypFbLrEWrt9AZUloCMefxO8bNLjK/O5g0rAVasar1TnyHE9qj
+4NwzANZASWjQNbc4MAG8vzqezFwLIn/kNyNTsXNfqEko9OgHZknlj2Z79dwTJcRA
+L4QLcT5aND0EHZLB2fAUDXiWIb2j4rg1mwPlBMiBXA==
+-----END EC PRIVATE KEY-----
+"""
+
x1234 = b'\x01\x02\x03\x04'
+TEST_KEY_BYTESTR_2 = '\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01#\x00\x00\x00\x81\x00\xd3\x8fV\xea\x07\x85\xa6k%\x8d<\x1f\xbc\x8dT\x98\xa5\x96$\xf3E#\xbe>\xbc\xd2\x93\x93\x87f\xceD\x18\xdb \x0c\xb3\xa1a\x96\xf8e#\xcc\xacS\x8a#\xefVlE\x83\x1epv\xc1o\x17M\xef\xdf\x89DUXL\xa6\x8b\xaa<\x06\x10\xd7\x93w\xec\xaf\xe2\xaf\x95\xd8\xfb\xd9\xbfw\xcb\x9f0)#y{\x10\x90\xaa\x85l\tPru\x8c\t\x19\xce\xa0\xf1\xd2\xdc\x8e/\x8b\xa8f\x9c0\xdey\x84\xd2F\xf7\xcbmm\x1f\x87'
+TEST_KEY_BYTESTR_3 = '\x00\x00\x00\x07ssh-rsa\x00\x00\x00\x01#\x00\x00\x00\x00ӏV\x07k%<\x1fT$E#>ғfD\x18 \x0cae#̬S#VlE\x1epvo\x17M߉DUXL<\x06\x10דw\u2bd5ٿw˟0)#y{\x10l\tPru\t\x19Π\u070e/f0yFmm\x1f'
+
class KeyTest (unittest.TestCase):
@@ -205,43 +233,72 @@ class KeyTest (unittest.TestCase):
msg.rewind()
self.assertTrue(key.verify_ssh_sig(b'jerri blank', msg))
- def test_10_load_ecdsa(self):
- key = ECDSAKey.from_private_key_file(test_path('test_ecdsa.key'))
+ def test_C_generate_ecdsa(self):
+ key = ECDSAKey.generate()
+ msg = key.sign_ssh_data(b'jerri blank')
+ msg.rewind()
+ self.assertTrue(key.verify_ssh_sig(b'jerri blank', msg))
+ self.assertEqual(key.get_bits(), 256)
+ self.assertEqual(key.get_name(), 'ecdsa-sha2-nistp256')
+
+ key = ECDSAKey.generate(bits=256)
+ msg = key.sign_ssh_data(b'jerri blank')
+ msg.rewind()
+ self.assertTrue(key.verify_ssh_sig(b'jerri blank', msg))
+ self.assertEqual(key.get_bits(), 256)
+ self.assertEqual(key.get_name(), 'ecdsa-sha2-nistp256')
+
+ key = ECDSAKey.generate(bits=384)
+ msg = key.sign_ssh_data(b'jerri blank')
+ msg.rewind()
+ self.assertTrue(key.verify_ssh_sig(b'jerri blank', msg))
+ self.assertEqual(key.get_bits(), 384)
+ self.assertEqual(key.get_name(), 'ecdsa-sha2-nistp384')
+
+ key = ECDSAKey.generate(bits=521)
+ msg = key.sign_ssh_data(b'jerri blank')
+ msg.rewind()
+ self.assertTrue(key.verify_ssh_sig(b'jerri blank', msg))
+ self.assertEqual(key.get_bits(), 521)
+ self.assertEqual(key.get_name(), 'ecdsa-sha2-nistp521')
+
+ def test_10_load_ecdsa_256(self):
+ key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_256.key'))
self.assertEqual('ecdsa-sha2-nistp256', key.get_name())
- exp_ecdsa = b(FINGER_ECDSA.split()[1].replace(':', ''))
+ exp_ecdsa = b(FINGER_ECDSA_256.split()[1].replace(':', ''))
my_ecdsa = hexlify(key.get_fingerprint())
self.assertEqual(exp_ecdsa, my_ecdsa)
- self.assertEqual(PUB_ECDSA.split()[1], key.get_base64())
+ self.assertEqual(PUB_ECDSA_256.split()[1], key.get_base64())
self.assertEqual(256, key.get_bits())
s = StringIO()
key.write_private_key(s)
- self.assertEqual(ECDSA_PRIVATE_OUT, s.getvalue())
+ self.assertEqual(ECDSA_PRIVATE_OUT_256, s.getvalue())
s.seek(0)
key2 = ECDSAKey.from_private_key(s)
self.assertEqual(key, key2)
- def test_11_load_ecdsa_password(self):
- key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_password.key'), b'television')
+ def test_11_load_ecdsa_password_256(self):
+ key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_password_256.key'), b'television')
self.assertEqual('ecdsa-sha2-nistp256', key.get_name())
- exp_ecdsa = b(FINGER_ECDSA.split()[1].replace(':', ''))
+ exp_ecdsa = b(FINGER_ECDSA_256.split()[1].replace(':', ''))
my_ecdsa = hexlify(key.get_fingerprint())
self.assertEqual(exp_ecdsa, my_ecdsa)
- self.assertEqual(PUB_ECDSA.split()[1], key.get_base64())
+ self.assertEqual(PUB_ECDSA_256.split()[1], key.get_base64())
self.assertEqual(256, key.get_bits())
- def test_12_compare_ecdsa(self):
+ def test_12_compare_ecdsa_256(self):
# verify that the private & public keys compare equal
- key = ECDSAKey.from_private_key_file(test_path('test_ecdsa.key'))
+ key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_256.key'))
self.assertEqual(key, key)
pub = ECDSAKey(data=key.asbytes())
self.assertTrue(key.can_sign())
self.assertTrue(not pub.can_sign())
self.assertEqual(key, pub)
- def test_13_sign_ecdsa(self):
+ def test_13_sign_ecdsa_256(self):
# verify that the rsa private key can sign and verify
- key = ECDSAKey.from_private_key_file(test_path('test_ecdsa.key'))
+ key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_256.key'))
msg = key.sign_ssh_data(b'ice weasels')
self.assertTrue(type(msg) is Message)
msg.rewind()
@@ -255,6 +312,109 @@ class KeyTest (unittest.TestCase):
pub = ECDSAKey(data=key.asbytes())
self.assertTrue(pub.verify_ssh_sig(b'ice weasels', msg))
+ def test_14_load_ecdsa_384(self):
+ key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_384.key'))
+ self.assertEqual('ecdsa-sha2-nistp384', key.get_name())
+ exp_ecdsa = b(FINGER_ECDSA_384.split()[1].replace(':', ''))
+ my_ecdsa = hexlify(key.get_fingerprint())
+ self.assertEqual(exp_ecdsa, my_ecdsa)
+ self.assertEqual(PUB_ECDSA_384.split()[1], key.get_base64())
+ self.assertEqual(384, key.get_bits())
+
+ s = StringIO()
+ key.write_private_key(s)
+ self.assertEqual(ECDSA_PRIVATE_OUT_384, s.getvalue())
+ s.seek(0)
+ key2 = ECDSAKey.from_private_key(s)
+ self.assertEqual(key, key2)
+
+ def test_15_load_ecdsa_password_384(self):
+ key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_password_384.key'), b'television')
+ self.assertEqual('ecdsa-sha2-nistp384', key.get_name())
+ exp_ecdsa = b(FINGER_ECDSA_384.split()[1].replace(':', ''))
+ my_ecdsa = hexlify(key.get_fingerprint())
+ self.assertEqual(exp_ecdsa, my_ecdsa)
+ self.assertEqual(PUB_ECDSA_384.split()[1], key.get_base64())
+ self.assertEqual(384, key.get_bits())
+
+ def test_16_compare_ecdsa_384(self):
+ # verify that the private & public keys compare equal
+ key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_384.key'))
+ self.assertEqual(key, key)
+ pub = ECDSAKey(data=key.asbytes())
+ self.assertTrue(key.can_sign())
+ self.assertTrue(not pub.can_sign())
+ self.assertEqual(key, pub)
+
+ def test_17_sign_ecdsa_384(self):
+ # verify that the rsa private key can sign and verify
+ key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_384.key'))
+ msg = key.sign_ssh_data(b'ice weasels')
+ self.assertTrue(type(msg) is Message)
+ msg.rewind()
+ self.assertEqual('ecdsa-sha2-nistp384', msg.get_text())
+ # ECDSA signatures, like DSS signatures, tend to be different
+ # each time, so we can't compare against a "known correct"
+ # signature.
+ # Even the length of the signature can change.
+
+ msg.rewind()
+ pub = ECDSAKey(data=key.asbytes())
+ self.assertTrue(pub.verify_ssh_sig(b'ice weasels', msg))
+
+ def test_18_load_ecdsa_521(self):
+ key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_521.key'))
+ self.assertEqual('ecdsa-sha2-nistp521', key.get_name())
+ exp_ecdsa = b(FINGER_ECDSA_521.split()[1].replace(':', ''))
+ my_ecdsa = hexlify(key.get_fingerprint())
+ self.assertEqual(exp_ecdsa, my_ecdsa)
+ self.assertEqual(PUB_ECDSA_521.split()[1], key.get_base64())
+ self.assertEqual(521, key.get_bits())
+
+ s = StringIO()
+ key.write_private_key(s)
+ # Different versions of OpenSSL (SSLeay versions 0x1000100f and
+ # 0x1000207f for instance) use different apparently valid (as far as
+ # ssh-keygen is concerned) padding. So we can't check the actual value
+ # of the pem encoded key.
+ s.seek(0)
+ key2 = ECDSAKey.from_private_key(s)
+ self.assertEqual(key, key2)
+
+ def test_19_load_ecdsa_password_521(self):
+ key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_password_521.key'), b'television')
+ self.assertEqual('ecdsa-sha2-nistp521', key.get_name())
+ exp_ecdsa = b(FINGER_ECDSA_521.split()[1].replace(':', ''))
+ my_ecdsa = hexlify(key.get_fingerprint())
+ self.assertEqual(exp_ecdsa, my_ecdsa)
+ self.assertEqual(PUB_ECDSA_521.split()[1], key.get_base64())
+ self.assertEqual(521, key.get_bits())
+
+ def test_20_compare_ecdsa_521(self):
+ # verify that the private & public keys compare equal
+ key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_521.key'))
+ self.assertEqual(key, key)
+ pub = ECDSAKey(data=key.asbytes())
+ self.assertTrue(key.can_sign())
+ self.assertTrue(not pub.can_sign())
+ self.assertEqual(key, pub)
+
+ def test_21_sign_ecdsa_521(self):
+ # verify that the rsa private key can sign and verify
+ key = ECDSAKey.from_private_key_file(test_path('test_ecdsa_521.key'))
+ msg = key.sign_ssh_data(b'ice weasels')
+ self.assertTrue(type(msg) is Message)
+ msg.rewind()
+ self.assertEqual('ecdsa-sha2-nistp521', msg.get_text())
+ # ECDSA signatures, like DSS signatures, tend to be different
+ # each time, so we can't compare against a "known correct"
+ # signature.
+ # Even the length of the signature can change.
+
+ msg.rewind()
+ pub = ECDSAKey(data=key.asbytes())
+ self.assertTrue(pub.verify_ssh_sig(b'ice weasels', msg))
+
def test_salt_size(self):
# Read an existing encrypted private key
file_ = test_path('test_rsa_password.key')
@@ -271,3 +431,8 @@ class KeyTest (unittest.TestCase):
self.assertEqual(key, key2)
finally:
os.remove(newfile)
+
+ def test_stringification(self):
+ key = RSAKey.from_private_key_file(test_path('test_rsa.key'))
+ comparable = TEST_KEY_BYTESTR_2 if PY2 else TEST_KEY_BYTESTR_3
+ self.assertEqual(str(key), comparable)