enforce password must be bytes when loading PEM/DER asymmetric keys (#3383)

* enforce password must be bytes when loading PEM/DER asymmetric keys

Previously we were using an ffi.buffer on the Python string, which was
allowing text implicitly, but our documentation explicitly requires
bytes.

* add changelog entry
This commit is contained in:
Paul Kehrer 2017-02-09 05:55:34 +08:00 committed by Alex Gaynor
parent 0e6a129724
commit 7a13085afc
4 changed files with 47 additions and 2 deletions

View file

@ -15,11 +15,15 @@ Changelog
:meth:`~cryptography.hazmat.primitives.asymmetric.dh.DHPrivateKeyWithSerialization.private_bytes`
to
:class:`~cryptography.hazmat.primitives.asymmetric.dh.DHPrivateKeyWithSerialization`.
* Added
:meth:`~cryptography.hazmat.primitives.asymmetric.dh.DHPublicKeyWithSerialization.public_bytes`
to
:class:`~cryptography.hazmat.primitives.asymmetric.dh.DHPublicKeyWithSerialization`.
* :func:`~cryptography.hazmat.primitives.serialization.load_pem_private_key`
and
:func:`~cryptography.hazmat.primitives.serialization.load_der_private_key`
now require that ``password`` must be bytes if provided. Previously this
was documented but not enforced.
1.7.2 - 2017-01-27
~~~~~~~~~~~~~~~~~~

View file

@ -66,6 +66,8 @@ _MemoryBIO = collections.namedtuple("_MemoryBIO", ["bio", "char_ptr"])
class _PasswordUserdata(object):
def __init__(self, password):
if password is not None and not isinstance(password, bytes):
raise TypeError("Password must be bytes")
self.password = password
self.called = 0
self.exception = None

View file

@ -523,7 +523,7 @@ class TestOpenSSLSerializationWithOpenSSL(object):
backend._evp_pkey_to_public_key(key)
def test_very_long_pem_serialization_password(self):
password = "x" * 1024
password = b"x" * 1024
with pytest.raises(ValueError):
load_vectors_from_file(

View file

@ -77,6 +77,26 @@ class TestDERSerialization(object):
assert isinstance(key, dsa.DSAPrivateKey)
_check_dsa_private_numbers(key.private_numbers())
@pytest.mark.parametrize(
"key_path",
[
["DER_Serialization", "enc-rsa-pkcs8.der"],
]
)
@pytest.mark.requires_backend_interface(interface=RSABackend)
def test_password_not_bytes(self, key_path, backend):
key_file = os.path.join("asymmetric", *key_path)
password = u"this password is not bytes"
with pytest.raises(TypeError):
load_vectors_from_file(
key_file,
lambda derfile: load_der_private_key(
derfile.read(), password, backend
),
mode="rb"
)
@pytest.mark.parametrize(
("key_path", "password"),
[
@ -492,6 +512,25 @@ class TestPEMSerialization(object):
)
)
@pytest.mark.parametrize(
"key_path",
[
["Traditional_OpenSSL_Serialization", "testrsa-encrypted.pem"],
["PKCS8", "enc-rsa-pkcs8.pem"]
]
)
def test_password_not_bytes(self, key_path, backend):
key_file = os.path.join("asymmetric", *key_path)
password = u"this password is not bytes"
with pytest.raises(TypeError):
load_vectors_from_file(
key_file,
lambda pemfile: load_pem_private_key(
pemfile.read().encode(), password, backend
)
)
@pytest.mark.parametrize(
"key_path",
[