aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cryptography/hazmat/backends/interfaces.py23
-rw-r--r--cryptography/hazmat/backends/multibackend.py14
-rw-r--r--cryptography/hazmat/backends/openssl/backend.py73
-rw-r--r--cryptography/hazmat/bindings/openssl/err.py2
-rw-r--r--cryptography/hazmat/primitives/serialization.py6
-rw-r--r--docs/hazmat/backends/interfaces.rst20
-rw-r--r--docs/hazmat/primitives/asymmetric/serialization.rst52
-rw-r--r--pytest.ini1
-rw-r--r--tests/conftest.py8
-rw-r--r--tests/hazmat/backends/test_multibackend.py20
-rw-r--r--tests/hazmat/backends/test_openssl.py109
-rw-r--r--tests/hazmat/primitives/fixtures_rsa.py493
-rw-r--r--tests/hazmat/primitives/test_rsa.py529
-rw-r--r--tests/hazmat/primitives/test_serialization.py300
-rw-r--r--vectors/cryptography_vectors/asymmetric/PKCS8/bad-encryption-oid.pem17
-rw-r--r--vectors/cryptography_vectors/asymmetric/PKCS8/bad-oid-dsa-key.pem9
-rw-r--r--vectors/cryptography_vectors/asymmetric/PKCS8/unenc-dsa-pkcs8.pem9
17 files changed, 1469 insertions, 216 deletions
diff --git a/cryptography/hazmat/backends/interfaces.py b/cryptography/hazmat/backends/interfaces.py
index 264c5afb..55d5cd78 100644
--- a/cryptography/hazmat/backends/interfaces.py
+++ b/cryptography/hazmat/backends/interfaces.py
@@ -129,6 +129,19 @@ class RSABackend(object):
Returns encrypted bytes.
"""
+ @abc.abstractmethod
+ def rsa_padding_supported(self, padding):
+ """
+ Returns True if the backend supports the given padding options.
+ """
+
+ @abc.abstractmethod
+ def generate_rsa_parameters_supported(self, public_exponent, key_size):
+ """
+ Returns True if the backend supports the given parameters for key
+ generation.
+ """
+
@six.add_metaclass(abc.ABCMeta)
class DSABackend(object):
@@ -183,6 +196,16 @@ class TraditionalOpenSSLSerializationBackend(object):
@six.add_metaclass(abc.ABCMeta)
+class PKCS8SerializationBackend(object):
+ @abc.abstractmethod
+ def load_pkcs8_pem_private_key(self, data, password):
+ """
+ Load a private key from PEM encoded data, using password if the data
+ is encrypted.
+ """
+
+
+@six.add_metaclass(abc.ABCMeta)
class CMACBackend(object):
@abc.abstractmethod
def cmac_algorithm_supported(self, algorithm):
diff --git a/cryptography/hazmat/backends/multibackend.py b/cryptography/hazmat/backends/multibackend.py
index 21d307cf..b4cb6889 100644
--- a/cryptography/hazmat/backends/multibackend.py
+++ b/cryptography/hazmat/backends/multibackend.py
@@ -132,6 +132,14 @@ class MultiBackend(object):
raise UnsupportedAlgorithm("RSA is not supported by the backend.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
+ def generate_rsa_parameters_supported(self, public_exponent, key_size):
+ for b in self._filtered_backends(RSABackend):
+ return b.generate_rsa_parameters_supported(
+ public_exponent, key_size
+ )
+ raise UnsupportedAlgorithm("RSA is not supported by the backend.",
+ _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
+
def create_rsa_signature_ctx(self, private_key, padding, algorithm):
for b in self._filtered_backends(RSABackend):
return b.create_rsa_signature_ctx(private_key, padding, algorithm)
@@ -164,6 +172,12 @@ class MultiBackend(object):
raise UnsupportedAlgorithm("RSA is not supported by the backend.",
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
+ def rsa_padding_supported(self, padding):
+ for b in self._filtered_backends(RSABackend):
+ return b.rsa_padding_supported(padding)
+ raise UnsupportedAlgorithm("RSA is not supported by the backend.",
+ _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM)
+
def generate_dsa_parameters(self, key_size):
for b in self._filtered_backends(DSABackend):
return b.generate_dsa_parameters(key_size)
diff --git a/cryptography/hazmat/backends/openssl/backend.py b/cryptography/hazmat/backends/openssl/backend.py
index 5d9626d0..a5f21787 100644
--- a/cryptography/hazmat/backends/openssl/backend.py
+++ b/cryptography/hazmat/backends/openssl/backend.py
@@ -26,7 +26,8 @@ from cryptography.exceptions import (
)
from cryptography.hazmat.backends.interfaces import (
CMACBackend, CipherBackend, DSABackend, HMACBackend, HashBackend,
- PBKDF2HMACBackend, RSABackend, TraditionalOpenSSLSerializationBackend
+ PBKDF2HMACBackend, PKCS8SerializationBackend, RSABackend,
+ TraditionalOpenSSLSerializationBackend
)
from cryptography.hazmat.bindings.openssl.binding import Binding
from cryptography.hazmat.primitives import hashes, interfaces
@@ -55,6 +56,7 @@ _OpenSSLError = collections.namedtuple("_OpenSSLError",
@utils.register_interface(PBKDF2HMACBackend)
@utils.register_interface(RSABackend)
@utils.register_interface(TraditionalOpenSSLSerializationBackend)
+@utils.register_interface(PKCS8SerializationBackend)
class Backend(object):
"""
OpenSSL API binding interfaces.
@@ -378,6 +380,10 @@ class Backend(object):
return self._rsa_cdata_to_private_key(ctx)
+ def generate_rsa_parameters_supported(self, public_exponent, key_size):
+ return (public_exponent >= 3 and public_exponent & 1 != 0 and
+ key_size >= 512)
+
def _new_evp_pkey(self):
evp_pkey = self._lib.EVP_PKEY_new()
assert evp_pkey != self._ffi.NULL
@@ -534,6 +540,16 @@ class Backend(object):
else:
return isinstance(algorithm, hashes.SHA1)
+ def rsa_padding_supported(self, padding):
+ if isinstance(padding, PKCS1v15):
+ return True
+ elif isinstance(padding, PSS) and isinstance(padding._mgf, MGF1):
+ return self.mgf1_hash_supported(padding._mgf._algorithm)
+ elif isinstance(padding, OAEP) and isinstance(padding._mgf, MGF1):
+ return isinstance(padding._mgf._algorithm, hashes.SHA1)
+ else:
+ return False
+
def generate_dsa_parameters(self, key_size):
if key_size not in (1024, 2048, 3072):
raise ValueError(
@@ -763,6 +779,12 @@ class Backend(object):
return _CMACContext(self, algorithm)
def load_traditional_openssl_pem_private_key(self, data, password):
+ # OpenSSLs API for loading PKCS#8 certs can also load the traditional
+ # format so we just use that for both of them.
+
+ return self.load_pkcs8_pem_private_key(data, password)
+
+ def load_pkcs8_pem_private_key(self, data, password):
mem_bio = self._bytes_to_bio(data)
password_callback, password_func = self._pem_password_cb(password)
@@ -779,10 +801,18 @@ class Backend(object):
if not errors:
raise ValueError("Could not unserialize key data.")
- if errors[0][1:] == (
- self._lib.ERR_LIB_PEM,
- self._lib.PEM_F_PEM_DO_HEADER,
- self._lib.PEM_R_BAD_PASSWORD_READ
+ if (
+ errors[0][1:] == (
+ self._lib.ERR_LIB_PEM,
+ self._lib.PEM_F_PEM_DO_HEADER,
+ self._lib.PEM_R_BAD_PASSWORD_READ
+ )
+ ) or (
+ errors[0][1:] == (
+ self._lib.ERR_LIB_PEM,
+ self._lib.PEM_F_PEM_READ_BIO_PRIVATEKEY,
+ self._lib.PEM_R_BAD_PASSWORD_READ
+ )
):
assert not password
raise TypeError(
@@ -797,13 +827,36 @@ class Backend(object):
"Bad decrypt. Incorrect password?"
)
- elif errors[0][1:] == (
- self._lib.ERR_LIB_PEM,
- self._lib.PEM_F_PEM_GET_EVP_CIPHER_INFO,
- self._lib.PEM_R_UNSUPPORTED_ENCRYPTION
+ elif errors[0][1:] in (
+ (
+ self._lib.ERR_LIB_PEM,
+ self._lib.PEM_F_PEM_GET_EVP_CIPHER_INFO,
+ self._lib.PEM_R_UNSUPPORTED_ENCRYPTION
+ ),
+
+ (
+ self._lib.ERR_LIB_EVP,
+ self._lib.EVP_F_EVP_PBE_CIPHERINIT,
+ self._lib.EVP_R_UNKNOWN_PBE_ALGORITHM
+ )
):
raise UnsupportedAlgorithm(
- "PEM data is encrypted with an unsupported cipher")
+ "PEM data is encrypted with an unsupported cipher",
+ _Reasons.UNSUPPORTED_CIPHER
+ )
+
+ elif any(
+ error[1:] == (
+ self._lib.ERR_LIB_EVP,
+ self._lib.EVP_F_EVP_PKCS82PKEY,
+ self._lib.EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM
+ )
+ for error in errors
+ ):
+ raise UnsupportedAlgorithm(
+ "Unsupported public key algorithm.",
+ _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
+ )
else:
assert errors[0][1] in (
diff --git a/cryptography/hazmat/bindings/openssl/err.py b/cryptography/hazmat/bindings/openssl/err.py
index f6456d66..f685e494 100644
--- a/cryptography/hazmat/bindings/openssl/err.py
+++ b/cryptography/hazmat/bindings/openssl/err.py
@@ -135,6 +135,7 @@ static const int EVP_F_PKCS5_V2_PBE_KEYIVGEN;
static const int EVP_F_PKCS8_SET_BROKEN;
static const int EVP_F_RC2_MAGIC_TO_METH;
static const int EVP_F_RC5_CTRL;
+
static const int EVP_R_AES_KEY_SETUP_FAILED;
static const int EVP_R_ASN1_LIB;
static const int EVP_R_BAD_BLOCK_LENGTH;
@@ -168,6 +169,7 @@ static const int EVP_R_UNSUPPORTED_CIPHER;
static const int EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION;
static const int EVP_R_UNSUPPORTED_KEYLENGTH;
static const int EVP_R_UNSUPPORTED_SALT_TYPE;
+static const int EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM;
static const int EVP_R_WRONG_FINAL_BLOCK_LENGTH;
static const int EVP_R_WRONG_PUBLIC_KEY_TYPE;
diff --git a/cryptography/hazmat/primitives/serialization.py b/cryptography/hazmat/primitives/serialization.py
index 38937508..ed73c4c4 100644
--- a/cryptography/hazmat/primitives/serialization.py
+++ b/cryptography/hazmat/primitives/serialization.py
@@ -18,3 +18,9 @@ def load_pem_traditional_openssl_private_key(data, password, backend):
return backend.load_traditional_openssl_pem_private_key(
data, password
)
+
+
+def load_pem_pkcs8_private_key(data, password, backend):
+ return backend.load_pkcs8_pem_private_key(
+ data, password
+ )
diff --git a/docs/hazmat/backends/interfaces.rst b/docs/hazmat/backends/interfaces.rst
index ff389cb5..78a35cd9 100644
--- a/docs/hazmat/backends/interfaces.rst
+++ b/docs/hazmat/backends/interfaces.rst
@@ -263,6 +263,26 @@ A specific ``backend`` may provide one or more of these interfaces.
:returns: ``True`` if the specified ``algorithm`` is supported by this
backend, otherwise ``False``.
+ .. method:: rsa_padding_supported(padding)
+
+ Check if the specified ``padding`` is supported by the backend.
+
+ :param padding: An instance of an
+ :class:`~cryptography.hazmat.primitives.interfaces.AsymmetricPadding`
+ provider.
+
+ :returns: ``True`` if the specified ``padding`` is supported by this
+ backend, otherwise ``False``.
+
+ .. method:: generate_rsa_parameters_supported(public_exponent, key_size)
+
+ Check if the specified parameters are supported for key generation by
+ the backend.
+
+ :param int public_exponent: The public exponent.
+
+ :param int key_size: The bit length of the generated modulus.
+
.. method:: decrypt_rsa(private_key, ciphertext, padding)
:param private_key: An instance of an
diff --git a/docs/hazmat/primitives/asymmetric/serialization.rst b/docs/hazmat/primitives/asymmetric/serialization.rst
index 8d32ae58..2b3eb511 100644
--- a/docs/hazmat/primitives/asymmetric/serialization.rst
+++ b/docs/hazmat/primitives/asymmetric/serialization.rst
@@ -9,6 +9,58 @@ There are several common schemes for serializing asymmetric private and public
keys to bytes. They generally support encryption of private keys and additional
key metadata.
+Many serialization formats support multiple different types of asymmetric keys
+and will return an an instance of the appropriate type. You should check that
+the returned key matches the type your application expects when using these
+methods.
+
+ .. code-block:: pycon
+
+ >>> key = load_pkcs8_private_key(pem_data, None, backend)
+ >>> if isinstance(key, rsa.RSAPrivateKey):
+ >>> signature = sign_with_rsa_key(key, message)
+ >>> elif isinstance(key, dsa.DSAPrivateKey):
+ >>> signature = sign_with_dsa_key(key, message)
+ >>> else:
+ >>> raise TypeError
+
+
+PKCS #8 Format
+~~~~~~~~~~~~~~
+
+PKCS #8 is a serialization format originally standardized by RSA and
+currently maintained by the IETF in :rfc:`5208`. It supports password based
+encryption and additional key metadata attributes.
+
+
+.. function:: load_pkcs8_private_key(data, password, backend)
+
+ .. versionadded:: 0.5
+
+ Deserialize a private key from PEM encoded data to one of the supported
+ asymmetric private key types.
+
+ :param bytes data: The PEM encoded key data.
+
+ :param bytes password: The password to use to decrypt the data. Should
+ be ``None`` if the private key is not encrypted.
+ :param backend: A
+ :class:`~cryptography.hazmat.backends.interfaces.PKCS8SerializationBackend`
+ provider.
+
+ :returns: A new instance of a private key.
+
+ :raises ValueError: If the PEM data could not be decrypted or if its
+ structure could not be decoded successfully.
+
+ :raises TypeError: If a ``password`` was given and the private key was
+ not encrypted. Or if the key was encrypted but no
+ password was supplied.
+
+ :raises UnsupportedAlgorithm: If the serialized key is of a type that
+ is not supported by the backend or if the key is encrypted with a
+ symmetric cipher that is not supported by the backend.
+
Traditional OpenSSL Format
~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/pytest.ini b/pytest.ini
index f717693d..9b44f198 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -9,4 +9,5 @@ markers =
pbkdf2hmac: this test requires a backend providing PBKDF2HMACBackend
rsa: this test requires a backend providing RSABackend
traditional_openssl_serialization: this test requires a backend providing TraditionalOpenSSLSerializationBackend
+ pkcs8_serialization: this test requires a backend providing PKCS8SerializationBackend
supported: parametrized test requiring only_if and skip_message
diff --git a/tests/conftest.py b/tests/conftest.py
index 86d5a03b..b1326dc8 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -18,7 +18,8 @@ import pytest
from cryptography.hazmat.backends import _available_backends
from cryptography.hazmat.backends.interfaces import (
CMACBackend, CipherBackend, DSABackend, HMACBackend, HashBackend,
- PBKDF2HMACBackend, RSABackend, TraditionalOpenSSLSerializationBackend
+ PBKDF2HMACBackend, PKCS8SerializationBackend, RSABackend,
+ TraditionalOpenSSLSerializationBackend
)
from .utils import check_backend_support, check_for_iface, select_backends
@@ -45,6 +46,11 @@ def pytest_runtest_setup(item):
TraditionalOpenSSLSerializationBackend,
item
)
+ check_for_iface(
+ "pkcs8_serialization",
+ PKCS8SerializationBackend,
+ item
+ )
check_backend_support(item)
diff --git a/tests/hazmat/backends/test_multibackend.py b/tests/hazmat/backends/test_multibackend.py
index 088465a1..3fa364e2 100644
--- a/tests/hazmat/backends/test_multibackend.py
+++ b/tests/hazmat/backends/test_multibackend.py
@@ -101,6 +101,12 @@ class DummyRSABackend(object):
def mgf1_hash_supported(self, algorithm):
pass
+ def rsa_padding_supported(self, padding):
+ pass
+
+ def generate_rsa_parameters_supported(self, public_exponent, key_size):
+ pass
+
def decrypt_rsa(self, private_key, ciphertext, padding):
pass
@@ -222,6 +228,10 @@ class TestMultiBackend(object):
backend.mgf1_hash_supported(hashes.MD5())
+ backend.rsa_padding_supported(padding.PKCS1v15())
+
+ backend.generate_rsa_parameters_supported(65537, 1024)
+
backend.encrypt_rsa("public_key", "encryptme", padding.PKCS1v15())
backend.decrypt_rsa("private_key", "encrypted", padding.PKCS1v15())
@@ -252,6 +262,16 @@ class TestMultiBackend(object):
with raises_unsupported_algorithm(
_Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
):
+ backend.rsa_padding_supported(padding.PKCS1v15())
+
+ with raises_unsupported_algorithm(
+ _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
+ ):
+ backend.generate_rsa_parameters_supported(65537, 1024)
+
+ with raises_unsupported_algorithm(
+ _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
+ ):
backend.encrypt_rsa("public_key", "encryptme", padding.PKCS1v15())
with raises_unsupported_algorithm(
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py
index 19274bf8..0ccf7286 100644
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -43,11 +43,20 @@ class DummyCipher(object):
name = "dummy-cipher"
+@utils.register_interface(interfaces.AsymmetricPadding)
+class DummyPadding(object):
+ name = "dummy-cipher"
+
+
@utils.register_interface(interfaces.HashAlgorithm)
class DummyHash(object):
name = "dummy-hash"
+class DummyMGF(object):
+ _salt_length = 0
+
+
class TestOpenSSL(object):
def test_backend_exists(self):
assert backend
@@ -151,15 +160,6 @@ class TestOpenSSL(object):
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_HASH):
backend.derive_pbkdf2_hmac(hashes.SHA256(), 10, b"", 1000, b"")
- # This test is not in the TestOpenSSLRandomEngine class because to check
- # if it's really default we don't want to run the setup_method before it
- def test_osrandom_engine_is_default(self):
- e = backend._lib.ENGINE_get_default_RAND()
- name = backend._lib.ENGINE_get_name(e)
- assert name == backend._lib.Cryptography_osrandom_engine_name
- res = backend._lib.ENGINE_free(e)
- assert res == 1
-
@pytest.mark.skipif(
backend._lib.OPENSSL_VERSION_NUMBER >= 0x1000000f,
reason="Requires an older OpenSSL. Must be < 1.0.0"
@@ -181,6 +181,25 @@ class TestOpenSSL(object):
parameters = dsa.DSAParameters.generate(3072, backend)
assert utils.bit_length(parameters.p) == 3072
+ def test_int_to_bn(self):
+ value = (2 ** 4242) - 4242
+ bn = backend._int_to_bn(value)
+ assert bn != backend._ffi.NULL
+ bn = backend._ffi.gc(bn, backend._lib.BN_free)
+
+ assert bn
+ assert backend._bn_to_int(bn) == value
+
+ def test_int_to_bn_inplace(self):
+ value = (2 ** 4242) - 4242
+ bn_ptr = backend._lib.BN_new()
+ assert bn_ptr != backend._ffi.NULL
+ bn_ptr = backend._ffi.gc(bn_ptr, backend._lib.BN_free)
+ bn = backend._int_to_bn(value, bn_ptr)
+
+ assert bn == bn_ptr
+ assert backend._bn_to_int(bn_ptr) == value
+
class TestOpenSSLRandomEngine(object):
def teardown_method(self, method):
@@ -191,6 +210,15 @@ class TestOpenSSLRandomEngine(object):
name = backend._lib.ENGINE_get_name(current_default)
assert name == backend._lib.Cryptography_osrandom_engine_name
+ # This must be the first test in the class so that the teardown method
+ # has not (potentially) altered the default engine.
+ def test_osrandom_engine_is_default(self):
+ e = backend._lib.ENGINE_get_default_RAND()
+ name = backend._lib.ENGINE_get_name(e)
+ assert name == backend._lib.Cryptography_osrandom_engine_name
+ res = backend._lib.ENGINE_free(e)
+ assert res == 1
+
def test_osrandom_sanity_check(self):
# This test serves as a check against catastrophic failure.
buf = backend._ffi.new("char[]", 500)
@@ -241,27 +269,14 @@ class TestOpenSSLRandomEngine(object):
e = backend._lib.ENGINE_get_default_RAND()
assert e == backend._ffi.NULL
- def test_int_to_bn(self):
- value = (2 ** 4242) - 4242
- bn = backend._int_to_bn(value)
- assert bn != backend._ffi.NULL
- bn = backend._ffi.gc(bn, backend._lib.BN_free)
-
- assert bn
- assert backend._bn_to_int(bn) == value
-
- def test_int_to_bn_inplace(self):
- value = (2 ** 4242) - 4242
- bn_ptr = backend._lib.BN_new()
- assert bn_ptr != backend._ffi.NULL
- bn_ptr = backend._ffi.gc(bn_ptr, backend._lib.BN_free)
- bn = backend._int_to_bn(value, bn_ptr)
-
- assert bn == bn_ptr
- assert backend._bn_to_int(bn_ptr) == value
-
class TestOpenSSLRSA(object):
+ def test_generate_rsa_parameters_supported(self):
+ assert backend.generate_rsa_parameters_supported(1, 1024) is False
+ assert backend.generate_rsa_parameters_supported(4, 1024) is False
+ assert backend.generate_rsa_parameters_supported(3, 1024) is True
+ assert backend.generate_rsa_parameters_supported(3, 511) is False
+
@pytest.mark.skipif(
backend._lib.OPENSSL_VERSION_NUMBER >= 0x1000100f,
reason="Requires an older OpenSSL. Must be < 1.0.1"
@@ -300,6 +315,44 @@ class TestOpenSSLRSA(object):
def test_unsupported_mgf1_hash_algorithm(self):
assert backend.mgf1_hash_supported(DummyHash()) is False
+ def test_rsa_padding_unsupported_pss_mgf1_hash(self):
+ assert backend.rsa_padding_supported(
+ padding.PSS(mgf=padding.MGF1(DummyHash()), salt_length=0)
+ ) is False
+
+ def test_rsa_padding_unsupported(self):
+ assert backend.rsa_padding_supported(DummyPadding()) is False
+
+ def test_rsa_padding_supported_pkcs1v15(self):
+ assert backend.rsa_padding_supported(padding.PKCS1v15()) is True
+
+ def test_rsa_padding_supported_pss(self):
+ assert backend.rsa_padding_supported(
+ padding.PSS(mgf=padding.MGF1(hashes.SHA1()), salt_length=0)
+ ) is True
+
+ def test_rsa_padding_supported_oaep(self):
+ assert backend.rsa_padding_supported(
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA1()),
+ algorithm=hashes.SHA1(),
+ label=None
+ ),
+ ) is True
+
+ def test_rsa_padding_unsupported_mgf(self):
+ assert backend.rsa_padding_supported(
+ padding.OAEP(
+ mgf=DummyMGF(),
+ algorithm=hashes.SHA1(),
+ label=None
+ ),
+ ) is False
+
+ assert backend.rsa_padding_supported(
+ padding.PSS(mgf=DummyMGF(), salt_length=0)
+ ) is False
+
def test_unsupported_mgf1_hash_algorithm_decrypt(self):
private_key = rsa.RSAPrivateKey.generate(
public_exponent=65537,
diff --git a/tests/hazmat/primitives/fixtures_rsa.py b/tests/hazmat/primitives/fixtures_rsa.py
new file mode 100644
index 00000000..494b9942
--- /dev/null
+++ b/tests/hazmat/primitives/fixtures_rsa.py
@@ -0,0 +1,493 @@
+# icensed under the Apache icense, Version 2.0 (the "icense");
+# you may not use this file except in compliance with the icense.
+# You may obtain a copy of the icense at
+#
+# http://www.apache.org/licenses/ICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the icense is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the icense for the specific language governing permissions and
+# limitations under the icense.
+
+
+from __future__ import absolute_import, division, print_function
+
+
+RSA_KEY_512 = {
+ "p": int(
+ "d57846898d5c0de249c08467586cb458fa9bc417cdf297f73cfc52281b787cd9", 16
+ ),
+ "q": int(
+ "d10f71229e87e010eb363db6a85fd07df72d985b73c42786191f2ce9134afb2d", 16
+ ),
+ "private_exponent": int(
+ "272869352cacf9c866c4e107acc95d4c608ca91460a93d28588d51cfccc07f449"
+ "18bbe7660f9f16adc2b4ed36ca310ef3d63b79bd447456e3505736a45a6ed21", 16
+ ),
+ "dmp1": int(
+ "addff2ec7564c6b64bc670d250b6f24b0b8db6b2810099813b7e7658cecf5c39", 16
+ ),
+ "dmq1": int(
+ "463ae9c6b77aedcac1397781e50e4afc060d4b216dc2778494ebe42a6850c81", 16
+ ),
+ "iqmp": int(
+ "54deef8548f65cad1d411527a32dcb8e712d3e128e4e0ff118663fae82a758f4", 16
+ ),
+ "public_exponent": 65537,
+ "modulus": int(
+ "ae5411f963c50e3267fafcf76381c8b1e5f7b741fdb2a544bcf48bd607b10c991"
+ "90caeb8011dc22cf83d921da55ec32bd05cac3ee02ca5e1dbef93952850b525", 16
+ ),
+}
+
+RSA_KEY_512_ALT = {
+ "p": int(
+ "febe19c29a0b50fefa4f7b1832f84df1caf9be8242da25c9d689e18226e67ce5",
+ 16),
+ "q": int(
+ "eb616c639dd999feda26517e1c77b6878f363fe828c4e6670ec1787f28b1e731",
+ 16),
+ "private_exponent": int(
+ "80edecfde704a806445a4cc782b85d3f36f17558f385654ea767f006470fdfcbda5e2"
+ "206839289d3f419b4e4fb8e1acee1b4fb9c591f69b64ec83937f5829241", 16),
+ "dmp1": int(
+ "7f4fa06e2a3077a54691cc5216bf13ad40a4b9fa3dd0ea4bca259487484baea5",
+ 16),
+ "dmq1": int(
+ "35eaa70d5a8711c352ed1c15ab27b0e3f46614d575214535ae279b166597fac1",
+ 16),
+ "iqmp": int(
+ "cc1f272de6846851ec80cb89a02dbac78f44b47bc08f53b67b4651a3acde8b19",
+ 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "ea397388b999ef0f7e7416fa000367efd9a0ba0deddd3f8160d1c36d62267f210fbd9"
+ "c97abeb6654450ff03e7601b8caa6c6f4cba18f0b52c179d17e8f258ad5", 16),
+}
+
+RSA_KEY_522 = {
+ "p": int(
+ "1a8aab9a069f92b52fdf05824f2846223dc27adfc806716a247a77d4c36885e4bf",
+ 16),
+ "q": int(
+ "19e8d620d177ec54cdb733bb1915e72ef644b1202b889ceb524613efa49c07eb4f",
+ 16),
+ "private_exponent": int(
+ "10b8a7c0a92c1ae2d678097d69db3bfa966b541fb857468291d48d1b52397ea2bac0d"
+ "4370c159015c7219e3806a01bbafaffdd46f86e3da1e2d1fe80a0369ccd745", 16),
+ "dmp1": int(
+ "3eb6277f66e6e2dcf89f1b8529431f730839dbd9a3e49555159bc8470eee886e5",
+ 16),
+ "dmq1": int(
+ "184b4d74aa54c361e51eb23fee4eae5e4786b37b11b6e0447af9c0b9c4e4953c5b",
+ 16),
+ "iqmp": int(
+ "f80e9ab4fa7b35d0d232ef51c4736d1f2dcf2c7b1dd8716211b1bf1337e74f8ae",
+ 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "2afaea0e0bb6fca037da7d190b5270a6c665bc18e7a456f7e69beaac4433db748ba99"
+ "acdd14697e453bca596eb35b47f2d48f1f85ef08ce5109dad557a9cf85ebf1", 16),
+}
+
+RSA_KEY_599 = {
+ "p": int(
+ "cf95d20be0c7af69f4b3d909f65d858c26d1a7ef34da8e3977f4fa230580e58814b54"
+ "24be99", 16),
+ "q": int(
+ "6052be4b28debd4265fe12ace5aa4a0c4eb8d63ff8853c66824b35622161eb48a3bc8"
+ "c3ada5", 16),
+ "private_exponent": int(
+ "69d9adc465e61585d3142d7cc8dd30605e8d1cbbf31009bc2cd5538dc40528d5d68ee"
+ "fe6a42d23674b6ec76e192351bf368c8968f0392110bf1c2825dbcff071270b80adcc"
+ "fa1d19d00a1", 16),
+ "dmp1": int(
+ "a86d10edde456687fba968b1f298d2e07226adb1221b2a466a93f3d83280f0bb46c20"
+ "2b6811", 16),
+ "dmq1": int(
+ "40d570e08611e6b1da94b95d46f8e7fe80be48f7a5ff8838375b08039514a399b11c2"
+ "80735", 16),
+ "iqmp": int(
+ "cd051cb0ea68b88765c041262ace2ec4db11dab14afd192742e34d5da3328637fabdf"
+ "bae26e", 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "4e1b470fe00642426f3808e74c959632dd67855a4c503c5b7876ccf4dc7f6a1a49107"
+ "b90d26daf0a7879a6858218345fbc6e59f01cd095ca5647c27c25265e6c474fea8953"
+ "7191c7073d9d", 16),
+}
+
+RSA_KEY_745 = {
+ "p": int(
+ "1c5a0cfe9a86debd19eca33ba961f15bc598aa7983a545ce775b933afc89eb51bcf90"
+ "836257fdd060d4b383240241d", 16
+ ),
+ "q": int(
+ "fb2634f657f82ee6b70553382c4e2ed26b947c97ce2f0016f1b282cf2998184ad0527"
+ "a9eead826dd95fe06b57a025", 16
+ ),
+ "private_exponent": int(
+ "402f30f976bc07d15ff0779abff127b20a8b6b1d0024cc2ad8b6762d38f174f81e792"
+ "3b49d80bdbdd80d9675cbc7b2793ec199a0430eb5c84604dacfdb29259ae6a1a44676"
+ "22f0b23d4cb0f5cb1db4b8173c8d9d3e57a74dbd200d2141", 16),
+ "dmp1": int(
+ "e5e95b7751a6649f199be21bef7a51c9e49821d945b6fc5f538b4a670d8762c375b00"
+ "8e70f31d52b3ea2bd14c3101", 16),
+ "dmq1": int(
+ "12b85d5843645f72990fcf8d2f58408b34b3a3b9d9078dd527fceb5d2fb7839008092"
+ "dd4aca2a1fb00542801dcef5", 16),
+ "iqmp": int(
+ "5672740d947f621fc7969e3a44ec26736f3f819863d330e63e9409e139d20753551ac"
+ "c16544dd2bdadb9dee917440", 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "1bd085f92237774d34013b477ceebbb2f2feca71118db9b7429341477947e7b1d04e8"
+ "c43ede3c52bb25781af58d4ff81289f301eac62dc3bcd7dafd7a4d5304e9f308e7669"
+ "52fbf2b62373e66611fa53189987dbef9f7243dcbbeb25831", 16),
+}
+
+RSA_KEY_768 = {
+ "p": int(
+ "f80c0061b607f93206b68e208906498d68c6e396faf457150cf975c8f849848465869"
+ "7ecd402313397088044c4c2071b", 16),
+ "q": int(
+ "e5b5dbecc93c6d306fc14e6aa9737f9be2728bc1a326a8713d2849b34c1cb54c63468"
+ "3a68abb1d345dbf15a3c492cf55", 16),
+ "private_exponent": int(
+ "d44601442255ffa331212c60385b5e898555c75c0272632ff42d57c4b16ca97dbca9f"
+ "d6d99cd2c9fd298df155ed5141b4be06c651934076133331d4564d73faed7ce98e283"
+ "2f7ce3949bc183be7e7ca34f6dd04a9098b6c73649394b0a76c541", 16),
+ "dmp1": int(
+ "a5763406fa0b65929661ce7b2b8c73220e43a5ebbfe99ff15ddf464fd238105ad4f2a"
+ "c83818518d70627d8908703bb03", 16),
+ "dmq1": int(
+ "cb467a9ef899a39a685aecd4d0ad27b0bfdc53b68075363c373d8eb2bed8eccaf3533"
+ "42f4db735a9e087b7539c21ba9d", 16),
+ "iqmp": int(
+ "5fe86bd3aee0c4d09ef11e0530a78a4534c9b833422813b5c934a450c8e564d8097a0"
+ "6fd74f1ebe2d5573782093f587a", 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "de92f1eb5f4abf426b6cac9dd1e9bf57132a4988b4ed3f8aecc15e251028bd6df46eb"
+ "97c711624af7db15e6430894d1b640c13929329241ee094f5a4fe1a20bc9b75232320"
+ "a72bc567207ec54d6b48dccb19737cf63acc1021abb337f19130f7", 16),
+}
+
+RSA_KEY_1024 = {
+ "p": int(
+ "ea4d9d9a1a068be44b9a5f8f6de0512b2c5ba1fb804a4655babba688e6e890b347c1a"
+ "7426685a929337f513ae4256f0b7e5022d642237f960c5b24b96bee8e51", 16),
+ "q": int(
+ "cffb33e400d6f08b410d69deb18a85cf0ed88fcca9f32d6f2f66c62143d49aff92c11"
+ "4de937d4f1f62d4635ee89af99ce86d38a2b05310f3857c7b5d586ac8f9", 16),
+ "private_exponent": int(
+ "3d12d46d04ce942fb99be7bf30587b8cd3e21d75a2720e7bda1b867f1d418d91d8b9f"
+ "e1c00181fdde94f2faf33b4e6f800a1b3ae3b972ccb6d5079dcb6c794070ac8306d59"
+ "c00b58b7a9a81122a6b055832de7c72334a07494d8e7c9fbeed2cc37e011d9e6bfc6e"
+ "9bcddbef7f0f5771d9cf82cd4b268c97ec684575c24b6c881", 16),
+ "dmp1": int(
+ "470f2b11257b7ec9ca34136f487f939e6861920ad8a9ae132a02e74af5dceaa5b4c98"
+ "2949ccb44b67e2bcad2f58674db237fe250e0d62b47b28fa1dfaa603b41", 16),
+ "dmq1": int(
+ "c616e8317d6b3ae8272973709b80e8397256697ff14ea03389de454f619f99915a617"
+ "45319fefbe154ec1d49441a772c2f63f7d15c478199afc60469bfd0d561", 16),
+ "iqmp": int(
+ "d15e7c9ad357dfcd5dbdc8427680daf1006761bcfba93a7f86589ad88832a8d564b1c"
+ "d4291a658c96fbaea7ca588795820902d85caebd49c2d731e3fe0243130", 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "be5aac07456d990133ebce69c06b48845b972ab1ad9f134bc5683c6b5489b5119ede0"
+ "7be3bed0e355d48e0dfab1e4fb5187adf42d7d3fb0401c082acb8481bf17f0e871f88"
+ "77be04c3a1197d40aa260e2e0c48ed3fd2b93dc3fc0867591f67f3cd60a77adee1d68"
+ "a8c3730a5702485f6ac9ede7f0fd2918e037ee4cc1fc1b4c9", 16),
+}
+
+RSA_KEY_1025 = {
+ "p": int(
+ "18e9bfb7071725da04d31c103fa3563648c69def43a204989214eb57b0c8b299f9ef3"
+ "5dda79a62d8d67fd2a9b69fbd8d0490aa2edc1e111a2b8eb7c737bb691a5", 16),
+ "q": int(
+ "d8eccaeeb95815f3079d13685f3f72ca2bf2550b349518049421375df88ca9bbb4ba8"
+ "cb0e3502203c9eeae174112509153445d251313e4711a102818c66fcbb7", 16),
+ "private_exponent": int(
+ "fe9ac54910b8b1bc948a03511c54cab206a1d36d50d591124109a48abb7480977ccb0"
+ "47b4d4f1ce7b0805df2d4fa3fe425f49b78535a11f4b87a4eba0638b3340c23d4e6b2"
+ "1ecebe9d5364ea6ead2d47b27836019e6ecb407000a50dc95a8614c9d0031a6e3a524"
+ "d2345cfb76e15c1f69d5ba35bdfb6ec63bcb115a757ef79d9", 16),
+ "dmp1": int(
+ "18537e81006a68ea76d590cc88e73bd26bc38d09c977959748e5265c0ce21c0b5fd26"
+ "53d975f97ef759b809f791487a8fff1264bf561627fb4527a3f0bbb72c85", 16),
+ "dmq1": int(
+ "c807eac5a1f1e1239f04b04dd16eff9a00565127a91046fa89e1eb5d6301cace85447"
+ "4d1f47b0332bd35b4214b66e9166953241538f761f30d969272ee214f17", 16),
+ "iqmp": int(
+ "133aa74dd41fe70fa244f07d0c4091a22f8c8f0134fe6aea9ec8b55383b758fefe358"
+ "2beec36eca91715eee7d21931f24fa9e97e8e3a50f9cd0f731574a5eafcc", 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "151c44fed756370fb2d4a0e6ec7dcac84068ca459b6aaf22daf902dca72c77563bf27"
+ "6fe3523f38f5ddaf3ea9aa88486a9d8760ff732489075862bee0e599de5c5f509b451"
+ "9f4f446521bad15cd279a498fe1e89107ce0d237e3103d7c5eb80166642e2924b152a"
+ "ebff97b71fdd2d68ebb45034cc784e2e822ff6d1edf98af3f3", 16),
+}
+
+RSA_KEY_1026 = {
+ "p": int(
+ "1fcbfb8719c5bdb5fe3eb0937c76bb096e750b9442dfe31d6a877a13aed2a6a4e9f79"
+ "40f815f1c307dd6bc2b4b207bb6fe5be3a15bd2875a957492ce197cdedb1", 16),
+ "q": int(
+ "1f704a0f6b8966dd52582fdc08227dd3dbaeaa781918b41144b692711091b4ca4eb62"
+ "985c3513853828ce8739001dfba9a9a7f1a23cbcaf74280be925e2e7b50d", 16),
+ "private_exponent": int(
+ "c67975e35a1d0d0b3ebfca736262cf91990cb31cf4ac473c0c816f3bc2720bcba2475"
+ "e8d0de8535d257816c0fc53afc1b597eada8b229069d6ef2792fc23f59ffb4dc6c3d9"
+ "0a3c462082025a4cba7561296dd3d8870c4440d779406f00879afe2c681e7f5ee055e"
+ "ff829e6e55883ec20830c72300762e6e3a333d94b4dbe4501", 16),
+ "dmp1": int(
+ "314730ca7066c55d086a9fbdf3670ef7cef816b9efea8b514b882ae9d647217cf41d7"
+ "e9989269dc9893d02e315cb81f058c49043c2cac47adea58bdf5e20e841", 16),
+ "dmq1": int(
+ "1da28a9d687ff7cfeebc2439240de7505a8796376968c8ec723a2b669af8ce53d9c88"
+ "af18540bd78b2da429014923fa435f22697ac60812d7ca9c17a557f394cd", 16),
+ "iqmp": int(
+ "727947b57b8a36acd85180522f1b381bce5fdbd962743b3b14af98a36771a80f58ddd"
+ "62675d72a5935190da9ddc6fd6d6d5e9e9f805a2e92ab8d56b820493cdf", 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "3e7a5e6483e55eb8b723f9c46732d21b0af9e06a4a1099962d67a35ee3f62e3129cfa"
+ "e6ab0446da18e26f33e1d753bc1cc03585c100cf0ab5ef056695706fc8b0c9c710cd7"
+ "3fe6e5beda70f515a96fabd3cc5ac49efcb2594b220ff3b603fcd927f6a0838ef04bf"
+ "52f3ed9eab801f09e5aed1613ddeb946ed0fbb02060b3a36fd", 16),
+}
+
+RSA_KEY_1027 = {
+ "p": int(
+ "30135e54cfb072c3d3eaf2000f3ed92ceafc85efc867b9d4bf5612f2978c432040093"
+ "4829f741c0f002b54af2a4433ff872b6321ef00ff1e72cba4e0ced937c7d", 16),
+ "q": int(
+ "1d01a8aead6f86b78c875f18edd74214e06535d65da054aeb8e1851d6f3319b4fb6d8"
+ "6b01e07d19f8261a1ded7dc08116345509ab9790e3f13e65c037e5bb7e27", 16),
+ "private_exponent": int(
+ "21cf4477df79561c7818731da9b9c88cd793f1b4b8e175bd0bfb9c0941a4dc648ecf1"
+ "6d96b35166c9ea116f4c2eb33ce1c231e641a37c25e54c17027bdec08ddafcb83642e"
+ "795a0dd133155ccc5eed03b6e745930d9ac7cfe91f9045149f33295af03a2198c660f"
+ "08d8150d13ce0e2eb02f21ac75d63b55822f77bd5be8d07619", 16),
+ "dmp1": int(
+ "173fb695931e845179511c18b546b265cb79b517c135902377281bdf9f34205e1f399"
+ "4603ad63e9f6e7885ea73a929f03fa0d6bed943051ce76cddde2d89d434d", 16),
+ "dmq1": int(
+ "10956b387b2621327da0c3c8ffea2af8be967ee25163222746c28115a406e632a7f12"
+ "5a9397224f1fa5c116cd3a313e5c508d31db2deb83b6e082d213e33f7fcf", 16),
+ "iqmp": int(
+ "234f833949f2c0d797bc6a0e906331e17394fa8fbc8449395766d3a8d222cf6167c48"
+ "8e7fe1fe9721d3e3b699a595c8e6f063d92bd840dbc84d763b2b37002109", 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "57281707d7f9b1369c117911758980e32c05b133ac52c225bcf68b79157ff47ea0a5a"
+ "e9f579ef1fd7e42937f921eb3123c4a045cc47a2159fbbf904783e654954c42294c30"
+ "a95c15db7c7b91f136244e548f62474b137087346c5522e54f226f49d6c93bc58cb39"
+ "972e41bde452bb3ae9d60eb93e5e1ce91d222138d9890c7d0b", 16),
+}
+
+RSA_KEY_1028 = {
+ "p": int(
+ "359d17378fae8e9160097daee78a206bd52efe1b757c12a6da8026cc4fc4bb2620f12"
+ "b8254f4db6aed8228be8ee3e5a27ec7d31048602f01edb00befd209e8c75", 16),
+ "q": int(
+ "33a2e70b93d397c46e63b273dcd3dcfa64291342a6ce896e1ec8f1c0edc44106550f3"
+ "c06e7d3ca6ea29eccf3f6ab5ac6235c265313d6ea8e8767e6a343f616581", 16),
+ "private_exponent": int(
+ "880640088d331aa5c0f4cf2887809a420a2bc086e671e6ffe4e47a8c80792c038a314"
+ "9a8e45ef9a72816ab45b36e3af6800351067a6b2751843d4232413146bb575491463a"
+ "8addd06ce3d1bcf7028ec6c5d938c545a20f0a40214b5c574ca7e840062b2b5f8ed49"
+ "4b144bb2113677c4b10519177fee1d4f5fb8a1c159b0b47c01", 16),
+ "dmp1": int(
+ "75f8c52dad2c1cea26b8bba63236ee4059489e3d2db766136098bcc6b67fde8f77cd3"
+ "640035107bfb1ffc6480983cfb84fe0c3be008424ebc968a7db7e01f005", 16),
+ "dmq1": int(
+ "3893c59469e4ede5cd0e6ff9837ca023ba9b46ff40c60ccf1bec10f7d38db5b1ba817"
+ "6c41a3f750ec4203b711455aca06d1e0adffc5cffa42bb92c7cb77a6c01", 16),
+ "iqmp": int(
+ "ad32aafae3c962ac25459856dc8ef1f733c3df697eced29773677f435d186cf759d1a"
+ "5563dd421ec47b4d7e7f12f29647c615166d9c43fc49001b29089344f65", 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "ad0696bef71597eb3a88e135d83c596930cac73868fbd7e6b2d64f34eea5c28cce351"
+ "0c68073954d3ba4deb38643e7a820a4cf06e75f7f82eca545d412bd63781945c28d40"
+ "6e95a6cced5ae924a8bfa4f3def3e0250d91246c269ec40c89c93a85acd3770ba4d2e"
+ "774732f43abe94394de43fb57f93ca25f7a59d75d400a3eff5", 16),
+}
+
+RSA_KEY_1029 = {
+ "p": int(
+ "66f33e513c0b6b6adbf041d037d9b1f0ebf8de52812a3ac397a963d3f71ba64b3ad04"
+ "e4d4b5e377e6fa22febcac292c907dc8dcfe64c807fd9a7e3a698850d983", 16),
+ "q": int(
+ "3b47a89a19022461dcc2d3c05b501ee76955e8ce3cf821beb4afa85a21a26fd7203db"
+ "deb8941f1c60ada39fd6799f6c07eb8554113f1020460ec40e93cd5f6b21", 16),
+ "private_exponent": int(
+ "280c42af8b1c719821f2f6e2bf5f3dd53c81b1f3e1e7cc4fce6e2f830132da0665bde"
+ "bc1e307106b112b52ad5754867dddd028116cf4471bc14a58696b99524b1ad8f05b31"
+ "cf47256e54ab4399b6a073b2c0452441438dfddf47f3334c13c5ec86ece4d33409056"
+ "139328fafa992fb5f5156f25f9b21d3e1c37f156d963d97e41", 16),
+ "dmp1": int(
+ "198c7402a4ec10944c50ab8488d7b5991c767e75eb2817bd427dff10335ae141fa2e8"
+ "7c016dc22d975cac229b9ffdf7d943ddfd3a04b8bf82e83c3b32c5698b11", 16),
+ "dmq1": int(
+ "15fd30c7687b68ef7c2a30cdeb913ec56c4757c218cf9a04d995470797ee5f3a17558"
+ "fbb6d00af245d2631d893b382da48a72bc8a613024289895952ab245b0c1", 16),
+ "iqmp": int(
+ "4f8fde17e84557a3f4e242d889e898545ab55a1a8e075c9bb0220173ccffe84659abe"
+ "a235104f82e32750309389d4a52af57dbb6e48d831917b6efeb190176570", 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "17d6e0a09aa5b2d003e51f43b9c37ffde74688f5e3b709fd02ef375cb6b8d15e299a9"
+ "f74981c3eeaaf947d5c2d64a1a80f5c5108a49a715c3f7be95a016b8d3300965ead4a"
+ "4df76e642d761526803e9434d4ec61b10cb50526d4dcaef02593085ded8c331c1b27b"
+ "200a45628403065efcb2c0a0ca1f75d648d40a007fbfbf2cae3", 16),
+}
+
+RSA_KEY_1030 = {
+ "p": int(
+ "6f4ac8a8172ef1154cf7f80b5e91de723c35a4c512860bfdbafcc3b994a2384bf7796"
+ "3a2dd0480c7e04d5d418629651a0de8979add6f47b23da14c27a682b69c9", 16),
+ "q": int(
+ "65a9f83e07dea5b633e036a9dccfb32c46bf53c81040a19c574c3680838fc6d28bde9"
+ "55c0ff18b30481d4ab52a9f5e9f835459b1348bbb563ad90b15a682fadb3", 16),
+ "private_exponent": int(
+ "290db707b3e1a96445ae8ea93af55a9f211a54ebe52995c2eb28085d1e3f09c986e73"
+ "a00010c8e4785786eaaa5c85b98444bd93b585d0c24363ccc22c482e150a3fd900176"
+ "86968e4fa20423ae72823b0049defceccb39bb34aa4ef64e6b14463b76d6a871c859e"
+ "37285455b94b8e1527d1525b1682ac6f7c8fd79d576c55318c1", 16),
+ "dmp1": int(
+ "23f7fa84010225dea98297032dac5d45745a2e07976605681acfe87e0920a8ab3caf5"
+ "9d9602f3d63dc0584f75161fd8fff20c626c21c5e02a85282276a74628a9", 16),
+ "dmq1": int(
+ "18ebb657765464a8aa44bf019a882b72a2110a77934c54915f70e6375088b10331982"
+ "962bce1c7edd8ef9d3d95aa2566d2a99da6ebab890b95375919408d00f33", 16),
+ "iqmp": int(
+ "3d59d208743c74054151002d77dcdfc55af3d41357e89af88d7eef2767be54c290255"
+ "9258d85cf2a1083c035a33e65a1ca46dc8b706847c1c6434cef7b71a9dae", 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "2c326574320818a6a8cb6b3328e2d6c1ba2a3f09b6eb2bc543c03ab18eb5efdaa8fcd"
+ "bb6b4e12168304f587999f9d96a421fc80cb933a490df85d25883e6a88750d6bd8b3d"
+ "4117251eee8f45e70e6daac7dbbd92a9103c623a09355cf00e3f16168e38b9c4cb5b3"
+ "68deabbed8df466bc6835eaba959bc1c2f4ec32a09840becc8b", 16),
+}
+
+RSA_KEY_1031 = {
+ "p": int(
+ "c0958c08e50137db989fb7cc93abf1984543e2f955d4f43fb2967f40105e79274c852"
+ "293fa06ce63ca8436155e475ed6d1f73fea4c8e2516cc79153e3dc83e897", 16),
+ "q": int(
+ "78cae354ea5d6862e5d71d20273b7cddb8cdfab25478fe865180676b04250685c4d03"
+ "30c216574f7876a7b12dfe69f1661d3b0cea6c2c0dcfb84050f817afc28d", 16),
+ "private_exponent": int(
+ "1d55cc02b17a5d25bfb39f2bc58389004d0d7255051507f75ef347cdf5519d1a00f4b"
+ "d235ce4171bfab7bdb7a6dcfae1cf41433fb7da5923cc84f15a675c0b83492c95dd99"
+ "a9fc157aea352ffdcbb5d59dbc3662171d5838d69f130678ee27841a79ef64f679ce9"
+ "3821fa69c03f502244c04b737edad8967def8022a144feaab29", 16),
+ "dmp1": int(
+ "5b1c2504ec3a984f86b4414342b5bcf59a0754f13adf25b2a0edbc43f5ba8c3cc061d"
+ "80b03e5866d059968f0d10a98deaeb4f7830436d76b22cf41f2914e13eff", 16),
+ "dmq1": int(
+ "6c361e1819691ab5d67fb2a8f65c958d301cdf24d90617c68ec7005edfb4a7b638cde"
+ "79d4b61cfba5c86e8c0ccf296bc7f611cb8d4ae0e072a0f68552ec2d5995", 16),
+ "iqmp": int(
+ "b7d61945fdc8b92e075b15554bab507fa8a18edd0a18da373ec6c766c71eece61136a"
+ "84b90b6d01741d40458bfad17a9bee9d4a8ed2f6e270782dc3bf5d58b56e", 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "5adebaa926ea11fb635879487fdd53dcfbb391a11ac7279bb3b4877c9b811370a9f73"
+ "da0690581691626d8a7cf5d972cced9c2091ccf999024b23b4e6dc6d99f80a454737d"
+ "ec0caffaebe4a3fac250ed02079267c8f39620b5ae3e125ca35338522dc9353ecac19"
+ "cb2fe3b9e3a9291619dbb1ea3a7c388e9ee6469fbf5fb22892b", 16),
+}
+
+RSA_KEY_1536 = {
+ "p": int(
+ "f1a65fa4e2aa6e7e2b560251e8a4cd65b625ad9f04f6571785782d1c213d91c961637"
+ "0c572f2783caf2899f7fb690cf99a0184257fbd4b071b212c88fb348279a5387e61f1"
+ "17e9c62980c45ea863fa9292087c0f66ecdcde6443d5a37268bf71", 16),
+ "q": int(
+ "e54c2cbc3839b1da6ae6fea45038d986d6f523a3ae76051ba20583aab711ea5965cf5"
+ "3cf54128cc9573f7460bba0fd6758a57aaf240c391790fb38ab473d83ef735510c53d"
+ "1d10c31782e8fd7da42615e33565745c30a5e6ceb2a3ae0666cc35", 16),
+ "private_exponent": int(
+ "7bcad87e23da2cb2a8c328883fabce06e1f8e9b776c8bf253ad9884e6200e3bd9bd3b"
+ "a2cbe87d3854527bf005ba5d878c5b0fa20cfb0a2a42884ae95ca12bf7304285e9214"
+ "5e992f7006c7c0ae839ad550da495b143bec0f4806c7f44caed45f3ccc6dc44cfaf30"
+ "7abdb757e3d28e41c2d21366835c0a41e50a95af490ac03af061d2feb36ac0afb87be"
+ "a13fb0f0c5a410727ebedb286c77f9469473fae27ef2c836da6071ef7efc1647f1233"
+ "4009a89eecb09a8287abc8c2afd1ddd9a1b0641", 16),
+ "dmp1": int(
+ "a845366cd6f9df1f34861bef7594ed025aa83a12759e245f58adaa9bdff9c3befb760"
+ "75d3701e90038e888eec9bf092df63400152cb25fc07effc6c74c45f0654ccbde15cd"
+ "90dd5504298a946fa5cf22a956072da27a6602e6c6e5c97f2db9c1", 16),
+ "dmq1": int(
+ "28b0c1e78cdac03310717992d321a3888830ec6829978c048156152d805b4f8919c61"
+ "70b5dd204e5ddf3c6c53bc6aff15d0bd09faff7f351b94abb9db980b31f150a6d7573"
+ "08eb66938f89a5225cb4dd817a824c89e7a0293b58fc2eefb7e259", 16),
+ "iqmp": int(
+ "6c1536c0e16e42a094b6caaf50231ba81916871497d73dcbbbd4bdeb9e60cae0413b3"
+ "8143b5d680275b29ed7769fe5577e4f9b3647ddb064941120914526d64d80016d2eb7"
+ "dc362da7c569623157f3d7cff8347f11494bf5c048d77e28d3f515", 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "d871bb2d27672e54fc62c4680148cbdf848438da804e2c48b5a9c9f9daf6cc6e8ea7d"
+ "2296f25064537a9a542aef3dd449ea75774238d4da02c353d1bee70013dccc248ceef"
+ "4050160705c188043c8559bf6dbfb6c4bb382eda4e9547575a8227d5b3c0a70883913"
+ "64cf9f018d8bea053b226ec65e8cdbeaf48a071d0074860a734b1cb7d2146d43014b2"
+ "0776dea42f7853a54690e6cbbf3331a9f43763cfe2a51c3293bea3b2eebec0d8e43eb"
+ "317a443afe541107d886e5243c096091543ae65", 16),
+}
+
+RSA_KEY_2048 = {
+ "p": int(
+ "e14202e58c5f7446648d75e5dc465781f661f6b73000c080368afcfb21377f4ef19da"
+ "845d4ef9bc6b151f6d9f34629103f2e57615f9ba0a3a2fbb035069e1d63b4bb0e78ad"
+ "dad1ec3c6f87e25c877a1c4c1972098e09158ef7b9bc163852a18d44a70b7b31a03dc"
+ "2614fd9ab7bf002cba79054544af3bfbdb6aed06c7b24e6ab", 16),
+ "q": int(
+ "dbe2bea1ff92599bd19f9d045d6ce62250c05cfeac5117f3cf3e626cb696e3d886379"
+ "557d5a57b7476f9cf886accfd40508a805fe3b45a78e1a8a125e516cda91640ee6398"
+ "ec5a39d3e6b177ef12ab00d07907a17640e4ca454fd8487da3c4ffa0d5c2a5edb1221"
+ "1c8e33c7ee9fa6753771fd111ec04b8317f86693eb2928c89", 16),
+ "private_exponent": int(
+ "aef17f80f2653bc30539f26dd4c82ed6abc1d1b53bc0abcdbee47e9a8ab433abde865"
+ "9fcfae1244d22de6ad333c95aee7d47f30b6815065ac3322744d3ea75058002cd1b29"
+ "3141ee2a6dc682342432707080071bd2131d6262cab07871c28aa5238b87173fb78c3"
+ "7f9c7bcd18c12e8971bb77fd9fa3e0792fec18d8d9bed0b03ba02b263606f24dbace1"
+ "c8263ce2802a769a090e993fd49abc50c3d3c78c29bee2de0c98055d2f102f1c5684b"
+ "8dddee611d5205392d8e8dd61a15bf44680972a87f040a611a149271eeb2573f8bf6f"
+ "627dfa70e77def2ee6584914fa0290e041349ea0999cdff3e493365885b906cbcf195"
+ "843345809a85098cca90fea014a21", 16),
+ "dmp1": int(
+ "9ba56522ffcfa5244eae805c87cc0303461f82be29691b9a7c15a5a050df6c143c575"
+ "7c288d3d7ab7f32c782e9d9fcddc10a604e6425c0e5d0e46069035d95a923646d276d"
+ "d9d95b8696fa29ab0de18e53f6f119310f8dd9efca62f0679291166fed8cbd5f18fe1"
+ "3a5f1ead1d71d8c90f40382818c18c8d069be793dbc094f69", 16),
+ "dmq1": int(
+ "a8d4a0aaa2212ccc875796a81353da1fdf00d46676c88d2b96a4bfcdd924622d8e607"
+ "f3ac1c01dda7ebfb0a97dd7875c2a7b2db6728fb827b89c519f5716fb3228f4121647"
+ "04b30253c17de2289e9cce3343baa82eb404f789e094a094577a9b0c5314f1725fdf5"
+ "8e87611ad20da331bd30b8aebc7dc97d0e9a9ba8579772c9", 16),
+ "iqmp": int(
+ "17bd5ef638c49440d1853acb3fa63a5aca28cb7f94ed350db7001c8445da8943866a7"
+ "0936e1ee2716c98b484e357cc054d82fbbd98d42f880695d38a1dd4eb096f629b9417"
+ "aca47e6de5da9f34e60e8a0ffd7e35be74deeef67298d94b3e0db73fc4b7a4cb360c8"
+ "9d2117a0bfd9434d37dc7c027d6b01e5295c875015510917d", 16),
+ "public_exponent": 65537,
+ "modulus": int(
+ "c17afc7e77474caa5aa83036158a3ffbf7b5216851ba2230e5d6abfcc1c6cfef59e92"
+ "3ea1330bc593b73802ab608a6e4a3306523a3116ba5aa3966145174e13b6c49e9b780"
+ "62e449d72efb10fd49e91fa08b96d051e782e9f5abc5b5a6f7984827adb8e73da00f2"
+ "2b2efdcdb76eab46edad98ed65662743fdc6c0e336a5d0cdbaa7dc29e53635e24c87a"
+ "5b2c4215968063cdeb68a972babbc1e3cff00fb9a80e372a4d0c2c920d1e8cee333ce"
+ "470dc2e8145adb05bf29aee1d24f141e8cc784989c587fc6fbacd979f3f2163c1d729"
+ "9b365bc72ffe2848e967aed1e48dcc515b3a50ed4de04fd053846ca10a223b10cc841"
+ "cc80fdebee44f3114c13e886af583", 16),
+}
diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py
index be5e8bfc..ea72f916 100644
--- a/tests/hazmat/primitives/test_rsa.py
+++ b/tests/hazmat/primitives/test_rsa.py
@@ -28,6 +28,12 @@ from cryptography.exceptions import (
from cryptography.hazmat.primitives import hashes, interfaces
from cryptography.hazmat.primitives.asymmetric import padding, rsa
+from .fixtures_rsa import (
+ RSA_KEY_1024, RSA_KEY_1025, RSA_KEY_1026, RSA_KEY_1027, RSA_KEY_1028,
+ RSA_KEY_1029, RSA_KEY_1030, RSA_KEY_1031, RSA_KEY_1536, RSA_KEY_2048,
+ RSA_KEY_512, RSA_KEY_512_ALT, RSA_KEY_522, RSA_KEY_599, RSA_KEY_745,
+ RSA_KEY_768,
+)
from .utils import (
_check_rsa_private_key, generate_rsa_verification_test
)
@@ -93,7 +99,7 @@ class TestRSA(object):
assert skey.key_size == key_size
assert skey.public_exponent == public_exponent
- def test_generate_bad_rsa_key(self, backend):
+ def test_generate_bad_public_exponent(self, backend):
with pytest.raises(ValueError):
rsa.RSAPrivateKey.generate(public_exponent=1,
key_size=2048,
@@ -376,6 +382,12 @@ def test_rsa_generate_invalid_backend():
@pytest.mark.rsa
class TestRSASignature(object):
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PKCS1v15()
+ ),
+ skip_message="Does not support PKCS1v1.5."
+ )
@pytest.mark.parametrize(
"pkcs1_example",
_flatten_pkcs1_examples(load_vectors_from_file(
@@ -401,6 +413,15 @@ class TestRSASignature(object):
signature = signer.finalize()
assert binascii.hexlify(signature) == example["signature"]
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA1()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ),
+ skip_message="Does not support PSS."
+ )
@pytest.mark.parametrize(
"pkcs1_example",
_flatten_pkcs1_examples(load_vectors_from_file(
@@ -451,12 +472,17 @@ class TestRSASignature(object):
verifier.update(binascii.unhexlify(example["message"]))
verifier.verify()
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA1()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ),
+ skip_message="Does not support PSS."
+ )
def test_deprecated_pss_mgf1_salt_length(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
signer = private_key.signer(
pytest.deprecated_call(
padding.PSS,
@@ -493,15 +519,16 @@ class TestRSASignature(object):
[hashes.SHA224(), hashes.SHA256(), hashes.SHA384(), hashes.SHA512()]
)
def test_pss_signing_sha2(self, hash_alg, backend):
- if not backend.mgf1_hash_supported(hash_alg):
+ if not backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hash_alg),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ):
pytest.skip(
- "Does not support {0} with MGF1.".format(hash_alg.name)
+ "Does not support {0} in MGF1 using PSS.".format(hash_alg.name)
)
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=768,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_768)
public_key = private_key.public_key()
pss = padding.PSS(
mgf=padding.MGF1(hash_alg),
@@ -524,15 +551,19 @@ class TestRSASignature(object):
verifier.verify()
@pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA512()),
+ only_if=lambda backend: (
+ backend.hash_supported(hashes.SHA512()) and
+ backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA1()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ )
+ ),
skip_message="Does not support SHA512."
)
def test_pss_minimum_key_size_for_digest(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=522,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_522)
signer = private_key.signer(
padding.PSS(
mgf=padding.MGF1(hashes.SHA1()),
@@ -545,15 +576,20 @@ class TestRSASignature(object):
signer.finalize()
@pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA1()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ),
+ skip_message="Does not support PSS."
+ )
+ @pytest.mark.supported(
only_if=lambda backend: backend.hash_supported(hashes.SHA512()),
skip_message="Does not support SHA512."
)
def test_pss_signing_digest_too_large_for_key_size(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
with pytest.raises(ValueError):
private_key.signer(
padding.PSS(
@@ -564,12 +600,17 @@ class TestRSASignature(object):
backend
)
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA1()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ),
+ skip_message="Does not support PSS."
+ )
def test_pss_signing_salt_length_too_long(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
signer = private_key.signer(
padding.PSS(
mgf=padding.MGF1(hashes.SHA1()),
@@ -582,12 +623,14 @@ class TestRSASignature(object):
with pytest.raises(ValueError):
signer.finalize()
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PKCS1v15()
+ ),
+ skip_message="Does not support PKCS1v1.5."
+ )
def test_use_after_finalize(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
signer = private_key.signer(padding.PKCS1v15(), hashes.SHA1(), backend)
signer.update(b"sign me")
signer.finalize()
@@ -597,47 +640,43 @@ class TestRSASignature(object):
signer.update(b"more data")
def test_unsupported_padding(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING):
private_key.signer(DummyPadding(), hashes.SHA1(), backend)
def test_padding_incorrect_type(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
with pytest.raises(TypeError):
private_key.signer("notpadding", hashes.SHA1(), backend)
def test_rsa_signer_invalid_backend(self, backend):
pretend_backend = object()
- private_key = rsa.RSAPrivateKey.generate(65537, 2048, backend)
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_2048)
with raises_unsupported_algorithm(_Reasons.BACKEND_MISSING_INTERFACE):
private_key.signer(
padding.PKCS1v15(), hashes.SHA256, pretend_backend)
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(mgf=padding.MGF1(hashes.SHA1()), salt_length=0)
+ ),
+ skip_message="Does not support PSS."
+ )
def test_unsupported_pss_mgf(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_MGF):
private_key.signer(padding.PSS(mgf=DummyMGF()), hashes.SHA1(),
backend)
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PKCS1v15()
+ ),
+ skip_message="Does not support PKCS1v1.5."
+ )
def test_pkcs1_digest_too_large_for_key_size(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=599,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_599)
signer = private_key.signer(
padding.PKCS1v15(),
hashes.SHA512(),
@@ -647,12 +686,14 @@ class TestRSASignature(object):
with pytest.raises(ValueError):
signer.finalize()
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PKCS1v15()
+ ),
+ skip_message="Does not support PKCS1v1.5."
+ )
def test_pkcs1_minimum_key_size(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=745,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_745)
signer = private_key.signer(
padding.PKCS1v15(),
hashes.SHA512(),
@@ -664,6 +705,12 @@ class TestRSASignature(object):
@pytest.mark.rsa
class TestRSAVerification(object):
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PKCS1v15()
+ ),
+ skip_message="Does not support PKCS1v1.5."
+ )
@pytest.mark.parametrize(
"pkcs1_example",
_flatten_pkcs1_examples(load_vectors_from_file(
@@ -687,12 +734,14 @@ class TestRSAVerification(object):
verifier.update(binascii.unhexlify(example["message"]))
verifier.verify()
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PKCS1v15()
+ ),
+ skip_message="Does not support PKCS1v1.5."
+ )
def test_invalid_pkcs1v15_signature_wrong_data(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
public_key = private_key.public_key()
signer = private_key.signer(padding.PKCS1v15(), hashes.SHA1(), backend)
signer.update(b"sign me")
@@ -707,17 +756,15 @@ class TestRSAVerification(object):
with pytest.raises(InvalidSignature):
verifier.verify()
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PKCS1v15()
+ ),
+ skip_message="Does not support PKCS1v1.5."
+ )
def test_invalid_pkcs1v15_signature_wrong_key(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
- private_key2 = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
+ private_key2 = rsa.RSAPrivateKey(**RSA_KEY_512_ALT)
public_key = private_key2.public_key()
signer = private_key.signer(padding.PKCS1v15(), hashes.SHA1(), backend)
signer.update(b"sign me")
@@ -732,6 +779,15 @@ class TestRSAVerification(object):
with pytest.raises(InvalidSignature):
verifier.verify()
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA1()),
+ salt_length=20
+ )
+ ),
+ skip_message="Does not support PSS."
+ )
@pytest.mark.parametrize(
"pkcs1_example",
_flatten_pkcs1_examples(load_vectors_from_file(
@@ -758,6 +814,15 @@ class TestRSAVerification(object):
verifier.update(binascii.unhexlify(example["message"]))
verifier.verify()
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA1()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ),
+ skip_message="Does not support PSS."
+ )
def test_invalid_pss_signature_wrong_data(self, backend):
public_key = rsa.RSAPublicKey(
modulus=int(
@@ -784,6 +849,15 @@ class TestRSAVerification(object):
with pytest.raises(InvalidSignature):
verifier.verify()
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA1()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ),
+ skip_message="Does not support PSS."
+ )
def test_invalid_pss_signature_wrong_key(self, backend):
signature = binascii.unhexlify(
b"3a1880165014ba6eb53cc1449d13e5132ebcc0cfd9ade6d7a2494a0503bd0826"
@@ -812,6 +886,15 @@ class TestRSAVerification(object):
with pytest.raises(InvalidSignature):
verifier.verify()
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA1()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ),
+ skip_message="Does not support PSS."
+ )
def test_invalid_pss_signature_data_too_large_for_modulus(self, backend):
signature = binascii.unhexlify(
b"cb43bde4f7ab89eb4a79c6e8dd67e0d1af60715da64429d90c716a490b799c29"
@@ -840,12 +923,14 @@ class TestRSAVerification(object):
with pytest.raises(InvalidSignature):
verifier.verify()
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PKCS1v15()
+ ),
+ skip_message="Does not support PKCS1v1.5."
+ )
def test_use_after_finalize(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
public_key = private_key.public_key()
signer = private_key.signer(padding.PKCS1v15(), hashes.SHA1(), backend)
signer.update(b"sign me")
@@ -865,21 +950,13 @@ class TestRSAVerification(object):
verifier.update(b"more data")
def test_unsupported_padding(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
public_key = private_key.public_key()
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING):
public_key.verifier(b"sig", DummyPadding(), hashes.SHA1(), backend)
def test_padding_incorrect_type(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
public_key = private_key.public_key()
with pytest.raises(TypeError):
public_key.verifier(b"sig", "notpadding", hashes.SHA1(), backend)
@@ -893,27 +970,34 @@ class TestRSAVerification(object):
public_key.verifier(
b"foo", padding.PKCS1v15(), hashes.SHA256(), pretend_backend)
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(mgf=padding.MGF1(hashes.SHA1()), salt_length=0)
+ ),
+ skip_message="Does not support PSS."
+ )
def test_unsupported_pss_mgf(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
public_key = private_key.public_key()
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_MGF):
public_key.verifier(b"sig", padding.PSS(mgf=DummyMGF()),
hashes.SHA1(), backend)
@pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA1()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ),
+ skip_message="Does not support PSS."
+ )
+ @pytest.mark.supported(
only_if=lambda backend: backend.hash_supported(hashes.SHA512()),
skip_message="Does not support SHA512."
)
def test_pss_verify_digest_too_large_for_key_size(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
signature = binascii.unhexlify(
b"8b9a3ae9fb3b64158f3476dd8d8a1f1425444e98940e0926378baa9944d219d8"
b"534c050ef6b19b1bdc6eb4da422e89161106a6f5b5cc16135b11eb6439b646bd"
@@ -930,6 +1014,15 @@ class TestRSAVerification(object):
backend
)
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA1()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ),
+ skip_message="Does not support PSS."
+ )
def test_pss_verify_salt_length_too_long(self, backend):
signature = binascii.unhexlify(
b"8b9a3ae9fb3b64158f3476dd8d8a1f1425444e98940e0926378baa9944d219d8"
@@ -962,8 +1055,13 @@ class TestRSAVerification(object):
@pytest.mark.rsa
class TestRSAPSSMGF1Verification(object):
test_rsa_pss_mgf1_sha1 = pytest.mark.supported(
- only_if=lambda backend: backend.mgf1_hash_supported(hashes.SHA1()),
- skip_message="Does not support SHA1 with MGF1."
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA1()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ),
+ skip_message="Does not support PSS using MGF1 with SHA1."
)(generate_rsa_verification_test(
load_rsa_nist_vectors,
os.path.join("asymmetric", "RSA", "FIPS_186-2"),
@@ -982,8 +1080,13 @@ class TestRSAPSSMGF1Verification(object):
))
test_rsa_pss_mgf1_sha224 = pytest.mark.supported(
- only_if=lambda backend: backend.mgf1_hash_supported(hashes.SHA224()),
- skip_message="Does not support SHA224 with MGF1."
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA224()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ),
+ skip_message="Does not support PSS using MGF1 with SHA224."
)(generate_rsa_verification_test(
load_rsa_nist_vectors,
os.path.join("asymmetric", "RSA", "FIPS_186-2"),
@@ -1002,8 +1105,13 @@ class TestRSAPSSMGF1Verification(object):
))
test_rsa_pss_mgf1_sha256 = pytest.mark.supported(
- only_if=lambda backend: backend.mgf1_hash_supported(hashes.SHA256()),
- skip_message="Does not support SHA256 with MGF1."
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA256()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ),
+ skip_message="Does not support PSS using MGF1 with SHA256."
)(generate_rsa_verification_test(
load_rsa_nist_vectors,
os.path.join("asymmetric", "RSA", "FIPS_186-2"),
@@ -1022,8 +1130,13 @@ class TestRSAPSSMGF1Verification(object):
))
test_rsa_pss_mgf1_sha384 = pytest.mark.supported(
- only_if=lambda backend: backend.mgf1_hash_supported(hashes.SHA384()),
- skip_message="Does not support SHA384 with MGF1."
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA384()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ),
+ skip_message="Does not support PSS using MGF1 with SHA384."
)(generate_rsa_verification_test(
load_rsa_nist_vectors,
os.path.join("asymmetric", "RSA", "FIPS_186-2"),
@@ -1042,8 +1155,13 @@ class TestRSAPSSMGF1Verification(object):
))
test_rsa_pss_mgf1_sha512 = pytest.mark.supported(
- only_if=lambda backend: backend.mgf1_hash_supported(hashes.SHA512()),
- skip_message="Does not support SHA512 with MGF1."
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PSS(
+ mgf=padding.MGF1(hashes.SHA512()),
+ salt_length=padding.PSS.MAX_LENGTH
+ )
+ ),
+ skip_message="Does not support PSS using MGF1 with SHA512."
)(generate_rsa_verification_test(
load_rsa_nist_vectors,
os.path.join("asymmetric", "RSA", "FIPS_186-2"),
@@ -1065,8 +1183,11 @@ class TestRSAPSSMGF1Verification(object):
@pytest.mark.rsa
class TestRSAPKCS1Verification(object):
test_rsa_pkcs1v15_verify_sha1 = pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA1()),
- skip_message="Does not support SHA1."
+ only_if=lambda backend: (
+ backend.hash_supported(hashes.SHA1()) and
+ backend.rsa_padding_supported(padding.PKCS1v15())
+ ),
+ skip_message="Does not support SHA1 and PKCS1v1.5."
)(generate_rsa_verification_test(
load_rsa_nist_vectors,
os.path.join("asymmetric", "RSA", "FIPS_186-2"),
@@ -1080,8 +1201,11 @@ class TestRSAPKCS1Verification(object):
))
test_rsa_pkcs1v15_verify_sha224 = pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA224()),
- skip_message="Does not support SHA224."
+ only_if=lambda backend: (
+ backend.hash_supported(hashes.SHA224()) and
+ backend.rsa_padding_supported(padding.PKCS1v15())
+ ),
+ skip_message="Does not support SHA224 and PKCS1v1.5."
)(generate_rsa_verification_test(
load_rsa_nist_vectors,
os.path.join("asymmetric", "RSA", "FIPS_186-2"),
@@ -1095,8 +1219,11 @@ class TestRSAPKCS1Verification(object):
))
test_rsa_pkcs1v15_verify_sha256 = pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA256()),
- skip_message="Does not support SHA256."
+ only_if=lambda backend: (
+ backend.hash_supported(hashes.SHA256()) and
+ backend.rsa_padding_supported(padding.PKCS1v15())
+ ),
+ skip_message="Does not support SHA256 and PKCS1v1.5."
)(generate_rsa_verification_test(
load_rsa_nist_vectors,
os.path.join("asymmetric", "RSA", "FIPS_186-2"),
@@ -1110,8 +1237,11 @@ class TestRSAPKCS1Verification(object):
))
test_rsa_pkcs1v15_verify_sha384 = pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA384()),
- skip_message="Does not support SHA384."
+ only_if=lambda backend: (
+ backend.hash_supported(hashes.SHA384()) and
+ backend.rsa_padding_supported(padding.PKCS1v15())
+ ),
+ skip_message="Does not support SHA384 and PKCS1v1.5."
)(generate_rsa_verification_test(
load_rsa_nist_vectors,
os.path.join("asymmetric", "RSA", "FIPS_186-2"),
@@ -1125,8 +1255,11 @@ class TestRSAPKCS1Verification(object):
))
test_rsa_pkcs1v15_verify_sha512 = pytest.mark.supported(
- only_if=lambda backend: backend.hash_supported(hashes.SHA512()),
- skip_message="Does not support SHA512."
+ only_if=lambda backend: (
+ backend.hash_supported(hashes.SHA512()) and
+ backend.rsa_padding_supported(padding.PKCS1v15())
+ ),
+ skip_message="Does not support SHA512 and PKCS1v1.5."
)(generate_rsa_verification_test(
load_rsa_nist_vectors,
os.path.join("asymmetric", "RSA", "FIPS_186-2"),
@@ -1230,6 +1363,12 @@ class TestOAEP(object):
@pytest.mark.rsa
class TestRSADecryption(object):
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PKCS1v15()
+ ),
+ skip_message="Does not support PKCS1v1.5."
+ )
@pytest.mark.parametrize(
"vector",
_flatten_pkcs1_examples(load_vectors_from_file(
@@ -1260,20 +1399,18 @@ class TestRSADecryption(object):
assert message == binascii.unhexlify(example["message"])
def test_unsupported_padding(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING):
private_key.decrypt(b"0" * 64, DummyPadding(), backend)
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PKCS1v15()
+ ),
+ skip_message="Does not support PKCS1v1.5."
+ )
def test_decrypt_invalid_decrypt(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
with pytest.raises(ValueError):
private_key.decrypt(
b"\x00" * 64,
@@ -1281,12 +1418,14 @@ class TestRSADecryption(object):
backend
)
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PKCS1v15()
+ ),
+ skip_message="Does not support PKCS1v1.5."
+ )
def test_decrypt_ciphertext_too_large(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
with pytest.raises(ValueError):
private_key.decrypt(
b"\x00" * 65,
@@ -1294,12 +1433,14 @@ class TestRSADecryption(object):
backend
)
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PKCS1v15()
+ ),
+ skip_message="Does not support PKCS1v1.5."
+ )
def test_decrypt_ciphertext_too_small(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
ct = binascii.unhexlify(
b"50b4c14136bd198c2f3c3ed243fce036e168d56517984a263cd66492b80804f1"
b"69d210f2b9bdfb48b12f9ea05009c77da257cc600ccefe3a6283789d8ea0"
@@ -1322,6 +1463,16 @@ class TestRSADecryption(object):
pretend_backend
)
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA1()),
+ algorithm=hashes.SHA1(),
+ label=None
+ )
+ ),
+ skip_message="Does not support OAEP."
+ )
@pytest.mark.parametrize(
"vector",
_flatten_pkcs1_examples(load_vectors_from_file(
@@ -1354,11 +1505,7 @@ class TestRSADecryption(object):
assert message == binascii.unhexlify(example["message"])
def test_unsupported_oaep_mgf(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_MGF):
private_key.decrypt(
b"0" * 64,
@@ -1373,26 +1520,66 @@ class TestRSADecryption(object):
@pytest.mark.rsa
class TestRSAEncryption(object):
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.OAEP(
+ mgf=padding.MGF1(algorithm=hashes.SHA1()),
+ algorithm=hashes.SHA1(),
+ label=None
+ )
+ ),
+ skip_message="Does not support OAEP."
+ )
@pytest.mark.parametrize(
- ("key_size", "pad"),
+ ("key_data", "pad"),
itertools.product(
- (1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1536, 2048),
- (
+ (RSA_KEY_1024, RSA_KEY_1025, RSA_KEY_1026, RSA_KEY_1027,
+ RSA_KEY_1028, RSA_KEY_1029, RSA_KEY_1030, RSA_KEY_1031,
+ RSA_KEY_1536, RSA_KEY_2048),
+ [
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA1()),
algorithm=hashes.SHA1(),
label=None
- ),
- padding.PKCS1v15()
- )
+ )
+ ]
+ )
+ )
+ def test_rsa_encrypt_oaep(self, key_data, pad, backend):
+ private_key = rsa.RSAPrivateKey(**key_data)
+ pt = b"encrypt me!"
+ public_key = private_key.public_key()
+ ct = public_key.encrypt(
+ pt,
+ pad,
+ backend
)
+ assert ct != pt
+ assert len(ct) == math.ceil(public_key.key_size / 8.0)
+ recovered_pt = private_key.decrypt(
+ ct,
+ pad,
+ backend
+ )
+ assert recovered_pt == pt
+
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.rsa_padding_supported(
+ padding.PKCS1v15()
+ ),
+ skip_message="Does not support PKCS1v1.5."
)
- def test_rsa_encrypt(self, key_size, pad, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=key_size,
- backend=backend
+ @pytest.mark.parametrize(
+ ("key_data", "pad"),
+ itertools.product(
+ (RSA_KEY_1024, RSA_KEY_1025, RSA_KEY_1026, RSA_KEY_1027,
+ RSA_KEY_1028, RSA_KEY_1029, RSA_KEY_1030, RSA_KEY_1031,
+ RSA_KEY_1536, RSA_KEY_2048),
+ [padding.PKCS1v15()]
)
+ )
+ def test_rsa_encrypt_pkcs1v15(self, key_data, pad, backend):
+ private_key = rsa.RSAPrivateKey(**key_data)
pt = b"encrypt me!"
public_key = private_key.public_key()
ct = public_key.encrypt(
@@ -1410,9 +1597,11 @@ class TestRSAEncryption(object):
assert recovered_pt == pt
@pytest.mark.parametrize(
- ("key_size", "pad"),
+ ("key_data", "pad"),
itertools.product(
- (1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1536, 2048),
+ (RSA_KEY_1024, RSA_KEY_1025, RSA_KEY_1026, RSA_KEY_1027,
+ RSA_KEY_1028, RSA_KEY_1029, RSA_KEY_1030, RSA_KEY_1031,
+ RSA_KEY_1536, RSA_KEY_2048),
(
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA1()),
@@ -1423,17 +1612,13 @@ class TestRSAEncryption(object):
)
)
)
- def test_rsa_encrypt_key_too_small(self, key_size, pad, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=key_size,
- backend=backend
- )
+ def test_rsa_encrypt_key_too_small(self, key_data, pad, backend):
+ private_key = rsa.RSAPrivateKey(**key_data)
public_key = private_key.public_key()
# Slightly smaller than the key size but not enough for padding.
with pytest.raises(ValueError):
public_key.encrypt(
- b"\x00" * (key_size // 8 - 1),
+ b"\x00" * (private_key.key_size // 8 - 1),
pad,
backend
)
@@ -1441,7 +1626,7 @@ class TestRSAEncryption(object):
# Larger than the key size.
with pytest.raises(ValueError):
public_key.encrypt(
- b"\x00" * (key_size // 8 + 5),
+ b"\x00" * (private_key.key_size // 8 + 5),
pad,
backend
)
@@ -1459,22 +1644,14 @@ class TestRSAEncryption(object):
)
def test_unsupported_padding(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
public_key = private_key.public_key()
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_PADDING):
public_key.encrypt(b"somedata", DummyPadding(), backend)
def test_unsupported_oaep_mgf(self, backend):
- private_key = rsa.RSAPrivateKey.generate(
- public_exponent=65537,
- key_size=512,
- backend=backend
- )
+ private_key = rsa.RSAPrivateKey(**RSA_KEY_512)
public_key = private_key.public_key()
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_MGF):
diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py
index 8d3b8fd4..b19990e0 100644
--- a/tests/hazmat/primitives/test_serialization.py
+++ b/tests/hazmat/primitives/test_serialization.py
@@ -19,8 +19,10 @@ import textwrap
import pytest
+from cryptography.exceptions import _Reasons
from cryptography.hazmat.primitives.asymmetric import dsa, rsa
from cryptography.hazmat.primitives.serialization import (
+ load_pem_pkcs8_private_key,
load_pem_traditional_openssl_private_key
)
@@ -242,7 +244,303 @@ class TestTraditionalOpenSSLSerialisation(object):
password = b"password"
- with raises_unsupported_algorithm(None):
+ with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):
load_pem_traditional_openssl_private_key(
key_data, password, backend
)
+
+
+@pytest.mark.pkcs8_serialization
+class TestPKCS8Serialisation(object):
+ @pytest.mark.parametrize(
+ ("key_file", "password"),
+ [
+ ("unencpkcs8.pem", None),
+ ("encpkcs8.pem", b"foobar"),
+ ("enc2pkcs8.pem", b"baz"),
+ ("pkcs12_s2k_pem-X_9607.pem", b"123456"),
+ ("pkcs12_s2k_pem-X_9671.pem", b"123456"),
+ ("pkcs12_s2k_pem-X_9925.pem", b"123456"),
+ ("pkcs12_s2k_pem-X_9926.pem", b"123456"),
+ ("pkcs12_s2k_pem-X_9927.pem", b"123456"),
+ ("pkcs12_s2k_pem-X_9928.pem", b"123456"),
+ ("pkcs12_s2k_pem-X_9929.pem", b"123456"),
+ ("pkcs12_s2k_pem-X_9930.pem", b"123456"),
+ ("pkcs12_s2k_pem-X_9931.pem", b"123456"),
+ ("pkcs12_s2k_pem-X_9932.pem", b"123456"),
+ ]
+ )
+ def test_load_pem_rsa_private_key(self, key_file, password, backend):
+ key = load_vectors_from_file(
+ os.path.join(
+ "asymmetric", "PKCS8", key_file),
+ lambda pemfile: load_pem_pkcs8_private_key(
+ pemfile.read().encode(), password, backend
+ )
+ )
+
+ assert key
+ assert isinstance(key, rsa.RSAPrivateKey)
+ _check_rsa_private_key(key)
+
+ def test_unused_password(self, backend):
+ key_file = os.path.join(
+ "asymmetric", "PKCS8", "unencpkcs8.pem")
+ password = b"this password will not be used"
+
+ with pytest.raises(TypeError):
+ load_vectors_from_file(
+ key_file,
+ lambda pemfile: load_pem_pkcs8_private_key(
+ pemfile.read().encode(), password, backend
+ )
+ )
+
+ def test_wrong_password(self, backend):
+ key_file = os.path.join(
+ "asymmetric", "PKCS8", "encpkcs8.pem")
+ password = b"this password is wrong"
+
+ with pytest.raises(ValueError):
+ load_vectors_from_file(
+ key_file,
+ lambda pemfile: load_pem_pkcs8_private_key(
+ pemfile.read().encode(), password, backend
+ )
+ )
+
+ @pytest.mark.parametrize("password", [None, b""])
+ def test_missing_password(self, backend, password):
+ key_file = os.path.join(
+ "asymmetric",
+ "PKCS8",
+ "encpkcs8.pem"
+ )
+
+ with pytest.raises(TypeError):
+ load_vectors_from_file(
+ key_file,
+ lambda pemfile: load_pem_pkcs8_private_key(
+ pemfile.read().encode(), password, backend
+ )
+ )
+
+ def test_wrong_format(self, backend):
+ key_data = b"---- NOT A KEY ----\n"
+
+ with pytest.raises(ValueError):
+ load_pem_pkcs8_private_key(
+ key_data, None, backend
+ )
+
+ with pytest.raises(ValueError):
+ load_pem_pkcs8_private_key(
+ key_data, b"this password will not be used", backend
+ )
+
+ def test_corrupt_format(self, backend):
+ # unencpkcs8.pem with a bunch of data missing.
+ key_data = textwrap.dedent("""\
+ -----BEGIN PRIVATE KEY-----
+ MIICdQIBADALBgkqhkiG9w0BAQEEggJhMIICXQIBAAKBgQC7JHoJfg6yNzLMOWet
+ 8Z49a4KD0dCspMAYvo2YAMB7/wdEycocujbhJ2n/seONi+5XqTqqFkM5VBl8rmkk
+ FPZk/7x0xmdsTPECSWnHK+HhoaNDFPR3j8jQhVo1laxiqcEhAHegi5cwtFosuJAv
+ FiRC0Cgz+frQPFQEBsAV9RuasyQxqzxrR0Ow0qncBeGBWbYE6WZhqtcLAI895b+i
+ +F4lbB4iD7T9QeIDMU/aIMXA81UO4cns1z4qDAHKeyLLrPQrJ/B4X7XC+egUWm5+
+ hr1qmyAMusyXIBECQQDJWZ8piluf4yrYfsJAn6hF5T4RjTztbqvO0GVG2McHY7Uj
+ NPSffhzHx/ll0fQEQji+OgydCCX8o3HZrgw5YfSJAkEA7e+rqdU5nO5ZG//PSEQb
+ tjLnRiTzBH/elQhtdZ5nF7pcpNTi4k13zutmKcWW4GK75azcRGJUhu1kDM7QYAOd
+ SQJAVNkYcifkvna7GmooL5VYEsQsqLbM4v0NF2TIGNfG3z1MGp75KrC5LhL97MNR
+ we2p/bd2k0HYyCKUGnf2nMPDiQJBAI75pwittSoE240EobUGIDTSz8CJsXIxuDmL
+ z+KOpdpPRR5TQmbEMEspjsFpFymMiuYPgmihQbO2cJl1qScY5OkCQQCJ6m5tcN8l
+ Xxg/SNpjEIv+qAyUD96XVlOJlOIeLHQ8kYE0C6ZA+MsqYIzgAreJk88Yn0lU/X0/
+ mu/UpE/BRZmR
+ -----END PRIVATE KEY-----
+ """).encode()
+
+ with pytest.raises(ValueError):
+ load_pem_pkcs8_private_key(
+ key_data, None, backend
+ )
+
+ with pytest.raises(ValueError):
+ load_pem_pkcs8_private_key(
+ key_data, b"this password will not be used", backend
+ )
+
+ def test_encrypted_corrupt_format(self, backend):
+ # encpkcs8.pem with some bits flipped.
+ key_data = textwrap.dedent("""\
+ -----BEGIN ENCRYPTED PRIVATE KEY-----
+ MIICojAcBgoqhkiG9w0BDAEDMA4ECHK0M0+QuEL9AgIBIcSCAoDRq+KRY+0XP0tO
+ lwBTzViiXSXoyNnKAZKt5r5K/fGNntv22g/1s/ZNCetrqsJDC5eMUPPacz06jFq/
+ Ipsep4/OgjQ9UAOzXNrWEoNyrHnWDo7usgD3CW0mKyqER4+wG0adVMbt3N+CJHGB
+ 85jzRmQTfkdx1rSWeSx+XyswHn8ER4+hQ+omKWMVm7AFkjjmP/KnhUnLT98J8rhU
+ ArQoFPHz/6HVkypFccNaPPNg6IA4aS2A+TU9vJYOaXSVfFB2yf99hfYYzC+ukmuU
+ 5Lun0cysK5s/5uSwDueUmDQKspnaNyiaMGDxvw8hilJc7vg0fGObfnbIpizhxJwq
+ gKBfR7Zt0Hv8OYi1He4MehfMGdbHskztF+yQ40LplBGXQrvAqpU4zShga1BoQ98T
+ 0ekbBmqj7hg47VFsppXR7DKhx7G7rpMmdKbFhAZVCjae7rRGpUtD52cpFdPhMyAX
+ huhMkoczwUW8B/rM4272lkHo6Br0yk/TQfTEGkvryflNVu6lniPTV151WV5U1M3o
+ 3G3a44eDyt7Ln+WSOpWtbPQMTrpKhur6WXgJvrpa/m02oOGdvOlDsoOCgavgQMWg
+ 7xKKL7620pHl7p7f/8tlE8q6vLXVvyNtAOgt/JAr2rgvrHaZSzDE0DwgCjBXEm+7
+ cVMVNkHod7bLQefVanVtWqPzbmr8f7gKeuGwWSG9oew/lN2hxcLEPJHAQlnLgx3P
+ 0GdGjK9NvwA0EP2gYIeE4+UtSder7xQ7bVh25VB20R4TTIIs4aXXCVOoQPagnzaT
+ 6JLgl8FrvdfjHwIvmSOO1YMNmILBq000Q8WDqyErBDs4hsvtO6VQ4LeqJj6gClX3
+ qeJNaJFu
+ -----END ENCRYPTED PRIVATE KEY-----
+ """).encode()
+
+ password = b"this password is wrong"
+
+ with pytest.raises(ValueError):
+ load_pem_pkcs8_private_key(
+ key_data, None, backend
+ )
+
+ with pytest.raises(ValueError):
+ load_pem_pkcs8_private_key(
+ key_data, password, backend
+ )
+
+ def test_key1_pem_encrypted_values(self, backend):
+ pkey = load_vectors_from_file(
+ os.path.join(
+ "asymmetric", "PKCS8", "encpkcs8.pem"),
+ lambda pemfile: load_pem_pkcs8_private_key(
+ pemfile.read().encode(), b"foobar", backend
+ )
+ )
+ assert pkey
+
+ assert pkey.modulus == int(
+ "00beec64d6db5760ac2fd4c971145641b9bd7f5c56558ece608795c79807"
+ "376a7fe5b19f95b35ca358ea5c8abd7ae051d49cd2f1e45969a1ae945460"
+ "3c14b278664a0e414ebc8913acb6203626985525e17a600611b028542dd0"
+ "562aad787fb4f1650aa318cdcff751e1b187cbf6785fbe164e9809491b95"
+ "dd68480567c99b1a57", 16
+ )
+
+ assert pkey.public_exponent == 65537
+
+ assert pkey.private_exponent == int(
+ "0cfe316e9dc6b8817f4fcfd5ae38a0886f68f773b8a6db4c9e6d8703c599"
+ "f3d9785c3a2c09e4c8090909fb3721e19a3009ec21221523a729265707a5"
+ "8f13063671c42a4096cad378ef2510cb59e23071489d8893ac4934dd149f"
+ "34f2d094bea57f1c8027c3a77248ac9b91218737d0c3c3dfa7d7829e6977"
+ "cf7d995688c86c81", 16
+ )
+
+ assert pkey.p == int(
+ "00db122ac857b2c0437d7616daa98e597bb75ca9ad3a47a70bec10c10036"
+ "03328794b225c8e3eee6ffd3fd6d2253d28e071fe27d629ab072faa14377"
+ "ce6118cb67", 16
+ )
+
+ assert pkey.q == int(
+ "00df1b8aa8506fcbbbb9d00257f2975e38b33d2698fd0f37e82d7ef38c56"
+ "f21b6ced63c825383782a7115cfcc093300987dbd2853b518d1c8f26382a"
+ "2d2586d391", 16
+ )
+
+ assert pkey.dmp1 == int(
+ "00be18aca13e60712fdf5daa85421eb10d86d654b269e1255656194fb0c4"
+ "2dd01a1070ea12c19f5c39e09587af02f7b1a1030d016a9ffabf3b36d699"
+ "ceaf38d9bf", 16
+ )
+
+ assert pkey.dmq1 == int(
+ "71aa8978f90a0c050744b77cf1263725b203ac9f730606d8ae1d289dce4a"
+ "28b8d534e9ea347aeb808c73107e583eb80c546d2bddadcdb3c82693a4c1"
+ "3d863451", 16
+ )
+
+ assert pkey.iqmp == int(
+ "136b7b1afac6e6279f71b24217b7083485a5e827d156024609dae39d48a6"
+ "bdb55af2f062cc4a3b077434e6fffad5faa29a2b5dba2bed3e4621e478c0"
+ "97ccfe7f", 16
+ )
+
+ @pytest.mark.parametrize(
+ ("key_file", "password"),
+ [
+ ("unenc-dsa-pkcs8.pem", None),
+ ]
+ )
+ def test_load_pem_dsa_private_key(self, key_file, password, backend):
+ key = load_vectors_from_file(
+ os.path.join(
+ "asymmetric", "PKCS8", key_file),
+ lambda pemfile: load_pem_traditional_openssl_private_key(
+ pemfile.read().encode(), password, backend
+ )
+ )
+ assert key
+ assert isinstance(key, dsa.DSAPrivateKey)
+
+ params = key.parameters()
+ assert isinstance(params, dsa.DSAParameters)
+
+ assert key.x == int("00a535a8e1d0d91beafc8bee1d9b2a3a8de3311203", 16)
+ assert key.y == int(
+ "2b260ea97dc6a12ae932c640e7df3d8ff04a8a05a0324f8d5f1b23f15fa1"
+ "70ff3f42061124eff2586cb11b49a82dcdc1b90fc6a84fb10109cb67db5d"
+ "2da971aeaf17be5e37284563e4c64d9e5fc8480258b319f0de29d54d8350"
+ "70d9e287914d77df81491f4423b62da984eb3f45eb2a29fcea5dae525ac6"
+ "ab6bcce04bfdf5b6",
+ 16
+ )
+
+ assert params.p == int(
+ "00aa0930cc145825221caffa28ac2894196a27833de5ec21270791689420"
+ "7774a2e7b238b0d36f1b2499a2c2585083eb01432924418d867faa212dd1"
+ "071d4dceb2782794ad393cc08a4d4ada7f68d6e839a5fcd34b4e402d82cb"
+ "8a8cb40fec31911bf9bd360b034caacb4c5e947992573c9e90099c1b0f05"
+ "940cabe5d2de49a167",
+ 16
+ )
+
+ assert params.q == int("00adc0e869b36f0ac013a681fdf4d4899d69820451",
+ 16)
+
+ assert params.g == int(
+ "008c6b4589afa53a4d1048bfc346d1f386ca75521ccf72ddaa251286880e"
+ "e13201ff48890bbfc33d79bacaec71e7a778507bd5f1a66422e39415be03"
+ "e71141ba324f5b93131929182c88a9fa4062836066cebe74b5c6690c7d10"
+ "1106c240ab7ebd54e4e3301fd086ce6adac922fb2713a2b0887cba13b9bc"
+ "68ce5cfff241cd3246",
+ 16
+ )
+
+ @pytest.mark.parametrize(
+ ("key_file", "password"),
+ [
+ ("bad-oid-dsa-key.pem", None),
+ ]
+ )
+ def test_load_bad_oid_key(self, key_file, password, backend):
+ with raises_unsupported_algorithm(
+ _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM
+ ):
+ load_vectors_from_file(
+ os.path.join(
+ "asymmetric", "PKCS8", key_file),
+ lambda pemfile: load_pem_traditional_openssl_private_key(
+ pemfile.read().encode(), password, backend
+ )
+ )
+
+ @pytest.mark.parametrize(
+ ("key_file", "password"),
+ [
+ ("bad-encryption-oid.pem", b"password"),
+ ]
+ )
+ def test_load_bad_encryption_oid_key(self, key_file, password, backend):
+ with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_CIPHER):
+ load_vectors_from_file(
+ os.path.join(
+ "asymmetric", "PKCS8", key_file),
+ lambda pemfile: load_pem_traditional_openssl_private_key(
+ pemfile.read().encode(), password, backend
+ )
+ )
diff --git a/vectors/cryptography_vectors/asymmetric/PKCS8/bad-encryption-oid.pem b/vectors/cryptography_vectors/asymmetric/PKCS8/bad-encryption-oid.pem
new file mode 100644
index 00000000..4ebcc12c
--- /dev/null
+++ b/vectors/cryptography_vectors/asymmetric/PKCS8/bad-encryption-oid.pem
@@ -0,0 +1,17 @@
+-----BEGIN ENCRYPTED PRIVATE KEY-----
+MIICojAcBgoYYYYYYYYYYYYYMA4ECHK0M0+QuEL9AgIBIgSCAoDRq+KRY+0XP0tO
+lwBTzViiXSXoyNnKAZKt5r5K/fGNntv22g/1s/ZNCetrqsJDC5eMUPPacz06jFq/
+Ipsep4/OgjQ9UAOzXNrWEoNyrHnWDo7usgD3CW0mKyqER4+wG0ZdVMbt3N+CJHGB
+85jzRmQTfkdx1rSWeSx+XyswHn8ER4+hQ+omKWMVm7AFkjjmP/KmhUnLT98J8rhU
+ArQoFPHz/6HVkypFccNaPPNg6IA4aS2A+TU9vJYOaXSVfFB2yf99hfYYzC+ukmuU
+5Lun0cysK5s/5uSwDueUmDQKspnaNyiaMGDxvw8hilJc7vg0fGObfnbIpizhxJwq
+gKBfR7Zt0Hv8OYi1He4MehfMGdbHskztF+yQ40LplBGXQrvAqpU4zShga1BoQ98T
+0ekbBmqj7hg47VFsppXR7DKhx7G7rpMmdKbFhAZVCjae7rRGpUtD52cpFdPhMyAX
+huhMkoczwUW8B/rM4272lkHo6Br0yk/TQfTEGkvryflNVu6lniPTV151WV5U1M3o
+3G3a44eDyt7Ln+WSOpWtbPQMTrpKhur6WXgJvrpa/m02oOGdvOlDsoOCgavgQMWg
+7xKKL7620pHl7p7f/8tlE8q6vLXVvyNtAOgt/JAr2rgvrHaZSzDE0DwgCjBXEm+7
+cVMVNkHod7bLQefVanVtWqPzbmr8f7gKeuGwWSG9oew/lN2hxcLEPJHAQlnLgx3P
+0GdGjK9NvwA0EP2gYIeE4+UtSder7xQ7bVh25VB20R4TTIIs4aXXCVOoQPagnzaT
+6JLgl8FrvdfjHwIvmSOO1YMNmILBq000Q8WDqyErBDs4hsvtO6VQ4LeqJj6gClX3
+qeJNaJFu
+-----END ENCRYPTED PRIVATE KEY-----
diff --git a/vectors/cryptography_vectors/asymmetric/PKCS8/bad-oid-dsa-key.pem b/vectors/cryptography_vectors/asymmetric/PKCS8/bad-oid-dsa-key.pem
new file mode 100644
index 00000000..50d045be
--- /dev/null
+++ b/vectors/cryptography_vectors/asymmetric/PKCS8/bad-oid-dsa-key.pem
@@ -0,0 +1,9 @@
+-----BEGIN PRIVATE KEY-----
+MIIBTAIBADCCASwGByXXXXXXXXEwggEfAoGBAKoJMMwUWCUiHK/6KKwolBlqJ4M9
+5ewhJweRaJQgd3Si57I4sNNvGySZosJYUIPrAUMpJEGNhn+qIS3RBx1NzrJ4J5St
+OTzAik1K2n9o1ug5pfzTS05ALYLLioy0D+wxkRv5vTYLA0yqy0xelHmSVzyekAmc
+Gw8FlAyr5dLeSaFnAhUArcDoabNvCsATpoH99NSJnWmCBFECgYEAjGtFia+lOk0Q
+SL/DRtHzhsp1UhzPct2qJRKGiA7hMgH/SIkLv8M9ebrK7HHnp3hQe9XxpmQi45QV
+vgPnEUG6Mk9bkxMZKRgsiKn6QGKDYGbOvnS1xmkMfRARBsJAq369VOTjMB/Qhs5q
+2ski+ycTorCIfLoTubxozlz/8kHNMkYEFwIVAKU1qOHQ2Rvq/IvuHZsqOo3jMRID
+-----END PRIVATE KEY-----
diff --git a/vectors/cryptography_vectors/asymmetric/PKCS8/unenc-dsa-pkcs8.pem b/vectors/cryptography_vectors/asymmetric/PKCS8/unenc-dsa-pkcs8.pem
new file mode 100644
index 00000000..7b2099d3
--- /dev/null
+++ b/vectors/cryptography_vectors/asymmetric/PKCS8/unenc-dsa-pkcs8.pem
@@ -0,0 +1,9 @@
+-----BEGIN PRIVATE KEY-----
+MIIBTAIBADCCASwGByqGSM44BAEwggEfAoGBAKoJMMwUWCUiHK/6KKwolBlqJ4M9
+5ewhJweRaJQgd3Si57I4sNNvGySZosJYUIPrAUMpJEGNhn+qIS3RBx1NzrJ4J5St
+OTzAik1K2n9o1ug5pfzTS05ALYLLioy0D+wxkRv5vTYLA0yqy0xelHmSVzyekAmc
+Gw8FlAyr5dLeSaFnAhUArcDoabNvCsATpoH99NSJnWmCBFECgYEAjGtFia+lOk0Q
+SL/DRtHzhsp1UhzPct2qJRKGiA7hMgH/SIkLv8M9ebrK7HHnp3hQe9XxpmQi45QV
+vgPnEUG6Mk9bkxMZKRgsiKn6QGKDYGbOvnS1xmkMfRARBsJAq369VOTjMB/Qhs5q
+2ski+ycTorCIfLoTubxozlz/8kHNMkYEFwIVAKU1qOHQ2Rvq/IvuHZsqOo3jMRID
+-----END PRIVATE KEY-----