aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/hazmat/primitives/asymmetric/rsa.rst20
-rw-r--r--docs/hazmat/primitives/asymmetric/serialization.rst60
-rw-r--r--src/cryptography/hazmat/backends/openssl/rsa.py27
-rw-r--r--src/cryptography/hazmat/primitives/asymmetric/rsa.py15
-rw-r--r--src/cryptography/hazmat/primitives/interfaces/__init__.py5
-rw-r--r--src/cryptography/hazmat/primitives/serialization.py23
-rw-r--r--src/cryptography/utils.py1
-rw-r--r--tests/hazmat/backends/test_openssl.py12
-rw-r--r--tests/hazmat/primitives/test_rsa.py51
-rw-r--r--tests/hazmat/primitives/test_serialization.py23
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"")