summaryrefslogtreecommitdiff
path: root/paramiko/pkey.py
diff options
context:
space:
mode:
authorPierce Lopez <pierce.lopez@gmail.com>2019-12-05 18:06:10 -0500
committerPierce Lopez <pierce.lopez@gmail.com>2019-12-05 18:41:22 -0500
commit8b59b04c20609167c187b652016bdb7a942bb7a0 (patch)
treefab0e30eb64a2ee3ced155cd84ccc06d452a8575 /paramiko/pkey.py
parent5a4a0a213312e95f6b9c34b8728e016f2f2b31e1 (diff)
downloadparamiko-8b59b04c20609167c187b652016bdb7a942bb7a0.tar.gz
fix loading new openssh private key format when no padding
Diffstat (limited to 'paramiko/pkey.py')
-rw-r--r--paramiko/pkey.py36
1 files changed, 23 insertions, 13 deletions
diff --git a/paramiko/pkey.py b/paramiko/pkey.py
index c6beef51..3a07426f 100644
--- a/paramiko/pkey.py
+++ b/paramiko/pkey.py
@@ -27,6 +27,7 @@ from hashlib import md5
import re
import struct
+import six
import bcrypt
from cryptography.hazmat.backends import default_backend
@@ -35,18 +36,29 @@ from cryptography.hazmat.primitives.ciphers import algorithms, modes, Cipher
from paramiko import util
from paramiko.common import o600
-from paramiko.py3compat import (
- u,
- encodebytes,
- decodebytes,
- b,
- string_types,
- byte_ord,
-)
+from paramiko.py3compat import u, b, encodebytes, decodebytes, string_types
from paramiko.ssh_exception import SSHException, PasswordRequiredException
from paramiko.message import Message
+OPENSSH_AUTH_MAGIC = b"openssh-key-v1\x00"
+
+
+def _unpad_openssh(data):
+ # At the moment, this is only used for unpadding private keys on disk. This
+ # really ought to be made constant time (possibly by upstreaming this logic
+ # into pyca/cryptography).
+ padding_length = six.indexbytes(data, -1)
+ 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(padding_length):
+ if six.indexbytes(data, i - padding_length) != i + 1:
+ raise SSHException("Invalid key")
+ return data[:-padding_length]
+
+
class PKey(object):
"""
Base class for public keys.
@@ -395,8 +407,8 @@ class PKey(object):
raise SSHException("base64 decoding error: {}".format(e))
# read data struct
- auth_magic = data[:14]
- if auth_magic != b("openssh-key-v1"):
+ auth_magic = data[:15]
+ if auth_magic != OPENSSH_AUTH_MAGIC:
raise SSHException("unexpected OpenSSH key header encountered")
cstruct = self._uint32_cstruct_unpack(data[15:], "sssur")
@@ -466,9 +478,7 @@ class PKey(object):
"OpenSSH private key file checkints do not match"
)
- # Remove padding
- padlen = byte_ord(keydata[len(keydata) - 1])
- return keydata[: len(keydata) - padlen]
+ return _unpad_openssh(keydata)
def _uint32_cstruct_unpack(self, data, strformat):
"""