summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJeff Forcier <jeff@bitprophet.org>2019-06-21 16:34:53 -0400
committerJeff Forcier <jeff@bitprophet.org>2019-06-21 16:34:53 -0400
commitb7af6829de1e4c4544334bca11fc777c6d350548 (patch)
treeffb8c28b51ae54e8afe1328c1b6d018341653a7d
parent0db807758757170b92d882ecbc43f1bdad36cce6 (diff)
parent26ae0c9b452b4fa395aa89a010e855cbe10780e6 (diff)
Merge branch '2.3' into 2.4
-rw-r--r--paramiko/ed25519key.py8
-rw-r--r--sites/www/changelog.rst5
-rw-r--r--tests/test_ed25519-funky-padding.key7
-rw-r--r--tests/test_ed25519-funky-padding_password.key8
-rw-r--r--tests/test_pkey.py8
5 files changed, 33 insertions, 3 deletions
diff --git a/paramiko/ed25519key.py b/paramiko/ed25519key.py
index 68ada224..6e0d3ccf 100644
--- a/paramiko/ed25519key.py
+++ b/paramiko/ed25519key.py
@@ -37,10 +37,12 @@ def unpad(data):
# really ought to be made constant time (possibly by upstreaming this logic
# into pyca/cryptography).
padding_length = six.indexbytes(data, -1)
- if padding_length > 16:
+ if 0x20 <= padding_length < 0x7f:
+ return data # no padding, last byte part comment (printable ascii)
+ if padding_length > 15:
raise SSHException("Invalid key")
- for i in range(1, padding_length + 1):
- if six.indexbytes(data, -i) != (padding_length - i + 1):
+ for i in range(padding_length):
+ if six.indexbytes(data, i - padding_length) != i + 1:
raise SSHException("Invalid key")
return data[:-padding_length]
diff --git a/sites/www/changelog.rst b/sites/www/changelog.rst
index 8a1eb76b..86419aa7 100644
--- a/sites/www/changelog.rst
+++ b/sites/www/changelog.rst
@@ -2,6 +2,11 @@
Changelog
=========
+- :bug:`1306` (via :issue:`1400`) Fix Ed25519 key handling so certain key
+ comment lengths don't cause ``SSHException("Invalid key")`` (this was
+ technically a bug in how padding, or lack thereof, is
+ calculated/interpreted). Thanks to ``@parke`` for the bug report & Pierce
+ Lopez for the patch.
- :support:`1378 backported` Add support for the modern (as of Python 3.3)
import location of ``MutableMapping`` (used in host key management) to avoid
the old location becoming deprecated in Python 3.8. Thanks to Josh Karpel for
diff --git a/tests/test_ed25519-funky-padding.key b/tests/test_ed25519-funky-padding.key
new file mode 100644
index 00000000..f178ca45
--- /dev/null
+++ b/tests/test_ed25519-funky-padding.key
@@ -0,0 +1,7 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
+QyNTUxOQAAACAHzPvYoDSkMVX52/CbA2M2aSBS7R0wt/9b2n5n+osNygAAAJAHZ1meB2dZ
+ngAAAAtzc2gtZWQyNTUxOQAAACAHzPvYoDSkMVX52/CbA2M2aSBS7R0wt/9b2n5n+osNyg
+AAAEAIyamvYUpzCovQuUtLhz+fwE4qYQo+rTuUVIX4fmTzMAfM+9igNKQxVfnb8JsDYzZp
+IFLtHTC3/1vafmf6iw3KAAAADW15IGNvbW1lbnQgaXM=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/tests/test_ed25519-funky-padding_password.key b/tests/test_ed25519-funky-padding_password.key
new file mode 100644
index 00000000..1b135d69
--- /dev/null
+++ b/tests/test_ed25519-funky-padding_password.key
@@ -0,0 +1,8 @@
+-----BEGIN OPENSSH PRIVATE KEY-----
+b3BlbnNzaC1rZXktdjEAAAAACmFlczI1Ni1jdHIAAAAGYmNyeXB0AAAAGAAAABDo3dGRlE
+xKndv32nDnz2mHAAAAEAAAAAEAAAAzAAAAC3NzaC1lZDI1NTE5AAAAIDcAVH8yDxoiqj0O
+rX3YTRMsnvJr+XdKJW16YQpxx8UvAAAAoI78IY+u8lYOzxAEO2N8qEVQH8b/m27yQhcSbK
+q1RvvuHmql3NoQvjYQe9/om4oqE+uesNRnoQGNplBHCeroD3ZcksXhLGDhwTh577NR+NQ+
+GNYAK5Ex7Va3Xgao5HUYtBQXlXbtzY1Q+71hcOlRVNnLUDvwShdCa9o6ETIOGcZl04fbzv
+Z3vC1C68G3+JMNFenAGYU+iQq0XENtpT6xAIU=
+-----END OPENSSH PRIVATE KEY-----
diff --git a/tests/test_pkey.py b/tests/test_pkey.py
index f7dabf26..749bb5f5 100644
--- a/tests/test_pkey.py
+++ b/tests/test_pkey.py
@@ -467,6 +467,14 @@ class KeyTest(unittest.TestCase):
)
self.assertNotEqual(key1.asbytes(), key2.asbytes())
+ def test_ed25519_funky_padding(self):
+ # Proves #1306 by just not exploding with 'Invalid key'.
+ Ed25519Key.from_private_key_file(_support("test_ed25519-funky-padding.key"))
+
+ def test_ed25519_funky_padding_with_passphrase(self):
+ # Proves #1306 by just not exploding with 'Invalid key'.
+ Ed25519Key.from_private_key_file(_support("test_ed25519-funky-padding_password.key"), b"asdf")
+
def test_ed25519_compare(self):
# verify that the private & public keys compare equal
key = Ed25519Key.from_private_key_file(_support("test_ed25519.key"))