diff --git a/changelogs/fragments/296-openssl_pkcs12-cryptography-35.yml b/changelogs/fragments/296-openssl_pkcs12-cryptography-35.yml new file mode 100644 index 00000000..63f90aa3 --- /dev/null +++ b/changelogs/fragments/296-openssl_pkcs12-cryptography-35.yml @@ -0,0 +1,2 @@ +bugfixes: + - "openssl_pkcs12 - fix compatibility with the cryptography 35.0.0 release (https://github.com/ansible-collections/community.crypto/pull/296)." diff --git a/plugins/module_utils/crypto/cryptography_support.py b/plugins/module_utils/crypto/cryptography_support.py index 82d3e7b8..edec7853 100644 --- a/plugins/module_utils/crypto/cryptography_support.py +++ b/plugins/module_utils/crypto/cryptography_support.py @@ -24,6 +24,8 @@ import binascii import re import sys +from distutils.version import LooseVersion + from ansible.module_utils.common.text.converters import to_text, to_bytes from ._asn1 import serialize_asn1_string_as_der @@ -525,8 +527,28 @@ def parse_pkcs12(pkcs12_bytes, passphrase=None): backend._lib except AttributeError: backend = certificate._backend - maybe_name = backend._lib.X509_alias_get0(certificate._x509, backend._ffi.NULL) - if maybe_name != backend._ffi.NULL: - friendly_name = backend._ffi.string(maybe_name) + if LooseVersion(cryptography.__version__) >= LooseVersion('35.0'): + # This code basically does what load_key_and_certificates() does, but without error-checking. + # Since load_key_and_certificates succeeded, it should not fail. + pkcs12 = backend._ffi.gc( + backend._lib.d2i_PKCS12_bio(backend._bytes_to_bio(pkcs12_bytes).bio, backend._ffi.NULL), + backend._lib.PKCS12_free) + certificate_x509_ptr = backend._ffi.new("X509 **") + with backend._zeroed_null_terminated_buf(to_bytes(passphrase) if passphrase is not None else None) as passphrase_buffer: + backend._lib.PKCS12_parse( + pkcs12, + passphrase_buffer, + backend._ffi.new("EVP_PKEY **"), + certificate_x509_ptr, + backend._ffi.new("Cryptography_STACK_OF_X509 **")) + if certificate_x509_ptr[0] != backend._ffi.NULL: + maybe_name = backend._lib.X509_alias_get0(certificate_x509_ptr[0], backend._ffi.NULL) + if maybe_name != backend._ffi.NULL: + friendly_name = backend._ffi.string(maybe_name) + else: + # cryptography < 35.0.0 + maybe_name = backend._lib.X509_alias_get0(certificate._x509, backend._ffi.NULL) + if maybe_name != backend._ffi.NULL: + friendly_name = backend._ffi.string(maybe_name) return private_key, certificate, additional_certificates, friendly_name