Support cryptography 35.0.0 for all modules except openssl_pkcs12 (#294)
* Add some workarounds for cryptography 35.0.0. * Make fix work with very old cryptography versions as well (which supported multiple backends). * [TEMP] Disable openssl_pkcs12 tests to see whether everything else works. * Revert "[TEMP] Disable openssl_pkcs12 tests to see whether everything else works." This reverts commitpull/296/head3f905bc795
. * Add changelog fragment. * Remove unnecessary assignment. * Simplify code change. * [TEMP] Disable openssl_pkcs12 tests to see whether everything else works. * Revert "[TEMP] Disable openssl_pkcs12 tests to see whether everything else works." This reverts commitfdb210528e
.
parent
2a7e452cf8
commit
a2a7d94055
|
@ -0,0 +1,4 @@
|
||||||
|
bugfixes:
|
||||||
|
- "get_certificate - fix compatibility with the cryptography 35.0.0 release (https://github.com/ansible-collections/community.crypto/pull/294)."
|
||||||
|
- "openssl_csr_info - fix compatibility with the cryptography 35.0.0 release (https://github.com/ansible-collections/community.crypto/pull/294)."
|
||||||
|
- "x509_certificate_info - fix compatibility with the cryptography 35.0.0 release (https://github.com/ansible-collections/community.crypto/pull/294)."
|
|
@ -20,6 +20,10 @@ from __future__ import absolute_import, division, print_function
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
|
|
||||||
|
# WARNING: this function no longer works with cryptography 35.0.0 and newer!
|
||||||
|
# It must **ONLY** be used in compatibility code for older
|
||||||
|
# cryptography versions!
|
||||||
|
|
||||||
def obj2txt(openssl_lib, openssl_ffi, obj):
|
def obj2txt(openssl_lib, openssl_ffi, obj):
|
||||||
# Set to 80 on the recommendation of
|
# Set to 80 on the recommendation of
|
||||||
# https://www.openssl.org/docs/crypto/OBJ_nid2ln.html#return_values
|
# https://www.openssl.org/docs/crypto/OBJ_nid2ln.html#return_values
|
||||||
|
|
|
@ -30,6 +30,7 @@ from ._asn1 import serialize_asn1_string_as_der
|
||||||
try:
|
try:
|
||||||
import cryptography
|
import cryptography
|
||||||
from cryptography import x509
|
from cryptography import x509
|
||||||
|
from cryptography.hazmat.backends import default_backend
|
||||||
from cryptography.hazmat.primitives import serialization
|
from cryptography.hazmat.primitives import serialization
|
||||||
import ipaddress
|
import ipaddress
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -68,9 +69,19 @@ def cryptography_get_extensions_from_cert(cert):
|
||||||
# Since cryptography won't give us the DER value for an extension
|
# Since cryptography won't give us the DER value for an extension
|
||||||
# (that is only stored for unrecognized extensions), we have to re-do
|
# (that is only stored for unrecognized extensions), we have to re-do
|
||||||
# the extension parsing outselves.
|
# the extension parsing outselves.
|
||||||
|
backend = default_backend()
|
||||||
|
try:
|
||||||
|
# For certain old versions of cryptography, backend is a MultiBackend object,
|
||||||
|
# which has no _lib attribute. In that case, revert to the old approach.
|
||||||
|
backend._lib
|
||||||
|
except AttributeError:
|
||||||
|
backend = cert._backend
|
||||||
|
|
||||||
result = dict()
|
result = dict()
|
||||||
backend = cert._backend
|
|
||||||
x509_obj = cert._x509
|
x509_obj = cert._x509
|
||||||
|
# With cryptography 35.0.0, we can no longer use obj2txt. Unfortunately it still does
|
||||||
|
# not allow to get the raw value of an extension, so we have to use this ugly hack:
|
||||||
|
exts = list(cert.extensions)
|
||||||
|
|
||||||
for i in range(backend._lib.X509_get_ext_count(x509_obj)):
|
for i in range(backend._lib.X509_get_ext_count(x509_obj)):
|
||||||
ext = backend._lib.X509_get_ext(x509_obj, i)
|
ext = backend._lib.X509_get_ext(x509_obj, i)
|
||||||
|
@ -84,8 +95,12 @@ def cryptography_get_extensions_from_cert(cert):
|
||||||
critical=(crit == 1),
|
critical=(crit == 1),
|
||||||
value=base64.b64encode(der),
|
value=base64.b64encode(der),
|
||||||
)
|
)
|
||||||
oid = obj2txt(backend._lib, backend._ffi, backend._lib.X509_EXTENSION_get_object(ext))
|
try:
|
||||||
|
oid = obj2txt(backend._lib, backend._ffi, backend._lib.X509_EXTENSION_get_object(ext))
|
||||||
|
except AttributeError:
|
||||||
|
oid = exts[i].oid.dotted_string
|
||||||
result[oid] = entry
|
result[oid] = entry
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@ -94,7 +109,13 @@ def cryptography_get_extensions_from_csr(csr):
|
||||||
# (that is only stored for unrecognized extensions), we have to re-do
|
# (that is only stored for unrecognized extensions), we have to re-do
|
||||||
# the extension parsing outselves.
|
# the extension parsing outselves.
|
||||||
result = dict()
|
result = dict()
|
||||||
backend = csr._backend
|
backend = default_backend()
|
||||||
|
try:
|
||||||
|
# For certain old versions of cryptography, backend is a MultiBackend object,
|
||||||
|
# which has no _lib attribute. In that case, revert to the old approach.
|
||||||
|
backend._lib
|
||||||
|
except AttributeError:
|
||||||
|
backend = csr._backend
|
||||||
|
|
||||||
extensions = backend._lib.X509_REQ_get_extensions(csr._x509_req)
|
extensions = backend._lib.X509_REQ_get_extensions(csr._x509_req)
|
||||||
extensions = backend._ffi.gc(
|
extensions = backend._ffi.gc(
|
||||||
|
@ -105,6 +126,10 @@ def cryptography_get_extensions_from_csr(csr):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# With cryptography 35.0.0, we can no longer use obj2txt. Unfortunately it still does
|
||||||
|
# not allow to get the raw value of an extension, so we have to use this ugly hack:
|
||||||
|
exts = list(csr.extensions)
|
||||||
|
|
||||||
for i in range(backend._lib.sk_X509_EXTENSION_num(extensions)):
|
for i in range(backend._lib.sk_X509_EXTENSION_num(extensions)):
|
||||||
ext = backend._lib.sk_X509_EXTENSION_value(extensions, i)
|
ext = backend._lib.sk_X509_EXTENSION_value(extensions, i)
|
||||||
if ext == backend._ffi.NULL:
|
if ext == backend._ffi.NULL:
|
||||||
|
@ -117,8 +142,12 @@ def cryptography_get_extensions_from_csr(csr):
|
||||||
critical=(crit == 1),
|
critical=(crit == 1),
|
||||||
value=base64.b64encode(der),
|
value=base64.b64encode(der),
|
||||||
)
|
)
|
||||||
oid = obj2txt(backend._lib, backend._ffi, backend._lib.X509_EXTENSION_get_object(ext))
|
try:
|
||||||
|
oid = obj2txt(backend._lib, backend._ffi, backend._lib.X509_EXTENSION_get_object(ext))
|
||||||
|
except AttributeError:
|
||||||
|
oid = exts[i].oid.dotted_string
|
||||||
result[oid] = entry
|
result[oid] = entry
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
@ -489,9 +518,15 @@ def parse_pkcs12(pkcs12_bytes, passphrase=None):
|
||||||
friendly_name = None
|
friendly_name = None
|
||||||
if certificate:
|
if certificate:
|
||||||
# See https://github.com/pyca/cryptography/issues/5760#issuecomment-842687238
|
# See https://github.com/pyca/cryptography/issues/5760#issuecomment-842687238
|
||||||
maybe_name = certificate._backend._lib.X509_alias_get0(
|
backend = default_backend()
|
||||||
certificate._x509, certificate._backend._ffi.NULL)
|
try:
|
||||||
if maybe_name != certificate._backend._ffi.NULL:
|
# For certain old versions of cryptography, backend is a MultiBackend object,
|
||||||
friendly_name = certificate._backend._ffi.string(maybe_name)
|
# which has no _lib attribute. In that case, revert to the old approach.
|
||||||
|
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)
|
||||||
|
|
||||||
return private_key, certificate, additional_certificates, friendly_name
|
return private_key, certificate, additional_certificates, friendly_name
|
||||||
|
|
Loading…
Reference in New Issue