From f83e25c81bb186ed8a96d4a569d5068546a24349 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 21 Feb 2015 18:34:00 -0600 Subject: Support for traditional OpenSSL and PKCS8 RSA private key serialization --- CHANGELOG.rst | 8 ++ docs/hazmat/primitives/asymmetric/rsa.rst | 62 ++++++++++++++ .../hazmat/primitives/asymmetric/serialization.rst | 70 ++++++++++++++- docs/spelling_wordlist.txt | 2 + src/cryptography/hazmat/backends/openssl/rsa.py | 61 ++++++++++++- .../hazmat/primitives/asymmetric/rsa.py | 12 ++- .../hazmat/primitives/serialization.py | 47 ++++++++++ src/cryptography/utils.py | 1 + tests/hazmat/backends/test_openssl.py | 29 ++++++- tests/hazmat/primitives/test_rsa.py | 99 +++++++++++++++++++++- tests/hazmat/primitives/test_serialization.py | 29 ++++++- 11 files changed, 410 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index da529f68..66a308a5 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -78,6 +78,14 @@ Changelog support loading DER encoded public keys. * Fixed building against LibreSSL, a compile-time substitute for OpenSSL. * FreeBSD 9.2 was removed from the continuous integration system. +* Added + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization` + and deprecated + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithNumbers`. +* Added + :meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.dump` + to + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization`. 0.7.2 - 2015-01-16 ~~~~~~~~~~~~~~~~~~ diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index fd97d75b..66bb37c9 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -80,6 +80,37 @@ password. If the key is encrypted we can pass a ``bytes`` object as the There is also support for :func:`loading public keys in the SSH format `. +Key serialization +~~~~~~~~~~~~~~~~~ + +If you have a previously loaded or generated key that has the +:class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization` +interface you can use +:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.dump` +to serialize the key. + +.. doctest:: + + >>> from cryptography.hazmat.primitives import serialization + >>> pem = private_key.dump( + ... serialization.PKCS8(serialization.Encoding.PEM), + ... serialization.BestAvailable(b'passwordgoeshere') + ... ) + >>> pem.splitlines()[0] + '-----BEGIN ENCRYPTED PRIVATE KEY-----' + +It is also possible to serialize without encryption using +:class:`~cryptography.hazmat.primitives.serialization.NoEncryption`. + +.. doctest:: + + >>> pem = private_key.dump( + ... serialization.TraditionalOpenSSL(serialization.Encoding.PEM), + ... serialization.NoEncryption() + ... ) + >>> pem.splitlines()[0] + '-----BEGIN RSA PRIVATE KEY-----' + Signing ~~~~~~~ @@ -485,6 +516,37 @@ Key interfaces instance. +.. class:: RSAPrivateKeyWithSerialization + + .. versionadded:: 0.8 + + Extends :class:`RSAPrivateKey`. + + .. method:: private_numbers() + + Create a + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers` + object. + + :returns: An + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers` + instance. + + .. method:: dump(serializer, encryption_type) + + Dump the key to PEM encoded bytes using the serializer provided. + + :param serializer: An instance of + :class:`~cryptography.hazmat.primitives.serialization.TraditionalOpenSSL` + or :class:`~cryptography.hazmat.primitives.serialization.PKCS8` + + :param encryption_type: An instance of an object conforming to the + :class:`~cryptography.hazmat.primitives.serialization.KeySerializationEncryption` + interface. + + :return bytes: Serialized key. + + .. class:: RSAPublicKey .. versionadded:: 0.2 diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index 87f3c0b0..68eaf021 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -3,7 +3,7 @@ Key Serialization ================= -.. currentmodule:: cryptography.hazmat.primitives.serialization +.. module:: cryptography.hazmat.primitives.serialization .. testsetup:: @@ -282,3 +282,71 @@ DSA keys look almost identical but begin with ``ssh-dss`` rather than :raises cryptography.exceptions.UnsupportedAlgorithm: If the serialized key is of a type that is not supported. + +Serializers +~~~~~~~~~~~ + +Instances of these classes can be passed to methods like +:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.dump`. + +.. class:: PKCS8(encoding) + + .. versionadded:: 0.8 + + A serializer for the PKCS #8 format. + + :param encoding: A value from the + :class:`~cryptography.hazmat.primitives.serialization.Encoding` enum. + +.. class:: TraditionalOpenSSL(encoding) + + .. versionadded:: 0.8 + + A serializer for the traditional OpenSSL (sometimes known as PKCS #1) + format. + + :param encoding: A value from the + :class:`~cryptography.hazmat.primitives.serialization.Encoding` enum. + + +Serialization Encryption Types +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. class:: KeySerializationEncryption + + Objects with this interface are usable as encryption types with methods + like + :meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.dump`. + All other classes in this section represent the available choices for + encryption and have this interface. + +.. class:: BestAvailable + + Encrypt using the best available encryption for a given key's backend. + This is a curated encryption choice and the algorithm may change over + time. + + :param bytes password: The password to use for encryption. + +.. class:: NoEncryption + + Do not encrypt. + + +Utility Classes +~~~~~~~~~~~~~~~ + +.. class:: Encoding + + .. versionadded:: 0.8 + + An enumeration for encoding types. Used by :class:`PKCS8` and + :class:`TraditionalOpenSSL`. + + .. attribute:: PEM + + For PEM format. This is a base64 format with delimiters. + + .. attribute:: DER + + For DER format. This is a binary format. diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index ddd37897..6e545370 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -44,6 +44,8 @@ pseudorandom pyOpenSSL Schneier scrypt +Serializers +serializer Solaris Tanja testability diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py index 00ddcda3..1357889f 100644 --- a/src/cryptography/hazmat/backends/openssl/rsa.py +++ b/src/cryptography/hazmat/backends/openssl/rsa.py @@ -17,8 +17,13 @@ from cryptography.hazmat.primitives.asymmetric import ( from cryptography.hazmat.primitives.asymmetric.padding import ( AsymmetricPadding, MGF1, OAEP, PKCS1v15, PSS ) -from cryptography.hazmat.primitives.interfaces import ( - RSAPrivateKeyWithNumbers, RSAPublicKeyWithNumbers +from cryptography.hazmat.primitives.asymmetric.rsa import ( + RSAPrivateKeyWithNumbers, RSAPrivateKeyWithSerialization, + RSAPublicKeyWithNumbers +) +from cryptography.hazmat.primitives.serialization import ( + BestAvailable, Encoding, KeySerializationEncryption, NoEncryption, PKCS8, + TraditionalOpenSSL ) @@ -507,6 +512,7 @@ class _RSAVerificationContext(object): @utils.register_interface(RSAPrivateKeyWithNumbers) +@utils.register_interface(RSAPrivateKeyWithSerialization) class _RSAPrivateKey(object): def __init__(self, backend, rsa_cdata): self._backend = backend @@ -559,6 +565,57 @@ class _RSAPrivateKey(object): ) ) + def dump(self, serializer, encryption_algorithm): + if isinstance(serializer, PKCS8): + write_bio = self._backend._lib.PEM_write_bio_PKCS8PrivateKey + key = self._evp_pkey + elif isinstance(serializer, TraditionalOpenSSL): + write_bio = self._backend._lib.PEM_write_bio_RSAPrivateKey + key = self._rsa_cdata + else: + raise TypeError("serializer must be PKCS8 or TraditionalOpenSSL") + + if serializer.encoding != Encoding.PEM: + raise ValueError("Only PEM encoding is supported by this backend") + + if not isinstance(encryption_algorithm, KeySerializationEncryption): + raise TypeError( + "Encryption algorithm must be a KeySerializationEncryption " + "instance" + ) + + if isinstance(encryption_algorithm, NoEncryption): + password = b"" + passlen = 0 + evp_cipher = self._backend._ffi.NULL + elif isinstance(encryption_algorithm, BestAvailable): + # This is a curated value that we will update over time. + evp_cipher = self._backend._lib.EVP_get_cipherbyname( + b"aes-256-cbc" + ) + password = encryption_algorithm.password + passlen = len(password) + if passlen > 1023: + raise ValueError( + "Passwords longer than 1023 bytes are not supported by " + "this backend" + ) + else: + raise ValueError("Unsupported encryption type") + + bio = self._backend._create_mem_bio() + res = write_bio( + bio, + key, + evp_cipher, + password, + passlen, + self._backend._ffi.NULL, + self._backend._ffi.NULL + ) + assert res == 1 + return self._backend._read_mem_bio(bio) + @utils.register_interface(RSAPublicKeyWithNumbers) class _RSAPublicKey(object): diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py index 332ad2c3..e994a9cc 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -42,13 +42,23 @@ class RSAPrivateKey(object): @six.add_metaclass(abc.ABCMeta) -class RSAPrivateKeyWithNumbers(RSAPrivateKey): +class RSAPrivateKeyWithSerialization(RSAPrivateKey): @abc.abstractmethod def private_numbers(self): """ Returns an RSAPrivateNumbers. """ + @abc.abstractmethod + def dump(self, serializer, encryption_algorithm): + """ + Returns the PEM encoded key. + """ + + +# DeprecatedIn08 +RSAPrivateKeyWithNumbers = RSAPrivateKeyWithSerialization + @six.add_metaclass(abc.ABCMeta) class RSAPublicKey(object): diff --git a/src/cryptography/hazmat/primitives/serialization.py b/src/cryptography/hazmat/primitives/serialization.py index 0f9506e1..9bfbc6b7 100644 --- a/src/cryptography/hazmat/primitives/serialization.py +++ b/src/cryptography/hazmat/primitives/serialization.py @@ -4,11 +4,14 @@ from __future__ import absolute_import, division, print_function +import abc import base64 import struct +from enum import Enum import six +from cryptography import utils from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa @@ -164,3 +167,47 @@ else: data = data[4:] return result + + +class Encoding(Enum): + PEM = "PEM" + DER = "DER" + + +class PKCS8(object): + def __init__(self, encoding): + if not isinstance(encoding, Encoding): + raise TypeError( + "Encoding must be an element from the Encoding enum" + ) + + self.encoding = encoding + + +class TraditionalOpenSSL(object): + def __init__(self, encoding): + if not isinstance(encoding, Encoding): + raise TypeError( + "Encoding must be an element from the Encoding enum" + ) + + self.encoding = encoding + + +@six.add_metaclass(abc.ABCMeta) +class KeySerializationEncryption(object): + pass + + +@utils.register_interface(KeySerializationEncryption) +class BestAvailable(object): + def __init__(self, password): + if not isinstance(password, bytes) or len(password) == 0: + raise ValueError("Password must be 1 or more bytes.") + + self.password = password + + +@utils.register_interface(KeySerializationEncryption) +class NoEncryption(object): + pass diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index 78dcc1ca..77b6d253 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -12,6 +12,7 @@ import warnings # DeprecatedIn07 objects exist. This comment exists to remind developers to # look for them when it's time for the ninth release cycle deprecation dance. +# DeprecatedIn08 objects also exist. DeprecatedIn08 = PendingDeprecationWarning diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 0e4d75ed..35b7c5c3 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -15,11 +15,12 @@ import pytest from cryptography import utils from cryptography.exceptions import InternalError, _Reasons +from cryptography.hazmat.backends.interfaces import RSABackend from cryptography.hazmat.backends.openssl.backend import ( Backend, backend ) from cryptography.hazmat.backends.openssl.ec import _sn_to_elliptic_curve -from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import dsa, padding from cryptography.hazmat.primitives.ciphers import ( BlockCipherAlgorithm, Cipher, CipherAlgorithm @@ -27,7 +28,7 @@ from cryptography.hazmat.primitives.ciphers import ( from cryptography.hazmat.primitives.ciphers.algorithms import AES from cryptography.hazmat.primitives.ciphers.modes import CBC, CTR, Mode -from ..primitives.fixtures_rsa import RSA_KEY_512 +from ..primitives.fixtures_rsa import RSA_KEY_2048, RSA_KEY_512 from ...utils import load_vectors_from_file, raises_unsupported_algorithm @@ -493,3 +494,27 @@ class TestOpenSSLEllipticCurve(object): def test_sn_to_elliptic_curve_not_supported(self): with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_ELLIPTIC_CURVE): _sn_to_elliptic_curve(backend, b"fake") + + +@pytest.mark.requires_backend_interface(interface=RSABackend) +class TestRSAPEMSerialization(object): + def test_password_length_limit(self): + password = b"x" * 1024 + key = RSA_KEY_2048.private_key(backend) + with pytest.raises(ValueError): + key.dump( + serialization.PKCS8( + serialization.Encoding.PEM + ), + serialization.BestAvailable(password) + ) + + def test_unsupported_key_encoding(self): + key = RSA_KEY_2048.private_key(backend) + with pytest.raises(ValueError): + key.dump( + serialization.PKCS8( + serialization.Encoding.DER + ), + serialization.NoEncryption() + ) diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 74183010..72bc08ad 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -15,8 +15,10 @@ from cryptography import utils from cryptography.exceptions import ( AlreadyFinalized, InvalidSignature, _Reasons ) -from cryptography.hazmat.backends.interfaces import RSABackend -from cryptography.hazmat.primitives import hashes +from cryptography.hazmat.backends.interfaces import ( + PEMSerializationBackend, RSABackend +) +from cryptography.hazmat.primitives import hashes, serialization from cryptography.hazmat.primitives.asymmetric import padding, rsa from cryptography.hazmat.primitives.asymmetric.rsa import ( RSAPrivateNumbers, RSAPublicNumbers @@ -46,6 +48,11 @@ class DummyMGF(object): _salt_length = 0 +@utils.register_interface(serialization.KeySerializationEncryption) +class DummyKeyEncryption(object): + pass + + def _flatten_pkcs1_examples(vectors): flattened_vectors = [] for vector in vectors: @@ -78,6 +85,18 @@ def test_modular_inverse(): ) +def _skip_if_no_serialization(key, backend): + if not isinstance(key, rsa.RSAPrivateKeyWithSerialization): + pytest.skip( + "{0} does not support RSA key serialization".format(backend) + ) + + +def test_skip_if_no_serialization(): + with pytest.raises(pytest.skip.Exception): + _skip_if_no_serialization("notakeywithserialization", "backend") + + @pytest.mark.requires_backend_interface(interface=RSABackend) class TestRSA(object): @pytest.mark.parametrize( @@ -1725,3 +1744,79 @@ class TestRSAPrimeFactorRecovery(object): def test_invalid_recover_prime_factors(self): with pytest.raises(ValueError): rsa.rsa_recover_prime_factors(34, 3, 7) + + +@pytest.mark.requires_backend_interface(interface=RSABackend) +@pytest.mark.requires_backend_interface(interface=PEMSerializationBackend) +class TestRSAPEMWriter(object): + @pytest.mark.parametrize( + ("serializer", "password"), + itertools.product( + [serialization.TraditionalOpenSSL, serialization.PKCS8], + [ + b"s", + b"longerpassword", + b"!*$&(@#$*&($T@%_somesymbols", + b"\x01" * 1000, + ] + ) + ) + def test_dump_encrypted_pem(self, backend, serializer, password): + key = RSA_KEY_2048.private_key(backend) + _skip_if_no_serialization(key, backend) + serialized = key.dump( + serializer(serialization.Encoding.PEM), + serialization.BestAvailable(password) + ) + loaded_key = serialization.load_pem_private_key( + serialized, password, backend + ) + loaded_priv_num = loaded_key.private_numbers() + priv_num = key.private_numbers() + assert loaded_priv_num == priv_num + + @pytest.mark.parametrize( + "serializer", + (serialization.TraditionalOpenSSL, serialization.PKCS8), + ) + def test_dump_unencrypted_pem(self, backend, serializer): + key = RSA_KEY_2048.private_key(backend) + _skip_if_no_serialization(key, backend) + serialized = key.dump( + serializer(serialization.Encoding.PEM), + serialization.NoEncryption() + ) + loaded_key = serialization.load_pem_private_key( + serialized, None, backend + ) + loaded_priv_num = loaded_key.private_numbers() + priv_num = key.private_numbers() + assert loaded_priv_num == priv_num + + def test_dump_invalid_serializer(self, backend): + key = RSA_KEY_2048.private_key(backend) + _skip_if_no_serialization(key, backend) + with pytest.raises(TypeError): + key.dump("notaserializer", serialization.NoEncryption()) + + def test_dump_invalid_encryption_algorithm(self, backend): + key = RSA_KEY_2048.private_key(backend) + _skip_if_no_serialization(key, backend) + with pytest.raises(TypeError): + key.dump( + serialization.TraditionalOpenSSL( + serialization.Encoding.PEM + ), + "notanencalg" + ) + + def test_dump_unsupported_encryption_type(self, backend): + key = RSA_KEY_2048.private_key(backend) + _skip_if_no_serialization(key, backend) + with pytest.raises(ValueError): + key.dump( + serialization.TraditionalOpenSSL( + serialization.Encoding.PEM + ), + DummyKeyEncryption() + ) diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py index a17aac4b..2a5fb21d 100644 --- a/tests/hazmat/primitives/test_serialization.py +++ b/tests/hazmat/primitives/test_serialization.py @@ -18,8 +18,9 @@ from cryptography.hazmat.backends.interfaces import ( ) from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa from cryptography.hazmat.primitives.serialization import ( - load_der_private_key, load_der_public_key, load_pem_private_key, - load_pem_public_key, load_ssh_public_key + BestAvailable, Encoding, PKCS8, TraditionalOpenSSL, load_der_private_key, + load_der_public_key, load_pem_private_key, load_pem_public_key, + load_ssh_public_key ) @@ -1159,3 +1160,27 @@ class TestECDSASSHSerialization(object): ) with pytest.raises(ValueError): load_ssh_public_key(ssh_key, backend) + + +@pytest.mark.parametrize( + "serializer", + [PKCS8, TraditionalOpenSSL] +) +class TestSerializers(object): + def test_invalid_encoding(self, serializer): + with pytest.raises(TypeError): + serializer("thing") + + def test_valid_params(self, serializer): + fmt = serializer(Encoding.PEM) + assert isinstance(fmt, (PKCS8, TraditionalOpenSSL)) + + +class TestKeySerializationEncryptionTypes(object): + def test_non_bytes_password(self): + with pytest.raises(ValueError): + BestAvailable(object()) + + def test_encryption_with_zero_length_password(self): + with pytest.raises(ValueError): + BestAvailable(b"") -- cgit v1.2.3 From 199dc276cd1b45a799b511090b37237df49d68a3 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 23 Feb 2015 20:45:21 -0600 Subject: address review comments --- docs/hazmat/primitives/asymmetric/rsa.rst | 20 +++++--- .../hazmat/primitives/asymmetric/serialization.rst | 60 +++++++++------------- src/cryptography/hazmat/backends/openssl/rsa.py | 27 ++++++---- .../hazmat/primitives/asymmetric/rsa.py | 15 ++++-- .../hazmat/primitives/interfaces/__init__.py | 5 +- .../hazmat/primitives/serialization.py | 23 ++------- src/cryptography/utils.py | 1 - tests/hazmat/backends/test_openssl.py | 12 ++--- tests/hazmat/primitives/test_rsa.py | 51 ++++++++++++------ tests/hazmat/primitives/test_serialization.py | 23 ++------- 10 files changed, 113 insertions(+), 124 deletions(-) diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index 66bb37c9..ab2fe4e5 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -93,8 +93,9 @@ to serialize the key. >>> from cryptography.hazmat.primitives import serialization >>> pem = private_key.dump( - ... serialization.PKCS8(serialization.Encoding.PEM), - ... serialization.BestAvailable(b'passwordgoeshere') + ... encoding=serialization.Encoding.PEM, + ... fmt=serialization.Format.PKCS8, + ... encryption_type=serialization.BestAvailableEncryption(b'mypassword') ... ) >>> pem.splitlines()[0] '-----BEGIN ENCRYPTED PRIVATE KEY-----' @@ -105,8 +106,9 @@ It is also possible to serialize without encryption using .. doctest:: >>> pem = private_key.dump( - ... serialization.TraditionalOpenSSL(serialization.Encoding.PEM), - ... serialization.NoEncryption() + ... encoding=serialization.Encoding.PEM, + ... fmt=serialization.Format.PKCS8, + ... encryption_type=serialization.NoEncryption() ... ) >>> pem.splitlines()[0] '-----BEGIN RSA PRIVATE KEY-----' @@ -532,13 +534,15 @@ Key interfaces :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers` instance. - .. method:: dump(serializer, encryption_type) + .. method:: dump(encoding, fmt, encryption_type) Dump the key to PEM encoded bytes using the serializer provided. - :param serializer: An instance of - :class:`~cryptography.hazmat.primitives.serialization.TraditionalOpenSSL` - or :class:`~cryptography.hazmat.primitives.serialization.PKCS8` + :param encoding: A value from the + :class:`~cryptography.hazmat.primitives.serialization.Encoding` enum. + + :param fmt: A value from the + :class:`~cryptography.hazmat.primitives.serialization.Format` enum. :param encryption_type: An instance of an object conforming to the :class:`~cryptography.hazmat.primitives.serialization.KeySerializationEncryption` diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index 68eaf021..b429766d 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -75,12 +75,12 @@ methods. .. doctest:: >>> from cryptography.hazmat.backends import default_backend - >>> from cryptography.hazmat.primitives.asymmetric import dsa, rsa + >>> from cryptography.hazmat.primitives.asymmetric import rsa >>> from cryptography.hazmat.primitives.serialization import load_pem_private_key >>> key = load_pem_private_key(pem_data, password=None, backend=default_backend()) >>> if isinstance(key, rsa.RSAPrivateKey): ... signature = sign_with_rsa_key(key, message) - ... elif isinstance(key, dsa.DSAPrivateKey): + ... elif isinstance(key, interfaces.DSAPrivateKey): ... signature = sign_with_dsa_key(key, message) ... else: ... raise TypeError @@ -283,30 +283,37 @@ DSA keys look almost identical but begin with ``ssh-dss`` rather than :raises cryptography.exceptions.UnsupportedAlgorithm: If the serialized key is of a type that is not supported. -Serializers -~~~~~~~~~~~ - -Instances of these classes can be passed to methods like -:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.dump`. +Serialization Formats +~~~~~~~~~~~~~~~~~~~~~ -.. class:: PKCS8(encoding) +.. class:: Format .. versionadded:: 0.8 - A serializer for the PKCS #8 format. + An enumeration for key formats. + + .. attribute:: TraditionalOpenSSL + + Frequently known as PKCS#1 format. - :param encoding: A value from the - :class:`~cryptography.hazmat.primitives.serialization.Encoding` enum. + .. attribute:: PKCS8 -.. class:: TraditionalOpenSSL(encoding) +Serialization Encodings +~~~~~~~~~~~~~~~~~~~~~~~ + +.. class:: Encoding .. versionadded:: 0.8 - A serializer for the traditional OpenSSL (sometimes known as PKCS #1) - format. + An enumeration for encoding types. + + .. attribute:: PEM - :param encoding: A value from the - :class:`~cryptography.hazmat.primitives.serialization.Encoding` enum. + For PEM format. This is a base64 format with delimiters. + + .. attribute:: DER + + For DER format. This is a binary format. Serialization Encryption Types @@ -320,7 +327,7 @@ Serialization Encryption Types All other classes in this section represent the available choices for encryption and have this interface. -.. class:: BestAvailable +.. class:: BestAvailableEncryption(password) Encrypt using the best available encryption for a given key's backend. This is a curated encryption choice and the algorithm may change over @@ -331,22 +338,3 @@ Serialization Encryption Types .. class:: NoEncryption Do not encrypt. - - -Utility Classes -~~~~~~~~~~~~~~~ - -.. class:: Encoding - - .. versionadded:: 0.8 - - An enumeration for encoding types. Used by :class:`PKCS8` and - :class:`TraditionalOpenSSL`. - - .. attribute:: PEM - - For PEM format. This is a base64 format with delimiters. - - .. attribute:: DER - - For DER format. This is a binary format. diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py index 1357889f..efc1a577 100644 --- a/src/cryptography/hazmat/backends/openssl/rsa.py +++ b/src/cryptography/hazmat/backends/openssl/rsa.py @@ -22,8 +22,8 @@ from cryptography.hazmat.primitives.asymmetric.rsa import ( RSAPublicKeyWithNumbers ) from cryptography.hazmat.primitives.serialization import ( - BestAvailable, Encoding, KeySerializationEncryption, NoEncryption, PKCS8, - TraditionalOpenSSL + BestAvailableEncryption, Encoding, Format, KeySerializationEncryption, + NoEncryption ) @@ -565,18 +565,23 @@ class _RSAPrivateKey(object): ) ) - def dump(self, serializer, encryption_algorithm): - if isinstance(serializer, PKCS8): + def dump(self, encoding, fmt, encryption_algorithm): + if not isinstance(encoding, Encoding): + raise TypeError("encoding must be an item from the Encoding enum") + + if not isinstance(fmt, Format): + raise TypeError("format must be an item from the Format enum") + + # This is a temporary check until we land DER serialization. + if encoding != Encoding.PEM: + raise ValueError("Only PEM encoding is supported by this backend") + + if fmt == Format.PKCS8: write_bio = self._backend._lib.PEM_write_bio_PKCS8PrivateKey key = self._evp_pkey - elif isinstance(serializer, TraditionalOpenSSL): + elif fmt == Format.TraditionalOpenSSL: write_bio = self._backend._lib.PEM_write_bio_RSAPrivateKey key = self._rsa_cdata - else: - raise TypeError("serializer must be PKCS8 or TraditionalOpenSSL") - - if serializer.encoding != Encoding.PEM: - raise ValueError("Only PEM encoding is supported by this backend") if not isinstance(encryption_algorithm, KeySerializationEncryption): raise TypeError( @@ -588,7 +593,7 @@ class _RSAPrivateKey(object): password = b"" passlen = 0 evp_cipher = self._backend._ffi.NULL - elif isinstance(encryption_algorithm, BestAvailable): + elif isinstance(encryption_algorithm, BestAvailableEncryption): # This is a curated value that we will update over time. evp_cipher = self._backend._lib.EVP_get_cipherbyname( b"aes-256-cbc" diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py index e994a9cc..918717f3 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -50,14 +50,21 @@ class RSAPrivateKeyWithSerialization(RSAPrivateKey): """ @abc.abstractmethod - def dump(self, serializer, encryption_algorithm): + def dump(self, encoding, fmt, encryption_algorithm): """ - Returns the PEM encoded key. + Returns the dumped key. """ -# DeprecatedIn08 -RSAPrivateKeyWithNumbers = RSAPrivateKeyWithSerialization +RSAPrivateKeyWithNumbers = utils.deprecated( + RSAPrivateKeyWithSerialization, + __name__, + ( + "The RSAPrivateKeyWithNumbers interface has been renamed to " + "RSAPrivateKeyWithSerialization" + ), + utils.DeprecatedIn08 +) @six.add_metaclass(abc.ABCMeta) diff --git a/src/cryptography/hazmat/primitives/interfaces/__init__.py b/src/cryptography/hazmat/primitives/interfaces/__init__.py index 6b4241bd..f9ffae06 100644 --- a/src/cryptography/hazmat/primitives/interfaces/__init__.py +++ b/src/cryptography/hazmat/primitives/interfaces/__init__.py @@ -289,11 +289,12 @@ RSAPrivateKey = utils.deprecated( ) RSAPrivateKeyWithNumbers = utils.deprecated( - rsa.RSAPrivateKeyWithNumbers, + rsa.RSAPrivateKeyWithSerialization, __name__, ( "The RSAPrivateKeyWithNumbers interface has moved to the " - "cryptography.hazmat.primitives.asymmetric.rsa module" + "cryptography.hazmat.primitives.asymmetric.rsa module and has been " + "renamed RSAPrivateKeyWithSerialization" ), utils.DeprecatedIn08 ) diff --git a/src/cryptography/hazmat/primitives/serialization.py b/src/cryptography/hazmat/primitives/serialization.py index 9bfbc6b7..0d564221 100644 --- a/src/cryptography/hazmat/primitives/serialization.py +++ b/src/cryptography/hazmat/primitives/serialization.py @@ -174,24 +174,9 @@ class Encoding(Enum): DER = "DER" -class PKCS8(object): - def __init__(self, encoding): - if not isinstance(encoding, Encoding): - raise TypeError( - "Encoding must be an element from the Encoding enum" - ) - - self.encoding = encoding - - -class TraditionalOpenSSL(object): - def __init__(self, encoding): - if not isinstance(encoding, Encoding): - raise TypeError( - "Encoding must be an element from the Encoding enum" - ) - - self.encoding = encoding +class Format(Enum): + PKCS8 = "PKCS8" + TraditionalOpenSSL = "TraditionalOpenSSL" @six.add_metaclass(abc.ABCMeta) @@ -200,7 +185,7 @@ class KeySerializationEncryption(object): @utils.register_interface(KeySerializationEncryption) -class BestAvailable(object): +class BestAvailableEncryption(object): def __init__(self, password): if not isinstance(password, bytes) or len(password) == 0: raise ValueError("Password must be 1 or more bytes.") diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index 77b6d253..78dcc1ca 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -12,7 +12,6 @@ import warnings # DeprecatedIn07 objects exist. This comment exists to remind developers to # look for them when it's time for the ninth release cycle deprecation dance. -# DeprecatedIn08 objects also exist. DeprecatedIn08 = PendingDeprecationWarning diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 35b7c5c3..b5de702d 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -503,18 +503,16 @@ class TestRSAPEMSerialization(object): key = RSA_KEY_2048.private_key(backend) with pytest.raises(ValueError): key.dump( - serialization.PKCS8( - serialization.Encoding.PEM - ), - serialization.BestAvailable(password) + serialization.Encoding.PEM, + serialization.Format.PKCS8, + serialization.BestAvailableEncryption(password) ) def test_unsupported_key_encoding(self): key = RSA_KEY_2048.private_key(backend) with pytest.raises(ValueError): key.dump( - serialization.PKCS8( - serialization.Encoding.DER - ), + serialization.Encoding.DER, + serialization.Format.PKCS8, serialization.NoEncryption() ) diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 72bc08ad..a0df2f26 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -1750,9 +1750,12 @@ class TestRSAPrimeFactorRecovery(object): @pytest.mark.requires_backend_interface(interface=PEMSerializationBackend) class TestRSAPEMWriter(object): @pytest.mark.parametrize( - ("serializer", "password"), + ("fmt", "password"), itertools.product( - [serialization.TraditionalOpenSSL, serialization.PKCS8], + [ + serialization.Format.TraditionalOpenSSL, + serialization.Format.PKCS8 + ], [ b"s", b"longerpassword", @@ -1761,12 +1764,13 @@ class TestRSAPEMWriter(object): ] ) ) - def test_dump_encrypted_pem(self, backend, serializer, password): + def test_dump_encrypted_pem(self, backend, fmt, password): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) serialized = key.dump( - serializer(serialization.Encoding.PEM), - serialization.BestAvailable(password) + serialization.Encoding.PEM, + fmt, + serialization.BestAvailableEncryption(password) ) loaded_key = serialization.load_pem_private_key( serialized, password, backend @@ -1776,14 +1780,15 @@ class TestRSAPEMWriter(object): assert loaded_priv_num == priv_num @pytest.mark.parametrize( - "serializer", - (serialization.TraditionalOpenSSL, serialization.PKCS8), + "fmt", + (serialization.Format.TraditionalOpenSSL, serialization.Format.PKCS8), ) - def test_dump_unencrypted_pem(self, backend, serializer): + def test_dump_unencrypted_pem(self, backend, fmt): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) serialized = key.dump( - serializer(serialization.Encoding.PEM), + serialization.Encoding.PEM, + fmt, serialization.NoEncryption() ) loaded_key = serialization.load_pem_private_key( @@ -1793,20 +1798,33 @@ class TestRSAPEMWriter(object): priv_num = key.private_numbers() assert loaded_priv_num == priv_num - def test_dump_invalid_serializer(self, backend): + def test_dump_invalid_encoding(self, backend): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): - key.dump("notaserializer", serialization.NoEncryption()) + key.dump( + "notencoding", + serialization.Format.PKCS8, + serialization.NoEncryption() + ) + + def test_dump_invalid_format(self, backend): + key = RSA_KEY_2048.private_key(backend) + _skip_if_no_serialization(key, backend) + with pytest.raises(TypeError): + key.dump( + serialization.Encoding.PEM, + "invalidformat", + serialization.NoEncryption() + ) def test_dump_invalid_encryption_algorithm(self, backend): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.dump( - serialization.TraditionalOpenSSL( - serialization.Encoding.PEM - ), + serialization.Encoding.PEM, + serialization.Format.TraditionalOpenSSL, "notanencalg" ) @@ -1815,8 +1833,7 @@ class TestRSAPEMWriter(object): _skip_if_no_serialization(key, backend) with pytest.raises(ValueError): key.dump( - serialization.TraditionalOpenSSL( - serialization.Encoding.PEM - ), + serialization.Encoding.PEM, + serialization.Format.TraditionalOpenSSL, DummyKeyEncryption() ) diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py index 2a5fb21d..fc8f8664 100644 --- a/tests/hazmat/primitives/test_serialization.py +++ b/tests/hazmat/primitives/test_serialization.py @@ -18,9 +18,8 @@ from cryptography.hazmat.backends.interfaces import ( ) from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa from cryptography.hazmat.primitives.serialization import ( - BestAvailable, Encoding, PKCS8, TraditionalOpenSSL, load_der_private_key, - load_der_public_key, load_pem_private_key, load_pem_public_key, - load_ssh_public_key + BestAvailableEncryption, load_der_private_key, load_der_public_key, + load_pem_private_key, load_pem_public_key, load_ssh_public_key ) @@ -1162,25 +1161,11 @@ class TestECDSASSHSerialization(object): load_ssh_public_key(ssh_key, backend) -@pytest.mark.parametrize( - "serializer", - [PKCS8, TraditionalOpenSSL] -) -class TestSerializers(object): - def test_invalid_encoding(self, serializer): - with pytest.raises(TypeError): - serializer("thing") - - def test_valid_params(self, serializer): - fmt = serializer(Encoding.PEM) - assert isinstance(fmt, (PKCS8, TraditionalOpenSSL)) - - class TestKeySerializationEncryptionTypes(object): def test_non_bytes_password(self): with pytest.raises(ValueError): - BestAvailable(object()) + BestAvailableEncryption(object()) def test_encryption_with_zero_length_password(self): with pytest.raises(ValueError): - BestAvailable(b"") + BestAvailableEncryption(b"") -- cgit v1.2.3 From 4d236049529bc1ab1b301756a6c9be7a30ce8f8a Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 23 Feb 2015 21:54:36 -0600 Subject: fix docs --- docs/hazmat/primitives/asymmetric/rsa.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index ab2fe4e5..ac58b9d2 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -95,7 +95,7 @@ to serialize the key. >>> pem = private_key.dump( ... encoding=serialization.Encoding.PEM, ... fmt=serialization.Format.PKCS8, - ... encryption_type=serialization.BestAvailableEncryption(b'mypassword') + ... encryption_algorithm=serialization.BestAvailableEncryption(b'mypassword') ... ) >>> pem.splitlines()[0] '-----BEGIN ENCRYPTED PRIVATE KEY-----' @@ -107,8 +107,8 @@ It is also possible to serialize without encryption using >>> pem = private_key.dump( ... encoding=serialization.Encoding.PEM, - ... fmt=serialization.Format.PKCS8, - ... encryption_type=serialization.NoEncryption() + ... fmt=serialization.Format.TraditionalOpenSSL, + ... encryption_algorithm=serialization.NoEncryption() ... ) >>> pem.splitlines()[0] '-----BEGIN RSA PRIVATE KEY-----' @@ -534,7 +534,7 @@ Key interfaces :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers` instance. - .. method:: dump(encoding, fmt, encryption_type) + .. method:: dump(encoding, fmt, encryption_algorithm) Dump the key to PEM encoded bytes using the serializer provided. @@ -544,7 +544,7 @@ Key interfaces :param fmt: A value from the :class:`~cryptography.hazmat.primitives.serialization.Format` enum. - :param encryption_type: An instance of an object conforming to the + :param encryption_algorithm: An instance of an object conforming to the :class:`~cryptography.hazmat.primitives.serialization.KeySerializationEncryption` interface. -- cgit v1.2.3 From 8aad028501ef434071d3969bce41c4e6375b4c61 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 23 Feb 2015 22:03:09 -0600 Subject: rename dump to as_bytes --- CHANGELOG.rst | 2 +- docs/hazmat/primitives/asymmetric/rsa.rst | 10 ++++----- .../hazmat/primitives/asymmetric/serialization.rst | 2 +- src/cryptography/hazmat/backends/openssl/rsa.py | 2 +- .../hazmat/primitives/asymmetric/rsa.py | 4 ++-- tests/hazmat/backends/test_openssl.py | 4 ++-- tests/hazmat/primitives/test_rsa.py | 24 +++++++++++----------- 7 files changed, 24 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 66a308a5..8f40d287 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -83,7 +83,7 @@ Changelog and deprecated :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithNumbers`. * Added - :meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.dump` + :meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.as_bytes` to :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization`. diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index ac58b9d2..80d48497 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -86,13 +86,13 @@ Key serialization If you have a previously loaded or generated key that has the :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization` interface you can use -:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.dump` +:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.as_bytes` to serialize the key. .. doctest:: >>> from cryptography.hazmat.primitives import serialization - >>> pem = private_key.dump( + >>> pem = private_key.as_bytes( ... encoding=serialization.Encoding.PEM, ... fmt=serialization.Format.PKCS8, ... encryption_algorithm=serialization.BestAvailableEncryption(b'mypassword') @@ -105,7 +105,7 @@ It is also possible to serialize without encryption using .. doctest:: - >>> pem = private_key.dump( + >>> pem = private_key.as_bytes( ... encoding=serialization.Encoding.PEM, ... fmt=serialization.Format.TraditionalOpenSSL, ... encryption_algorithm=serialization.NoEncryption() @@ -534,9 +534,9 @@ Key interfaces :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers` instance. - .. method:: dump(encoding, fmt, encryption_algorithm) + .. method:: as_bytes(encoding, fmt, encryption_algorithm) - Dump the key to PEM encoded bytes using the serializer provided. + Serialize the key to bytes. :param encoding: A value from the :class:`~cryptography.hazmat.primitives.serialization.Encoding` enum. diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index b429766d..abf036ac 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -323,7 +323,7 @@ Serialization Encryption Types Objects with this interface are usable as encryption types with methods like - :meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.dump`. + :meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.as_bytes`. All other classes in this section represent the available choices for encryption and have this interface. diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py index efc1a577..0a1f106f 100644 --- a/src/cryptography/hazmat/backends/openssl/rsa.py +++ b/src/cryptography/hazmat/backends/openssl/rsa.py @@ -565,7 +565,7 @@ class _RSAPrivateKey(object): ) ) - def dump(self, encoding, fmt, encryption_algorithm): + def as_bytes(self, encoding, fmt, encryption_algorithm): if not isinstance(encoding, Encoding): raise TypeError("encoding must be an item from the Encoding enum") diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py index 918717f3..160ac6aa 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -50,9 +50,9 @@ class RSAPrivateKeyWithSerialization(RSAPrivateKey): """ @abc.abstractmethod - def dump(self, encoding, fmt, encryption_algorithm): + def as_bytes(self, encoding, fmt, encryption_algorithm): """ - Returns the dumped key. + Returns the key serialized as bytes. """ diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index b5de702d..8cf14b98 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -502,7 +502,7 @@ class TestRSAPEMSerialization(object): password = b"x" * 1024 key = RSA_KEY_2048.private_key(backend) with pytest.raises(ValueError): - key.dump( + key.as_bytes( serialization.Encoding.PEM, serialization.Format.PKCS8, serialization.BestAvailableEncryption(password) @@ -511,7 +511,7 @@ class TestRSAPEMSerialization(object): def test_unsupported_key_encoding(self): key = RSA_KEY_2048.private_key(backend) with pytest.raises(ValueError): - key.dump( + key.as_bytes( serialization.Encoding.DER, serialization.Format.PKCS8, serialization.NoEncryption() diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index a0df2f26..17a2a414 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -1764,10 +1764,10 @@ class TestRSAPEMWriter(object): ] ) ) - def test_dump_encrypted_pem(self, backend, fmt, password): + def test_as_bytes_encrypted_pem(self, backend, fmt, password): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) - serialized = key.dump( + serialized = key.as_bytes( serialization.Encoding.PEM, fmt, serialization.BestAvailableEncryption(password) @@ -1783,10 +1783,10 @@ class TestRSAPEMWriter(object): "fmt", (serialization.Format.TraditionalOpenSSL, serialization.Format.PKCS8), ) - def test_dump_unencrypted_pem(self, backend, fmt): + def test_as_bytes_unencrypted_pem(self, backend, fmt): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) - serialized = key.dump( + serialized = key.as_bytes( serialization.Encoding.PEM, fmt, serialization.NoEncryption() @@ -1798,41 +1798,41 @@ class TestRSAPEMWriter(object): priv_num = key.private_numbers() assert loaded_priv_num == priv_num - def test_dump_invalid_encoding(self, backend): + def test_as_bytes_invalid_encoding(self, backend): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): - key.dump( + key.as_bytes( "notencoding", serialization.Format.PKCS8, serialization.NoEncryption() ) - def test_dump_invalid_format(self, backend): + def test_as_bytes_invalid_format(self, backend): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): - key.dump( + key.as_bytes( serialization.Encoding.PEM, "invalidformat", serialization.NoEncryption() ) - def test_dump_invalid_encryption_algorithm(self, backend): + def test_as_bytes_invalid_encryption_algorithm(self, backend): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): - key.dump( + key.as_bytes( serialization.Encoding.PEM, serialization.Format.TraditionalOpenSSL, "notanencalg" ) - def test_dump_unsupported_encryption_type(self, backend): + def test_as_bytes_unsupported_encryption_type(self, backend): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) with pytest.raises(ValueError): - key.dump( + key.as_bytes( serialization.Encoding.PEM, serialization.Format.TraditionalOpenSSL, DummyKeyEncryption() -- cgit v1.2.3 From 858dd3fcb2851b647c2581c8f4246d0d9c7c2be2 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Mon, 23 Feb 2015 23:47:06 -0600 Subject: listify a parametrized test --- tests/hazmat/primitives/test_rsa.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 17a2a414..8dcb6450 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -1781,7 +1781,7 @@ class TestRSAPEMWriter(object): @pytest.mark.parametrize( "fmt", - (serialization.Format.TraditionalOpenSSL, serialization.Format.PKCS8), + [serialization.Format.TraditionalOpenSSL, serialization.Format.PKCS8], ) def test_as_bytes_unencrypted_pem(self, backend, fmt): key = RSA_KEY_2048.private_key(backend) -- cgit v1.2.3 From 6177cbe2fad1422899a2c26cb53abbbf97886485 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 27 Feb 2015 17:05:52 -0600 Subject: address review feedback --- docs/hazmat/primitives/asymmetric/rsa.rst | 14 +++++++++----- src/cryptography/hazmat/backends/openssl/rsa.py | 10 +++++----- src/cryptography/hazmat/primitives/asymmetric/rsa.py | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index 80d48497..17e13c28 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -94,7 +94,7 @@ to serialize the key. >>> from cryptography.hazmat.primitives import serialization >>> pem = private_key.as_bytes( ... encoding=serialization.Encoding.PEM, - ... fmt=serialization.Format.PKCS8, + ... format=serialization.Format.PKCS8, ... encryption_algorithm=serialization.BestAvailableEncryption(b'mypassword') ... ) >>> pem.splitlines()[0] @@ -107,7 +107,7 @@ It is also possible to serialize without encryption using >>> pem = private_key.as_bytes( ... encoding=serialization.Encoding.PEM, - ... fmt=serialization.Format.TraditionalOpenSSL, + ... format=serialization.Format.TraditionalOpenSSL, ... encryption_algorithm=serialization.NoEncryption() ... ) >>> pem.splitlines()[0] @@ -534,14 +534,18 @@ Key interfaces :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers` instance. - .. method:: as_bytes(encoding, fmt, encryption_algorithm) + .. method:: as_bytes(encoding, format, encryption_algorithm) - Serialize the key to bytes. + Allows serialization of the key to bytes. Encoding (PEM or DER), format + (TraditionalOpenSSL or PKCS8) and encryption algorithm (such as + :class:`~cryptography.hazmat.primitives.serialization.BestAvailableEncryption` + or :class:`~cryptography.hazmat.primitives.serialization.NoEncryption`) + are chosen to define the exact serialization. :param encoding: A value from the :class:`~cryptography.hazmat.primitives.serialization.Encoding` enum. - :param fmt: A value from the + :param format: A value from the :class:`~cryptography.hazmat.primitives.serialization.Format` enum. :param encryption_algorithm: An instance of an object conforming to the diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py index 0a1f106f..ce6f646c 100644 --- a/src/cryptography/hazmat/backends/openssl/rsa.py +++ b/src/cryptography/hazmat/backends/openssl/rsa.py @@ -565,21 +565,21 @@ class _RSAPrivateKey(object): ) ) - def as_bytes(self, encoding, fmt, encryption_algorithm): + def as_bytes(self, encoding, format, encryption_algorithm): if not isinstance(encoding, Encoding): raise TypeError("encoding must be an item from the Encoding enum") - if not isinstance(fmt, Format): + if not isinstance(format, Format): raise TypeError("format must be an item from the Format enum") # This is a temporary check until we land DER serialization. - if encoding != Encoding.PEM: + if encoding is not Encoding.PEM: raise ValueError("Only PEM encoding is supported by this backend") - if fmt == Format.PKCS8: + if format is Format.PKCS8: write_bio = self._backend._lib.PEM_write_bio_PKCS8PrivateKey key = self._evp_pkey - elif fmt == Format.TraditionalOpenSSL: + elif format is Format.TraditionalOpenSSL: write_bio = self._backend._lib.PEM_write_bio_RSAPrivateKey key = self._rsa_cdata diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py index 160ac6aa..932868e1 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -50,7 +50,7 @@ class RSAPrivateKeyWithSerialization(RSAPrivateKey): """ @abc.abstractmethod - def as_bytes(self, encoding, fmt, encryption_algorithm): + def as_bytes(self, encoding, format, encryption_algorithm): """ Returns the key serialized as bytes. """ -- cgit v1.2.3 From 20456e96ed510f96c5bdc24b799b89200e3dba4c Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 27 Feb 2015 22:45:24 -0600 Subject: add exact byte test --- tests/hazmat/primitives/test_rsa.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index 8dcb6450..dde73b06 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -1798,6 +1798,23 @@ class TestRSAPEMWriter(object): priv_num = key.private_numbers() assert loaded_priv_num == priv_num + def test_as_bytes_traditional_openssl_unencrypted_pem(self, backend): + key_bytes = load_vectors_from_file( + os.path.join( + "asymmetric", + "Traditional_OpenSSL_Serialization", + "testrsa.pem" + ), + lambda pemfile: pemfile.read().encode() + ) + key = serialization.load_pem_private_key(key_bytes, None, backend) + serialized = key.as_bytes( + serialization.Encoding.PEM, + serialization.Format.TraditionalOpenSSL, + serialization.NoEncryption() + ) + assert serialized == key_bytes + def test_as_bytes_invalid_encoding(self, backend): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) -- cgit v1.2.3 From 45be3546398e5516b58c53780a32d7dac36ca79e Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Fri, 27 Feb 2015 22:55:54 -0600 Subject: add more docs stuff from review that I missed --- docs/hazmat/primitives/asymmetric/rsa.rst | 2 +- docs/hazmat/primitives/asymmetric/serialization.rst | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index 17e13c28..4fba8e12 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -83,7 +83,7 @@ There is also support for :func:`loading public keys in the SSH format Key serialization ~~~~~~~~~~~~~~~~~ -If you have a previously loaded or generated key that has the +If you have a key that you've loaded or generated which implements the :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization` interface you can use :meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.as_bytes` diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index abf036ac..209c57c5 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -80,7 +80,7 @@ methods. >>> key = load_pem_private_key(pem_data, password=None, backend=default_backend()) >>> if isinstance(key, rsa.RSAPrivateKey): ... signature = sign_with_rsa_key(key, message) - ... elif isinstance(key, interfaces.DSAPrivateKey): + ... elif isinstance(key, dsa.DSAPrivateKey): ... signature = sign_with_dsa_key(key, message) ... else: ... raise TypeError @@ -294,10 +294,15 @@ Serialization Formats .. attribute:: TraditionalOpenSSL - Frequently known as PKCS#1 format. + Frequently known as PKCS#1 format. Still a widely used format, but + generally considered legacy. .. attribute:: PKCS8 + A more modern format for serializing keys which allows for better + encryption. Choose this unless you have explicit legacy compatibility + requirements. + Serialization Encodings ~~~~~~~~~~~~~~~~~~~~~~~ -- cgit v1.2.3 From 35194c99aeb846b2d85d6303dbe4f11b21eadaa6 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 28 Feb 2015 14:34:21 -0600 Subject: linkify some things per review, fix an import --- docs/hazmat/primitives/asymmetric/rsa.rst | 10 ++++++++-- docs/hazmat/primitives/asymmetric/serialization.rst | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index 4fba8e12..adb5cbfc 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -536,8 +536,14 @@ Key interfaces .. method:: as_bytes(encoding, format, encryption_algorithm) - Allows serialization of the key to bytes. Encoding (PEM or DER), format - (TraditionalOpenSSL or PKCS8) and encryption algorithm (such as + Allows serialization of the key to bytes. Encoding ( + :attr:`~cryptography.hazmat.primitives.serialization.Encoding.PEM` or + :attr:`~cryptography.hazmat.primitives.serialization.Encoding.DER`), + format ( + :attr:`~cryptography.hazmat.primitives.serialization.Format.TraditionalOpenSSL` + or + :attr:`~cryptography.hazmat.primitives.serialization.Format.PKCS8`) and + encryption algorithm (such as :class:`~cryptography.hazmat.primitives.serialization.BestAvailableEncryption` or :class:`~cryptography.hazmat.primitives.serialization.NoEncryption`) are chosen to define the exact serialization. diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index 209c57c5..36ba241b 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -75,7 +75,7 @@ methods. .. doctest:: >>> from cryptography.hazmat.backends import default_backend - >>> from cryptography.hazmat.primitives.asymmetric import rsa + >>> from cryptography.hazmat.primitives.asymmetric import dsa, rsa >>> from cryptography.hazmat.primitives.serialization import load_pem_private_key >>> key = load_pem_private_key(pem_data, password=None, backend=default_backend()) >>> if isinstance(key, rsa.RSAPrivateKey): -- cgit v1.2.3 From 223a8f02a37a87b3c7366441647013cf9a18b061 Mon Sep 17 00:00:00 2001 From: Paul Kehrer Date: Sat, 28 Feb 2015 18:54:10 -0600 Subject: change as_bytes to private_bytes, link more things --- CHANGELOG.rst | 2 +- docs/hazmat/primitives/asymmetric/rsa.rst | 8 +++---- .../hazmat/primitives/asymmetric/serialization.rst | 11 +++++---- src/cryptography/hazmat/backends/openssl/rsa.py | 2 +- .../hazmat/primitives/asymmetric/rsa.py | 2 +- tests/hazmat/backends/test_openssl.py | 4 ++-- tests/hazmat/primitives/test_rsa.py | 28 +++++++++++----------- 7 files changed, 30 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8f40d287..f0e373be 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -83,7 +83,7 @@ Changelog and deprecated :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithNumbers`. * Added - :meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.as_bytes` + :meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.private_bytes` to :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization`. diff --git a/docs/hazmat/primitives/asymmetric/rsa.rst b/docs/hazmat/primitives/asymmetric/rsa.rst index adb5cbfc..924696db 100644 --- a/docs/hazmat/primitives/asymmetric/rsa.rst +++ b/docs/hazmat/primitives/asymmetric/rsa.rst @@ -86,13 +86,13 @@ Key serialization If you have a key that you've loaded or generated which implements the :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization` interface you can use -:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.as_bytes` +:meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.private_bytes` to serialize the key. .. doctest:: >>> from cryptography.hazmat.primitives import serialization - >>> pem = private_key.as_bytes( + >>> pem = private_key.private_bytes( ... encoding=serialization.Encoding.PEM, ... format=serialization.Format.PKCS8, ... encryption_algorithm=serialization.BestAvailableEncryption(b'mypassword') @@ -105,7 +105,7 @@ It is also possible to serialize without encryption using .. doctest:: - >>> pem = private_key.as_bytes( + >>> pem = private_key.private_bytes( ... encoding=serialization.Encoding.PEM, ... format=serialization.Format.TraditionalOpenSSL, ... encryption_algorithm=serialization.NoEncryption() @@ -534,7 +534,7 @@ Key interfaces :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateNumbers` instance. - .. method:: as_bytes(encoding, format, encryption_algorithm) + .. method:: private_bytes(encoding, format, encryption_algorithm) Allows serialization of the key to bytes. Encoding ( :attr:`~cryptography.hazmat.primitives.serialization.Encoding.PEM` or diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst index 36ba241b..4940ebd4 100644 --- a/docs/hazmat/primitives/asymmetric/serialization.rst +++ b/docs/hazmat/primitives/asymmetric/serialization.rst @@ -290,7 +290,8 @@ Serialization Formats .. versionadded:: 0.8 - An enumeration for key formats. + An enumeration for key formats. Used with + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.private_bytes`. .. attribute:: TraditionalOpenSSL @@ -310,7 +311,8 @@ Serialization Encodings .. versionadded:: 0.8 - An enumeration for encoding types. + An enumeration for encoding types. Used with + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.private_bytes`. .. attribute:: PEM @@ -328,9 +330,10 @@ Serialization Encryption Types Objects with this interface are usable as encryption types with methods like - :meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.as_bytes`. + :meth:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.private_bytes`. All other classes in this section represent the available choices for - encryption and have this interface. + encryption and have this interface. They are used with + :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKeyWithSerialization.private_bytes`. .. class:: BestAvailableEncryption(password) diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py index ce6f646c..e7365c11 100644 --- a/src/cryptography/hazmat/backends/openssl/rsa.py +++ b/src/cryptography/hazmat/backends/openssl/rsa.py @@ -565,7 +565,7 @@ class _RSAPrivateKey(object): ) ) - def as_bytes(self, encoding, format, encryption_algorithm): + def private_bytes(self, encoding, format, encryption_algorithm): if not isinstance(encoding, Encoding): raise TypeError("encoding must be an item from the Encoding enum") diff --git a/src/cryptography/hazmat/primitives/asymmetric/rsa.py b/src/cryptography/hazmat/primitives/asymmetric/rsa.py index 932868e1..4963d85c 100644 --- a/src/cryptography/hazmat/primitives/asymmetric/rsa.py +++ b/src/cryptography/hazmat/primitives/asymmetric/rsa.py @@ -50,7 +50,7 @@ class RSAPrivateKeyWithSerialization(RSAPrivateKey): """ @abc.abstractmethod - def as_bytes(self, encoding, format, encryption_algorithm): + def private_bytes(self, encoding, format, encryption_algorithm): """ Returns the key serialized as bytes. """ diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py index 8cf14b98..4f44f686 100644 --- a/tests/hazmat/backends/test_openssl.py +++ b/tests/hazmat/backends/test_openssl.py @@ -502,7 +502,7 @@ class TestRSAPEMSerialization(object): password = b"x" * 1024 key = RSA_KEY_2048.private_key(backend) with pytest.raises(ValueError): - key.as_bytes( + key.private_bytes( serialization.Encoding.PEM, serialization.Format.PKCS8, serialization.BestAvailableEncryption(password) @@ -511,7 +511,7 @@ class TestRSAPEMSerialization(object): def test_unsupported_key_encoding(self): key = RSA_KEY_2048.private_key(backend) with pytest.raises(ValueError): - key.as_bytes( + key.private_bytes( serialization.Encoding.DER, serialization.Format.PKCS8, serialization.NoEncryption() diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index dde73b06..0cf94afe 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -1764,10 +1764,10 @@ class TestRSAPEMWriter(object): ] ) ) - def test_as_bytes_encrypted_pem(self, backend, fmt, password): + def test_private_bytes_encrypted_pem(self, backend, fmt, password): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) - serialized = key.as_bytes( + serialized = key.private_bytes( serialization.Encoding.PEM, fmt, serialization.BestAvailableEncryption(password) @@ -1783,10 +1783,10 @@ class TestRSAPEMWriter(object): "fmt", [serialization.Format.TraditionalOpenSSL, serialization.Format.PKCS8], ) - def test_as_bytes_unencrypted_pem(self, backend, fmt): + def test_private_bytes_unencrypted_pem(self, backend, fmt): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) - serialized = key.as_bytes( + serialized = key.private_bytes( serialization.Encoding.PEM, fmt, serialization.NoEncryption() @@ -1798,7 +1798,7 @@ class TestRSAPEMWriter(object): priv_num = key.private_numbers() assert loaded_priv_num == priv_num - def test_as_bytes_traditional_openssl_unencrypted_pem(self, backend): + def test_private_bytes_traditional_openssl_unencrypted_pem(self, backend): key_bytes = load_vectors_from_file( os.path.join( "asymmetric", @@ -1808,48 +1808,48 @@ class TestRSAPEMWriter(object): lambda pemfile: pemfile.read().encode() ) key = serialization.load_pem_private_key(key_bytes, None, backend) - serialized = key.as_bytes( + serialized = key.private_bytes( serialization.Encoding.PEM, serialization.Format.TraditionalOpenSSL, serialization.NoEncryption() ) assert serialized == key_bytes - def test_as_bytes_invalid_encoding(self, backend): + def test_private_bytes_invalid_encoding(self, backend): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): - key.as_bytes( + key.private_bytes( "notencoding", serialization.Format.PKCS8, serialization.NoEncryption() ) - def test_as_bytes_invalid_format(self, backend): + def test_private_bytes_invalid_format(self, backend): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): - key.as_bytes( + key.private_bytes( serialization.Encoding.PEM, "invalidformat", serialization.NoEncryption() ) - def test_as_bytes_invalid_encryption_algorithm(self, backend): + def test_private_bytes_invalid_encryption_algorithm(self, backend): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): - key.as_bytes( + key.private_bytes( serialization.Encoding.PEM, serialization.Format.TraditionalOpenSSL, "notanencalg" ) - def test_as_bytes_unsupported_encryption_type(self, backend): + def test_private_bytes_unsupported_encryption_type(self, backend): key = RSA_KEY_2048.private_key(backend) _skip_if_no_serialization(key, backend) with pytest.raises(ValueError): - key.as_bytes( + key.private_bytes( serialization.Encoding.PEM, serialization.Format.TraditionalOpenSSL, DummyKeyEncryption() -- cgit v1.2.3