Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Two PKCS12 tests fail when OpenSSL is built without RC2 support #5065

Closed
koobs opened this issue Nov 15, 2019 · 4 comments
Closed

Two PKCS12 tests fail when OpenSSL is built without RC2 support #5065

koobs opened this issue Nov 15, 2019 · 4 comments

Comments

@koobs
Copy link
Contributor

koobs commented Nov 15, 2019

The following two tests fail when run with an OpenSSL (1.1.1d) built without RC2 support:

  • TestPKCS12.test_load_pkcs12_ec_keys[cert-rc2-key-3des.p12-cryptography]
  • TestPKCS12.test_load_pkcs12_ec_keys[no-password.p12-None]

The error summary is: ValueError: Invalid password or PKCS12 data

Reproduction Environment:

  • Operating System: FreeBSD 13.0-CURRENT Document how to contribute private things #3 r354143: Tue Oct 29 13:10:35 AEDT 2019
  • OpenSSL: 1.1.1d-freebsd 10 Sep 2019 (via ports, with RC2 option disabled)
  • Python 2.7.17 / 3.7.5
  • cryptography: 2.8 (PyPI sdist)

Full backtraces follow:

TestPKCS12.test_load_pkcs12_ec_keys[cert-rc2-key-3des.p12-cryptography]

TestPKCS12.test_load_pkcs12_ec_keys[cert-rc2-key-3des.p12-cryptography] 
_______________________________________________________________________

self = <tests.hazmat.primitives.test_pkcs12.TestPKCS12 object at 0x8774ecc50>, filename = 'cert-rc2-key-3des.p12', password = 'cryptography', backend = <cryptography.hazmat.backends.openssl.backend.Backend object at 0x804bf5390>

    @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):
        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"
        )

tests/hazmat/primitives/test_pkcs12.py:49:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/utils.py:48: in load_vectors_from_file
    return loader(vector_file)
tests/hazmat/primitives/test_pkcs12.py:48: in <lambda>
    derfile.read(), password, backend
src/cryptography/hazmat/primitives/serialization/pkcs12.py:9: in load_key_and_certificates
    return backend.load_key_and_certificates_from_pkcs12(data, password)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <cryptography.hazmat.backends.openssl.backend.Backend object at 0x804bf5390>
data = "0\x82\x03R\x02\x01\x030\x82\x03\x18\x06\t*\x86H\x86\xf7\r\x01\x07\x01\xa0\x82\x03\t\x04\x82\x03\x050\x82\x03\x010\x82...2\x1a\x05\x00\x04\x14)\x00\x91\x90\xe8\x10I\xc3uw<U\xd4\xdc\xa7EM}C\x1b\x04\x08\xb7\xde6_\xa1\x95\xdd!\x02\x02\x08\x00", password = 'cryptography'

    def load_key_and_certificates_from_pkcs12(self, data, password):
        if password is not None:
            utils._check_byteslike("password", password)

        bio = self._bytes_to_bio(data)
        p12 = self._lib.d2i_PKCS12_bio(bio.bio, self._ffi.NULL)
        if p12 == self._ffi.NULL:
            self._consume_errors()
            raise ValueError("Could not deserialize PKCS12 data")

        p12 = self._ffi.gc(p12, self._lib.PKCS12_free)
        evp_pkey_ptr = self._ffi.new("EVP_PKEY **")
        x509_ptr = self._ffi.new("X509 **")
        sk_x509_ptr = self._ffi.new("Cryptography_STACK_OF_X509 **")
        with self._zeroed_null_terminated_buf(password) as password_buf:
            res = self._lib.PKCS12_parse(
                p12, password_buf, evp_pkey_ptr, x509_ptr, sk_x509_ptr
            )

        if res == 0:
            self._consume_errors()
>           raise ValueError("Invalid password or PKCS12 data")
E           ValueError: Invalid password or PKCS12 data

src/cryptography/hazmat/backends/openssl/backend.py:2433: ValueError

TestPKCS12.test_load_pkcs12_ec_keys[no-password.p12-None

TestPKCS12.test_load_pkcs12_ec_keys[no-password.p12-None
_________________________________________________________________________

self = <tests.hazmat.primitives.test_pkcs12.TestPKCS12 object at 0x8775bc950>, filename = 'no-password.p12', password = None, backend = <cryptography.hazmat.backends.openssl.backend.Backend object at 0x804bf5390>

    @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):
        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"
        )

tests/hazmat/primitives/test_pkcs12.py:49:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
tests/utils.py:48: in load_vectors_from_file
    return loader(vector_file)
tests/hazmat/primitives/test_pkcs12.py:48: in <lambda>
    derfile.read(), password, backend
src/cryptography/hazmat/primitives/serialization/pkcs12.py:9: in load_key_and_certificates
    return backend.load_key_and_certificates_from_pkcs12(data, password)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <cryptography.hazmat.backends.openssl.backend.Backend object at 0x804bf5390>
data = '0\x82\x03\xb0\x02\x01\x030\x82\x03w\x06\t*\x86H\x86\xf7\r\x01\x07\x01\xa0\x82\x03h\x04\x82\x03d0\x82\x03`0\x82\x02\'\...5\x00\x04\x14mL\xfc\xde\xc7i\xdc\xfd\xd4\x06x\xd7\x9d{\x19\xebm\x14"\xe4\x04\x08u+\xf6\x1b\x90\xbb\xee\xad\x02\x01\x01', password = None

    def load_key_and_certificates_from_pkcs12(self, data, password):
        if password is not None:
            utils._check_byteslike("password", password)

        bio = self._bytes_to_bio(data)
        p12 = self._lib.d2i_PKCS12_bio(bio.bio, self._ffi.NULL)
        if p12 == self._ffi.NULL:
            self._consume_errors()
            raise ValueError("Could not deserialize PKCS12 data")

        p12 = self._ffi.gc(p12, self._lib.PKCS12_free)
        evp_pkey_ptr = self._ffi.new("EVP_PKEY **")
        x509_ptr = self._ffi.new("X509 **")
        sk_x509_ptr = self._ffi.new("Cryptography_STACK_OF_X509 **")
        with self._zeroed_null_terminated_buf(password) as password_buf:
            res = self._lib.PKCS12_parse(
                p12, password_buf, evp_pkey_ptr, x509_ptr, sk_x509_ptr
            )

        if res == 0:
            self._consume_errors()
>           raise ValueError("Invalid password or PKCS12 data")
E           ValueError: Invalid password or PKCS12 data

src/cryptography/hazmat/backends/openssl/backend.py:2433: ValueError

_________________________________________________________________________
2 failed, 102886 passed, 4194 skipped, 3 warnings in 1021.08 seconds
_________________________________________________________________________
@alex
Copy link
Member

alex commented Nov 15, 2019

Thanks for tracking this down. I have no idea what the right fix is.

@alex
Copy link
Member

alex commented Nov 15, 2019

(Well, the fix is clearly to skip the test, I just don't know how to wire the "when" through all the paths)

@reaperhulk
Copy link
Member

We could make a private RC2 class that we only use for doing cipher_supported checks. That might work for this?

@alex
Copy link
Member

alex commented Nov 15, 2019 via email

alex added a commit to alex/cryptography that referenced this issue Nov 24, 2019
@alex alex self-assigned this Nov 24, 2019
alex added a commit to alex/cryptography that referenced this issue Nov 24, 2019
alex added a commit to alex/cryptography that referenced this issue Nov 24, 2019
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 27, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests

3 participants