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 == []
示例#2
0
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