summaryrefslogtreecommitdiff
path: root/tests/hazmat/primitives/test_pkcs12.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/hazmat/primitives/test_pkcs12.py')
-rw-r--r--tests/hazmat/primitives/test_pkcs12.py202
1 files changed, 175 insertions, 27 deletions
diff --git a/tests/hazmat/primitives/test_pkcs12.py b/tests/hazmat/primitives/test_pkcs12.py
index f084d578c..297483e2f 100644
--- a/tests/hazmat/primitives/test_pkcs12.py
+++ b/tests/hazmat/primitives/test_pkcs12.py
@@ -10,61 +10,85 @@ import pytest
from cryptography import x509
from cryptography.hazmat.backends.interfaces import DERSerializationBackend
+from cryptography.hazmat.backends.openssl.backend import _RC2
+from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.serialization import load_pem_private_key
from cryptography.hazmat.primitives.serialization.pkcs12 import (
- load_key_and_certificates
+ load_key_and_certificates,
+ serialize_key_and_certificates,
)
from .utils import load_vectors_from_file
+from ...doubles import DummyKeySerializationEncryption
@pytest.mark.requires_backend_interface(interface=DERSerializationBackend)
-class TestPKCS12(object):
- @pytest.mark.parametrize(
- ("filename", "password"),
- [
- ("cert-key-aes256cbc.p12", b"cryptography"),
- ("cert-none-key-none.p12", b"cryptography"),
- ("cert-rc2-key-3des.p12", b"cryptography"),
- ("no-password.p12", None),
- ]
- )
- def test_load_pkcs12_ec_keys(self, filename, password, backend):
+class TestPKCS12Loading(object):
+ def _test_load_pkcs12_ec_keys(self, filename, password, backend):
cert = load_vectors_from_file(
os.path.join("x509", "custom", "ca", "ca.pem"),
lambda pemfile: x509.load_pem_x509_certificate(
pemfile.read(), backend
- ), mode="rb"
+ ),
+ mode="rb",
)
key = load_vectors_from_file(
os.path.join("x509", "custom", "ca", "ca_key.pem"),
lambda pemfile: load_pem_private_key(
pemfile.read(), None, backend
- ), mode="rb"
+ ),
+ mode="rb",
)
parsed_key, parsed_cert, parsed_more_certs = load_vectors_from_file(
os.path.join("pkcs12", filename),
lambda derfile: load_key_and_certificates(
derfile.read(), password, backend
- ), mode="rb"
+ ),
+ mode="rb",
)
assert parsed_cert == cert
assert parsed_key.private_numbers() == key.private_numbers()
assert parsed_more_certs == []
+ @pytest.mark.parametrize(
+ ("filename", "password"),
+ [
+ ("cert-key-aes256cbc.p12", b"cryptography"),
+ ("cert-none-key-none.p12", b"cryptography"),
+ ],
+ )
+ def test_load_pkcs12_ec_keys(self, filename, password, backend):
+ self._test_load_pkcs12_ec_keys(filename, password, backend)
+
+ @pytest.mark.parametrize(
+ ("filename", "password"),
+ [
+ ("cert-rc2-key-3des.p12", b"cryptography"),
+ ("no-password.p12", None),
+ ],
+ )
+ @pytest.mark.supported(
+ only_if=lambda backend: backend.cipher_supported(_RC2(), None),
+ skip_message="Does not support RC2",
+ )
+ @pytest.mark.skip_fips(reason="Unsupported algorithm in FIPS mode")
+ def test_load_pkcs12_ec_keys_rc2(self, filename, password, backend):
+ self._test_load_pkcs12_ec_keys(filename, password, backend)
+
def test_load_pkcs12_cert_only(self, backend):
cert = load_vectors_from_file(
os.path.join("x509", "custom", "ca", "ca.pem"),
lambda pemfile: x509.load_pem_x509_certificate(
pemfile.read(), backend
- ), mode="rb"
+ ),
+ mode="rb",
)
parsed_key, parsed_cert, parsed_more_certs = load_vectors_from_file(
os.path.join("pkcs12", "cert-aes256cbc-no-key.p12"),
lambda data: load_key_and_certificates(
data.read(), b"cryptography", backend
),
- mode="rb"
+ mode="rb",
)
assert parsed_cert is None
assert parsed_key is None
@@ -75,14 +99,15 @@ class TestPKCS12(object):
os.path.join("x509", "custom", "ca", "ca_key.pem"),
lambda pemfile: load_pem_private_key(
pemfile.read(), None, backend
- ), mode="rb"
+ ),
+ mode="rb",
)
parsed_key, parsed_cert, parsed_more_certs = load_vectors_from_file(
os.path.join("pkcs12", "no-cert-key-aes256cbc.p12"),
lambda data: load_key_and_certificates(
data.read(), b"cryptography", backend
),
- mode="rb"
+ mode="rb",
)
assert parsed_key.private_numbers() == key.private_numbers()
assert parsed_cert is None
@@ -90,15 +115,11 @@ class TestPKCS12(object):
def test_non_bytes(self, backend):
with pytest.raises(TypeError):
- load_key_and_certificates(
- b"irrelevant", object(), backend
- )
+ load_key_and_certificates(b"irrelevant", object(), backend)
def test_not_a_pkcs12(self, backend):
with pytest.raises(ValueError):
- load_key_and_certificates(
- b"invalid", b"pass", backend
- )
+ load_key_and_certificates(b"invalid", b"pass", backend)
def test_invalid_password(self, backend):
with pytest.raises(ValueError):
@@ -106,13 +127,15 @@ class TestPKCS12(object):
os.path.join("pkcs12", "cert-key-aes256cbc.p12"),
lambda derfile: load_key_and_certificates(
derfile.read(), b"invalid", backend
- ), mode="rb"
+ ),
+ mode="rb",
)
def test_buffer_protocol(self, backend):
p12 = load_vectors_from_file(
os.path.join("pkcs12", "cert-key-aes256cbc.p12"),
- lambda derfile: derfile.read(), mode="rb"
+ lambda derfile: derfile.read(),
+ mode="rb",
)
p12buffer = bytearray(p12)
parsed_key, parsed_cert, parsed_more_certs = load_key_and_certificates(
@@ -121,3 +144,128 @@ class TestPKCS12(object):
assert parsed_key is not None
assert parsed_cert is not None
assert parsed_more_certs == []
+
+
+def _load_cert(backend, path):
+ return load_vectors_from_file(
+ path,
+ lambda pemfile: x509.load_pem_x509_certificate(
+ pemfile.read(), backend
+ ),
+ mode="rb",
+ )
+
+
+def _load_ca(backend):
+ cert = _load_cert(backend, os.path.join("x509", "custom", "ca", "ca.pem"))
+ key = load_vectors_from_file(
+ os.path.join("x509", "custom", "ca", "ca_key.pem"),
+ lambda pemfile: load_pem_private_key(pemfile.read(), None, backend),
+ mode="rb",
+ )
+ return cert, key
+
+
+class TestPKCS12Creation(object):
+ @pytest.mark.parametrize("name", [None, b"name"])
+ @pytest.mark.parametrize(
+ ("encryption_algorithm", "password"),
+ [
+ (serialization.BestAvailableEncryption(b"password"), b"password"),
+ (serialization.NoEncryption(), None),
+ ],
+ )
+ def test_generate(self, backend, name, encryption_algorithm, password):
+ cert, key = _load_ca(backend)
+ p12 = serialize_key_and_certificates(
+ name, key, cert, None, encryption_algorithm
+ )
+
+ parsed_key, parsed_cert, parsed_more_certs = load_key_and_certificates(
+ p12, password, backend
+ )
+ assert parsed_cert == cert
+ assert parsed_key.private_numbers() == key.private_numbers()
+ assert parsed_more_certs == []
+
+ def test_generate_with_cert_key_ca(self, backend):
+ cert, key = _load_ca(backend)
+ cert2 = _load_cert(
+ backend, os.path.join("x509", "custom", "dsa_selfsigned_ca.pem")
+ )
+ cert3 = _load_cert(backend, os.path.join("x509", "letsencryptx3.pem"))
+ encryption = serialization.NoEncryption()
+ p12 = serialize_key_and_certificates(
+ None, key, cert, [cert2, cert3], encryption
+ )
+
+ parsed_key, parsed_cert, parsed_more_certs = load_key_and_certificates(
+ p12, None, backend
+ )
+ assert parsed_cert == cert
+ assert parsed_key.private_numbers() == key.private_numbers()
+ assert parsed_more_certs == [cert2, cert3]
+
+ def test_generate_wrong_types(self, backend):
+ cert, key = _load_ca(backend)
+ cert2 = _load_cert(backend, os.path.join("x509", "letsencryptx3.pem"))
+ encryption = serialization.NoEncryption()
+ with pytest.raises(TypeError) as exc:
+ serialize_key_and_certificates(
+ b"name", cert, cert, None, encryption
+ )
+ assert (
+ str(exc.value)
+ == "Key must be RSA, DSA, or EllipticCurve private key."
+ )
+
+ with pytest.raises(TypeError) as exc:
+ serialize_key_and_certificates(b"name", key, key, None, encryption)
+ assert str(exc.value) == "cert must be a certificate"
+
+ with pytest.raises(TypeError) as exc:
+ serialize_key_and_certificates(b"name", key, cert, None, key)
+ assert str(exc.value) == (
+ "Key encryption algorithm must be a "
+ "KeySerializationEncryption instance"
+ )
+
+ with pytest.raises(TypeError) as exc:
+ serialize_key_and_certificates(None, key, cert, cert2, encryption)
+
+ with pytest.raises(TypeError) as exc:
+ serialize_key_and_certificates(None, key, cert, [key], encryption)
+ assert str(exc.value) == "all values in cas must be certificates"
+
+ def test_generate_no_cert(self, backend):
+ _, key = _load_ca(backend)
+ p12 = serialize_key_and_certificates(
+ None, key, None, None, serialization.NoEncryption()
+ )
+ parsed_key, parsed_cert, parsed_more_certs = load_key_and_certificates(
+ p12, None, backend
+ )
+ assert parsed_cert is None
+ assert parsed_key.private_numbers() == key.private_numbers()
+ assert parsed_more_certs == []
+
+ def test_must_supply_something(self):
+ with pytest.raises(ValueError) as exc:
+ serialize_key_and_certificates(
+ None, None, None, None, serialization.NoEncryption()
+ )
+ assert str(exc.value) == (
+ "You must supply at least one of key, cert, or cas"
+ )
+
+ def test_generate_unsupported_encryption_type(self, backend):
+ cert, key = _load_ca(backend)
+ with pytest.raises(ValueError) as exc:
+ serialize_key_and_certificates(
+ None,
+ key,
+ cert,
+ None,
+ DummyKeySerializationEncryption(),
+ )
+ assert str(exc.value) == "Unsupported key encryption type"