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", ) 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", ) 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", ) 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", ) 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", ) assert parsed_cert is None assert parsed_key is None assert parsed_more_certs == [cert] def test_load_pkcs12_key_only(self, backend): 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", ) 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", ) assert parsed_key.private_numbers() == key.private_numbers() assert parsed_cert is None assert parsed_more_certs == [] def test_non_bytes(self, backend): with pytest.raises(TypeError): load_key_and_certificates( b"irrelevant", object(), backend # type: ignore[arg-type] ) def test_not_a_pkcs12(self, backend): with pytest.raises(ValueError): load_key_and_certificates(b"invalid", b"pass", backend) def test_invalid_password(self, backend): with pytest.raises(ValueError): load_vectors_from_file( os.path.join("pkcs12", "cert-key-aes256cbc.p12"), lambda derfile: load_key_and_certificates( derfile.read(), b"invalid", backend), 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", ) p12buffer = bytearray(p12) parsed_key, parsed_cert, parsed_more_certs = load_key_and_certificates( p12buffer, bytearray(b"cryptography"), backend) assert parsed_key is not None assert parsed_cert is not None assert parsed_more_certs == []
class TestPKCS12Loading: 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", ) 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", ) assert isinstance(key, ec.EllipticCurvePrivateKey) 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", ) assert isinstance(parsed_key, ec.EllipticCurvePrivateKey) 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", ) 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", ) 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", ) assert parsed_cert is None assert parsed_key is None assert parsed_more_certs == [cert] def test_load_pkcs12_key_only(self, backend): 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", ) assert isinstance(key, ec.EllipticCurvePrivateKey) 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", ) assert isinstance(parsed_key, ec.EllipticCurvePrivateKey) assert parsed_key.private_numbers() == key.private_numbers() assert parsed_cert is None assert parsed_more_certs == [] def test_non_bytes(self, backend): with pytest.raises(TypeError): load_key_and_certificates( b"irrelevant", object(), backend # type: ignore[arg-type] ) def test_not_a_pkcs12(self, backend): with pytest.raises(ValueError): load_key_and_certificates(b"invalid", b"pass", backend) def test_invalid_password(self, backend): with pytest.raises(ValueError): load_vectors_from_file( os.path.join("pkcs12", "cert-key-aes256cbc.p12"), lambda derfile: load_key_and_certificates( derfile.read(), b"invalid", backend), 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", ) p12buffer = bytearray(p12) parsed_key, parsed_cert, parsed_more_certs = load_key_and_certificates( p12buffer, bytearray(b"cryptography"), backend) assert parsed_key is not None assert parsed_cert is not None assert parsed_more_certs == [] @pytest.mark.parametrize( ("name", "name2", "name3", "filename", "password"), [ (None, None, None, "no-name-no-pwd.p12", None), (b"name", b"name2", b"name3", "name-all-no-pwd.p12", None), (b"name", None, None, "name-1-no-pwd.p12", None), (None, b"name2", b"name3", "name-2-3-no-pwd.p12", None), (None, b"name2", None, "name-2-no-pwd.p12", None), (None, None, b"name3", "name-3-no-pwd.p12", None), ( "☺".encode("utf-8"), "ä".encode("utf-8"), "ç".encode("utf-8"), "name-unicode-no-pwd.p12", None, ), (None, None, None, "no-name-pwd.p12", b"password"), (b"name", b"name2", b"name3", "name-all-pwd.p12", b"password"), (b"name", None, None, "name-1-pwd.p12", b"password"), (None, b"name2", b"name3", "name-2-3-pwd.p12", b"password"), (None, b"name2", None, "name-2-pwd.p12", b"password"), (None, None, b"name3", "name-3-pwd.p12", b"password"), ( "☺".encode("utf-8"), "ä".encode("utf-8"), "ç".encode("utf-8"), "name-unicode-pwd.p12", b"password", ), ], ) def test_load_object(self, filename, name, name2, name3, password, backend): cert, key = _load_ca(backend) cert2 = _load_cert(backend, os.path.join("x509", "cryptography.io.pem")) cert3 = _load_cert(backend, os.path.join("x509", "letsencryptx3.pem")) pkcs12 = load_vectors_from_file( os.path.join("pkcs12", filename), lambda derfile: load_pkcs12(derfile.read(), password, backend), mode="rb", ) assert pkcs12.cert is not None assert pkcs12.cert.certificate == cert assert pkcs12.cert.friendly_name == name assert isinstance(pkcs12.key, ec.EllipticCurvePrivateKey) assert pkcs12.key.private_numbers() == key.private_numbers() assert len(pkcs12.additional_certs) == 2 assert pkcs12.additional_certs[0].certificate == cert2 assert pkcs12.additional_certs[0].friendly_name == name2 assert pkcs12.additional_certs[1].certificate == cert3 assert pkcs12.additional_certs[1].friendly_name == name3 @pytest.mark.parametrize( ("name2", "name3", "filename", "password"), [ (None, None, "no-cert-no-name-no-pwd.p12", None), (b"name2", b"name3", "no-cert-name-all-no-pwd.p12", None), (b"name2", None, "no-cert-name-2-no-pwd.p12", None), (None, b"name3", "no-cert-name-3-no-pwd.p12", None), ( "☹".encode("utf-8"), "ï".encode("utf-8"), "no-cert-name-unicode-no-pwd.p12", None, ), (None, None, "no-cert-no-name-pwd.p12", b"password"), (b"name2", b"name3", "no-cert-name-all-pwd.p12", b"password"), (b"name2", None, "no-cert-name-2-pwd.p12", b"password"), (None, b"name3", "no-cert-name-3-pwd.p12", b"password"), ( "☹".encode("utf-8"), "ï".encode("utf-8"), "no-cert-name-unicode-pwd.p12", b"password", ), ], ) def test_load_object_no_cert_key(self, filename, name2, name3, password, backend): cert2 = _load_cert(backend, os.path.join("x509", "cryptography.io.pem")) cert3 = _load_cert(backend, os.path.join("x509", "letsencryptx3.pem")) pkcs12 = load_vectors_from_file( os.path.join("pkcs12", filename), lambda derfile: load_pkcs12(derfile.read(), password, backend), mode="rb", ) assert pkcs12.cert is None assert pkcs12.key is None assert len(pkcs12.additional_certs) == 2 assert pkcs12.additional_certs[0].certificate == cert2 assert pkcs12.additional_certs[0].friendly_name == name2 assert pkcs12.additional_certs[1].certificate == cert3 assert pkcs12.additional_certs[1].friendly_name == name3