diff options
-rw-r--r-- | paramiko/ed25519key.py | 24 | ||||
-rw-r--r-- | paramiko/pkey.py | 36 |
2 files changed, 25 insertions, 35 deletions
diff --git a/paramiko/ed25519key.py b/paramiko/ed25519key.py index 96cff7d0..b584f521 100644 --- a/paramiko/ed25519key.py +++ b/paramiko/ed25519key.py @@ -21,32 +21,12 @@ from cryptography.hazmat.primitives.ciphers import Cipher import nacl.signing -import six - from paramiko.message import Message -from paramiko.pkey import PKey +from paramiko.pkey import PKey, OPENSSH_AUTH_MAGIC, _unpad_openssh from paramiko.py3compat import b from paramiko.ssh_exception import SSHException, PasswordRequiredException -OPENSSH_AUTH_MAGIC = b"openssh-key-v1\x00" - - -def unpad(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 Ed25519Key(PKey): """ Representation of an `Ed25519 <https://ed25519.cr.yp.to/>`_ key. @@ -155,7 +135,7 @@ class Ed25519Key(PKey): decryptor.update(private_ciphertext) + decryptor.finalize() ) - message = Message(unpad(private_data)) + message = Message(_unpad_openssh(private_data)) if message.get_int() != message.get_int(): raise SSHException("Invalid key") 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): """ |