diff options
author | Pierce Lopez <pierce.lopez@gmail.com> | 2019-12-05 18:06:10 -0500 |
---|---|---|
committer | Pierce Lopez <pierce.lopez@gmail.com> | 2019-12-05 18:41:22 -0500 |
commit | 8b59b04c20609167c187b652016bdb7a942bb7a0 (patch) | |
tree | fab0e30eb64a2ee3ced155cd84ccc06d452a8575 /paramiko/pkey.py | |
parent | 5a4a0a213312e95f6b9c34b8728e016f2f2b31e1 (diff) | |
download | paramiko-8b59b04c20609167c187b652016bdb7a942bb7a0.tar.gz |
fix loading new openssh private key format when no padding
Diffstat (limited to 'paramiko/pkey.py')
-rw-r--r-- | paramiko/pkey.py | 36 |
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): """ |