Remove support for cryptography < 3.4 (#878)

* Stop passing backend to cryptography.

* Make public_bytes() fallback the default.

* Remove compatibility code for older cryptography versions.

* Require cryptography 3.4+.

* Restrict to cryptography >= 3.4 in integration tests.

* Remove Debian Bullseye from CI.

It only supports cryptography 3.3.

* Improve imports.

* Remove no longer existing conditional.
This commit is contained in:
Felix Fontein
2025-05-02 15:27:18 +02:00
committed by GitHub
parent e8fec768cc
commit 5231ac8f3f
102 changed files with 668 additions and 1217 deletions

View File

@@ -5,155 +5,13 @@
from __future__ import annotations
from ansible_collections.community.crypto.plugins.module_utils.version import (
LooseVersion,
)
try:
import cryptography
from cryptography import x509
# Older versions of cryptography (< 2.1) do not have __hash__ functions for
# general name objects (DNSName, IPAddress, ...), while providing overloaded
# equality and string representation operations. This makes it impossible to
# use them in hash-based data structures such as set or dict. Since we are
# actually doing that in x509_certificate, and potentially in other code,
# we need to monkey-patch __hash__ for these classes to make sure our code
# works fine.
if LooseVersion(cryptography.__version__) < LooseVersion("2.1"):
# A very simply hash function which relies on the representation
# of an object to be implemented. This is the case since at least
# cryptography 1.0, see
# https://github.com/pyca/cryptography/commit/7a9abce4bff36c05d26d8d2680303a6f64a0e84f
def simple_hash(self):
return hash(repr(self))
# The hash functions for the following types were added for cryptography 2.1:
# https://github.com/pyca/cryptography/commit/fbfc36da2a4769045f2373b004ddf0aff906cf38
x509.DNSName.__hash__ = simple_hash
x509.DirectoryName.__hash__ = simple_hash
x509.GeneralName.__hash__ = simple_hash
x509.IPAddress.__hash__ = simple_hash
x509.OtherName.__hash__ = simple_hash
x509.RegisteredID.__hash__ = simple_hash
if LooseVersion(cryptography.__version__) < LooseVersion("1.2"):
# The hash functions for the following types were added for cryptography 1.2:
# https://github.com/pyca/cryptography/commit/b642deed88a8696e5f01ce6855ccf89985fc35d0
# https://github.com/pyca/cryptography/commit/d1b5681f6db2bde7a14625538bd7907b08dfb486
x509.RFC822Name.__hash__ = simple_hash
x509.UniformResourceIdentifier.__hash__ = simple_hash
# Test whether we have support for DSA, EC, Ed25519, Ed448, RSA, X25519 and/or X448
try:
# added in 0.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/dsa/
import cryptography.hazmat.primitives.asymmetric.dsa
CRYPTOGRAPHY_HAS_DSA = True
try:
# added later in 1.5
cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey.sign
CRYPTOGRAPHY_HAS_DSA_SIGN = True
except AttributeError:
CRYPTOGRAPHY_HAS_DSA_SIGN = False
except ImportError:
CRYPTOGRAPHY_HAS_DSA = False
CRYPTOGRAPHY_HAS_DSA_SIGN = False
try:
# added in 2.6 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ed25519/
import cryptography.hazmat.primitives.asymmetric.ed25519
CRYPTOGRAPHY_HAS_ED25519 = True
try:
# added with the primitive in 2.6
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.sign
CRYPTOGRAPHY_HAS_ED25519_SIGN = True
except AttributeError:
CRYPTOGRAPHY_HAS_ED25519_SIGN = False
except ImportError:
CRYPTOGRAPHY_HAS_ED25519 = False
CRYPTOGRAPHY_HAS_ED25519_SIGN = False
try:
# added in 2.6 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ed448/
import cryptography.hazmat.primitives.asymmetric.ed448
CRYPTOGRAPHY_HAS_ED448 = True
try:
# added with the primitive in 2.6
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey.sign
CRYPTOGRAPHY_HAS_ED448_SIGN = True
except AttributeError:
CRYPTOGRAPHY_HAS_ED448_SIGN = False
except ImportError:
CRYPTOGRAPHY_HAS_ED448 = False
CRYPTOGRAPHY_HAS_ED448_SIGN = False
try:
# added in 0.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/
import cryptography.hazmat.primitives.asymmetric.ec
CRYPTOGRAPHY_HAS_EC = True
try:
# added later in 1.5
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey.sign
CRYPTOGRAPHY_HAS_EC_SIGN = True
except AttributeError:
CRYPTOGRAPHY_HAS_EC_SIGN = False
except ImportError:
CRYPTOGRAPHY_HAS_EC = False
CRYPTOGRAPHY_HAS_EC_SIGN = False
try:
# added in 0.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/
import cryptography.hazmat.primitives.asymmetric.rsa
CRYPTOGRAPHY_HAS_RSA = True
try:
# added later in 1.4
cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey.sign
CRYPTOGRAPHY_HAS_RSA_SIGN = True
except AttributeError:
CRYPTOGRAPHY_HAS_RSA_SIGN = False
except ImportError:
CRYPTOGRAPHY_HAS_RSA = False
CRYPTOGRAPHY_HAS_RSA_SIGN = False
try:
# added in 2.0 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/x25519/
import cryptography.hazmat.primitives.asymmetric.x25519
CRYPTOGRAPHY_HAS_X25519 = True
try:
# added later in 2.5
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.private_bytes
CRYPTOGRAPHY_HAS_X25519_FULL = True
except AttributeError:
CRYPTOGRAPHY_HAS_X25519_FULL = False
except ImportError:
CRYPTOGRAPHY_HAS_X25519 = False
CRYPTOGRAPHY_HAS_X25519_FULL = False
try:
# added in 2.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/x448/
import cryptography.hazmat.primitives.asymmetric.x448
CRYPTOGRAPHY_HAS_X448 = True
except ImportError:
CRYPTOGRAPHY_HAS_X448 = False
import cryptography # noqa: F401, pylint: disable=unused-import
HAS_CRYPTOGRAPHY = True
except ImportError:
# Error handled in the calling module.
CRYPTOGRAPHY_HAS_EC = False
CRYPTOGRAPHY_HAS_EC_SIGN = False
CRYPTOGRAPHY_HAS_ED25519 = False
CRYPTOGRAPHY_HAS_ED25519_SIGN = False
CRYPTOGRAPHY_HAS_ED448 = False
CRYPTOGRAPHY_HAS_ED448_SIGN = False
CRYPTOGRAPHY_HAS_DSA = False
CRYPTOGRAPHY_HAS_DSA_SIGN = False
CRYPTOGRAPHY_HAS_RSA = False
CRYPTOGRAPHY_HAS_RSA_SIGN = False
CRYPTOGRAPHY_HAS_X25519 = False
CRYPTOGRAPHY_HAS_X25519_FULL = False
CRYPTOGRAPHY_HAS_X448 = False
HAS_CRYPTOGRAPHY = False

View File

@@ -27,9 +27,11 @@ try:
import cryptography
from cryptography import x509
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.serialization.pkcs12 import (
load_key_and_certificates as _load_key_and_certificates,
)
_HAS_CRYPTOGRAPHY = True
except ImportError:
@@ -37,36 +39,15 @@ except ImportError:
# Error handled in the calling module.
pass
try:
import cryptography.hazmat.primitives.asymmetric.rsa
except ImportError:
pass
try:
import cryptography.hazmat.primitives.asymmetric.ec
except ImportError:
pass
try:
import cryptography.hazmat.primitives.asymmetric.dsa
except ImportError:
pass
try:
import cryptography.hazmat.primitives.asymmetric.ed25519
except ImportError:
pass
try:
import cryptography.hazmat.primitives.asymmetric.ed448
import cryptography.hazmat.primitives.asymmetric.ed25519
import cryptography.hazmat.primitives.asymmetric.rsa
import cryptography.hazmat.primitives.asymmetric.x448
import cryptography.hazmat.primitives.asymmetric.x25519
except ImportError:
pass
try:
# This is a separate try/except since this is only present in cryptography 2.5 or newer
from cryptography.hazmat.primitives.serialization.pkcs12 import (
load_key_and_certificates as _load_key_and_certificates,
)
except ImportError:
# Error handled in the calling module.
_load_key_and_certificates = None
try:
# This is a separate try/except since this is only present in cryptography 36.0.0 or newer
from cryptography.hazmat.primitives.serialization.pkcs12 import (
@@ -89,43 +70,40 @@ from ansible.module_utils.basic import missing_required_lib
from ._obj2txt import obj2txt
from ._objects import NORMALIZE_NAMES, NORMALIZE_NAMES_SHORT, OID_LOOKUP, OID_MAP
from .basic import (
CRYPTOGRAPHY_HAS_DSA_SIGN,
CRYPTOGRAPHY_HAS_EC_SIGN,
CRYPTOGRAPHY_HAS_ED448,
CRYPTOGRAPHY_HAS_ED448_SIGN,
CRYPTOGRAPHY_HAS_ED25519,
CRYPTOGRAPHY_HAS_ED25519_SIGN,
CRYPTOGRAPHY_HAS_RSA_SIGN,
CRYPTOGRAPHY_HAS_X448,
CRYPTOGRAPHY_HAS_X25519,
CRYPTOGRAPHY_HAS_X25519_FULL,
OpenSSLObjectError,
)
CRYPTOGRAPHY_TIMEZONE = False
_CRYPTOGRAPHY_36_0_OR_NEWER = False
if _HAS_CRYPTOGRAPHY:
CRYPTOGRAPHY_TIMEZONE = LooseVersion(cryptography.__version__) >= LooseVersion(
"42.0.0"
)
_CRYPTOGRAPHY_36_0_OR_NEWER = LooseVersion(
cryptography.__version__
) >= LooseVersion("36.0")
DOTTED_OID = re.compile(r"^\d+(?:\.\d+)+$")
def cryptography_get_extensions_from_cert(cert):
result = dict()
try:
if _CRYPTOGRAPHY_36_0_OR_NEWER:
for ext in cert.extensions:
result[ext.oid.dotted_string] = dict(
critical=ext.critical,
value=to_native(base64.b64encode(ext.value.public_bytes())),
)
else:
# Since cryptography will not give us the DER value for an extension
# (that is only stored for unrecognized extensions), we have to re-do
# the extension parsing ourselves.
from cryptography.hazmat.backends import default_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 = cert._backend
x509_obj = cert._x509
# With cryptography 35.0.0, we can no longer use obj2txt. Unfortunately it still does
@@ -154,34 +132,26 @@ def cryptography_get_extensions_from_cert(cert):
oid = exts[i].oid.dotted_string
result[oid] = entry
except Exception:
# In case the above method breaks, we likely have cryptography 36.0.0 or newer.
# Use its public_bytes() feature in that case. We will later switch this around
# so that this code will be the default, but for now this will act as a fallback
# since it will re-serialize de-serialized data, which can be different (if the
# original data was not canonicalized) from what was contained in the certificate.
for ext in cert.extensions:
result[ext.oid.dotted_string] = dict(
critical=ext.critical,
value=to_native(base64.b64encode(ext.value.public_bytes())),
)
return result
def cryptography_get_extensions_from_csr(csr):
result = dict()
try:
if _CRYPTOGRAPHY_36_0_OR_NEWER:
for ext in csr.extensions:
result[ext.oid.dotted_string] = dict(
critical=ext.critical,
value=to_native(base64.b64encode(ext.value.public_bytes())),
)
else:
# Since cryptography will not give us the DER value for an extension
# (that is only stored for unrecognized extensions), we have to re-do
# the extension parsing ourselves.
from cryptography.hazmat.backends import default_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._ffi.gc(
@@ -220,18 +190,6 @@ def cryptography_get_extensions_from_csr(csr):
oid = exts[i].oid.dotted_string
result[oid] = entry
except Exception:
# In case the above method breaks, we likely have cryptography 36.0.0 or newer.
# Use its public_bytes() feature in that case. We will later switch this around
# so that this code will be the default, but for now this will act as a fallback
# since it will re-serialize de-serialized data, which can be different (if the
# original data was not canonicalized) from what was contained in the CSR.
for ext in csr.extensions:
result[ext.oid.dotted_string] = dict(
critical=ext.critical,
value=to_native(base64.b64encode(ext.value.public_bytes())),
)
return result
@@ -665,13 +623,11 @@ def cryptography_key_needs_digest_for_signing(key):
Ed25519 and Ed448 keys do not; they need None to be passed as the digest algorithm.
"""
if CRYPTOGRAPHY_HAS_ED25519 and isinstance(
if isinstance(
key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey
):
return False
if CRYPTOGRAPHY_HAS_ED448 and isinstance(
key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey
):
if isinstance(key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey):
return False
return True
@@ -693,33 +649,28 @@ def cryptography_compare_public_keys(key1, key2):
Needs special logic for Ed25519 and Ed448 keys, since they do not have public_numbers().
"""
if CRYPTOGRAPHY_HAS_ED25519:
res = _compare_public_keys(
key1,
key2,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
)
if res is not None:
return res
if CRYPTOGRAPHY_HAS_ED448:
res = _compare_public_keys(
key1, key2, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey
)
if res is not None:
return res
res = _compare_public_keys(
key1,
key2,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
)
if res is not None:
return res
res = _compare_public_keys(
key1, key2, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey
)
if res is not None:
return res
return key1.public_numbers() == key2.public_numbers()
def _compare_private_keys(key1, key2, clazz, has_no_private_bytes=False):
def _compare_private_keys(key1, key2, clazz):
a = isinstance(key1, clazz)
b = isinstance(key2, clazz)
if not (a or b):
return None
if not a or not b:
return False
if has_no_private_bytes:
# We do not have the private_bytes() function - compare associated public keys
return cryptography_compare_public_keys(a.public_key(), b.public_key())
encryption_algorithm = cryptography.hazmat.primitives.serialization.NoEncryption()
a = key1.private_bytes(
serialization.Encoding.Raw,
@@ -739,57 +690,35 @@ def cryptography_compare_private_keys(key1, key2):
Needs special logic for Ed25519, X25519, and Ed448 keys, since they do not have private_numbers().
"""
if CRYPTOGRAPHY_HAS_ED25519:
res = _compare_private_keys(
key1,
key2,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey,
)
if res is not None:
return res
if CRYPTOGRAPHY_HAS_X25519:
res = _compare_private_keys(
key1,
key2,
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey,
has_no_private_bytes=not CRYPTOGRAPHY_HAS_X25519_FULL,
)
if res is not None:
return res
if CRYPTOGRAPHY_HAS_ED448:
res = _compare_private_keys(
key1, key2, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey
)
if res is not None:
return res
if CRYPTOGRAPHY_HAS_X448:
res = _compare_private_keys(
key1, key2, cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey
)
if res is not None:
return res
res = _compare_private_keys(
key1,
key2,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey,
)
if res is not None:
return res
res = _compare_private_keys(
key1,
key2,
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey,
)
if res is not None:
return res
res = _compare_private_keys(
key1, key2, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey
)
if res is not None:
return res
res = _compare_private_keys(
key1, key2, cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey
)
if res is not None:
return res
return key1.private_numbers() == key2.private_numbers()
def cryptography_serial_number_of_cert(cert):
"""Returns cert.serial_number.
Also works for old versions of cryptography.
"""
try:
return cert.serial_number
except AttributeError:
# The property was called "serial" before cryptography 1.4
return cert.serial
def parse_pkcs12(pkcs12_bytes, passphrase=None):
"""Returns a tuple (private_key, certificate, additional_certificates, friendly_name)."""
if _load_pkcs12 is None and _load_key_and_certificates is None:
raise ValueError(
"neither load_pkcs12() nor load_key_and_certificates() present in the current cryptography version"
)
if passphrase is not None:
passphrase = to_bytes(passphrase)
@@ -825,6 +754,8 @@ def _parse_pkcs12_35_0_0(pkcs12_bytes, passphrase=None):
friendly_name = None
if certificate:
# See https://github.com/pyca/cryptography/issues/5760#issuecomment-842687238
from cryptography.hazmat.backends import default_backend
backend = default_backend()
# This code basically does what load_key_and_certificates() does, but without error-checking.
@@ -877,7 +808,7 @@ def cryptography_verify_signature(signature, data, hash_algorithm, signer_public
Check whether the given signature of the given data was signed by the given public key object.
"""
try:
if CRYPTOGRAPHY_HAS_RSA_SIGN and isinstance(
if isinstance(
signer_public_key,
cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey,
):
@@ -885,7 +816,7 @@ def cryptography_verify_signature(signature, data, hash_algorithm, signer_public
signature, data, padding.PKCS1v15(), hash_algorithm
)
return True
if CRYPTOGRAPHY_HAS_EC_SIGN and isinstance(
if isinstance(
signer_public_key,
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey,
):
@@ -895,19 +826,19 @@ def cryptography_verify_signature(signature, data, hash_algorithm, signer_public
cryptography.hazmat.primitives.asymmetric.ec.ECDSA(hash_algorithm),
)
return True
if CRYPTOGRAPHY_HAS_DSA_SIGN and isinstance(
if isinstance(
signer_public_key,
cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey,
):
signer_public_key.verify(signature, data, hash_algorithm)
return True
if CRYPTOGRAPHY_HAS_ED25519_SIGN and isinstance(
if isinstance(
signer_public_key,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
):
signer_public_key.verify(signature, data)
return True
if CRYPTOGRAPHY_HAS_ED448_SIGN and isinstance(
if isinstance(
signer_public_key,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey,
):

View File

@@ -35,7 +35,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
)
MINIMAL_CRYPTOGRAPHY_VERSION = "1.6"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
CRYPTOGRAPHY_VERSION = None

View File

@@ -11,7 +11,6 @@ import os
from ansible.module_utils.common.text.converters import to_bytes, to_native
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
CRYPTOGRAPHY_TIMEZONE,
cryptography_serial_number_of_cert,
get_not_valid_after,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.certificate import (
@@ -179,9 +178,7 @@ class EntrustCertificateBackend(CertificateBackend):
serial_number = None
expiry = None
if self.backend == "cryptography":
serial_number = (
f"{cryptography_serial_number_of_cert(self.existing_certificate):X}"
)
serial_number = f"{self.existing_certificate.serial_number:X}"
expiry = get_not_valid_after(self.existing_certificate)
# get some information about the expiry of this certificate

View File

@@ -18,7 +18,6 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptograp
cryptography_decode_name,
cryptography_get_extensions_from_cert,
cryptography_oid_to_name,
cryptography_serial_number_of_cert,
get_not_valid_after,
get_not_valid_before,
)
@@ -37,7 +36,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
)
MINIMAL_CRYPTOGRAPHY_VERSION = "1.6"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
try:
@@ -341,20 +340,12 @@ class CertificateInfoRetrievalCryptography(CertificateInfoRetrieval):
def _get_ocsp_must_staple(self):
try:
try:
# This only works with cryptography >= 2.1
tlsfeature_ext = self.cert.extensions.get_extension_for_class(
x509.TLSFeature
)
value = (
cryptography.x509.TLSFeatureType.status_request
in tlsfeature_ext.value
)
except AttributeError:
# Fallback for cryptography < 2.1
oid = x509.oid.ObjectIdentifier("1.3.6.1.5.5.7.1.24")
tlsfeature_ext = self.cert.extensions.get_extension_for_oid(oid)
value = tlsfeature_ext.value.value == b"\x30\x03\x02\x01\x05"
tlsfeature_ext = self.cert.extensions.get_extension_for_class(
x509.TLSFeature
)
value = (
cryptography.x509.TLSFeatureType.status_request in tlsfeature_ext.value
)
return value, tlsfeature_ext.critical
except cryptography.x509.ExtensionNotFound:
return None, False
@@ -416,7 +407,7 @@ class CertificateInfoRetrievalCryptography(CertificateInfoRetrieval):
return None, None, None
def _get_serial_number(self):
return cryptography_serial_number_of_cert(self.cert)
return self.cert.serial_number
def _get_all_extensions(self):
return cryptography_get_extensions_from_cert(self.cert)

View File

@@ -15,7 +15,6 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptograp
CRYPTOGRAPHY_TIMEZONE,
cryptography_compare_public_keys,
cryptography_key_needs_digest_for_signing,
cryptography_serial_number_of_cert,
cryptography_verify_certificate_signature,
get_not_valid_after,
get_not_valid_before,
@@ -44,7 +43,6 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
try:
import cryptography
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import Encoding
except ImportError:
pass
@@ -187,21 +185,10 @@ class OwnCACertificateBackendCryptography(CertificateBackend):
critical=False,
)
try:
certificate = cert_builder.sign(
private_key=self.ca_private_key,
algorithm=self.digest,
backend=default_backend(),
)
except TypeError as e:
if (
str(e) == "Algorithm must be a registered hash algorithm."
and self.digest is None
):
self.module.fail_json(
msg="Signing with Ed25519 and Ed448 keys requires cryptography 2.8 or newer."
)
raise
certificate = cert_builder.sign(
private_key=self.ca_private_key,
algorithm=self.digest,
)
self.cert = certificate
@@ -288,7 +275,7 @@ class OwnCACertificateBackendCryptography(CertificateBackend):
"notAfter": get_not_valid_after(self.cert).strftime(
"%Y%m%d%H%M%SZ"
),
"serial_number": cryptography_serial_number_of_cert(self.cert),
"serial_number": self.cert.serial_number,
}
)

View File

@@ -11,7 +11,6 @@ from random import randrange
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
CRYPTOGRAPHY_TIMEZONE,
cryptography_key_needs_digest_for_signing,
cryptography_serial_number_of_cert,
cryptography_verify_certificate_signature,
get_not_valid_after,
get_not_valid_before,
@@ -34,7 +33,6 @@ from ansible_collections.community.crypto.plugins.module_utils.time import (
try:
import cryptography
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import Encoding
except ImportError:
pass
@@ -90,17 +88,7 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
self.module.fail_json(
msg=f'Unsupported digest "{module.params["selfsigned_digest"]}"'
)
try:
self.csr = csr.sign(self.privatekey, digest, default_backend())
except TypeError as e:
if (
str(e) == "Algorithm must be a registered hash algorithm."
and digest is None
):
self.module.fail_json(
msg="Signing with Ed25519 and Ed448 keys requires cryptography 2.8 or newer."
)
raise
self.csr = csr.sign(self.privatekey, digest)
if cryptography_key_needs_digest_for_signing(self.privatekey):
if self.digest is None:
@@ -139,21 +127,10 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
except ValueError as e:
raise CertificateError(str(e))
try:
certificate = cert_builder.sign(
private_key=self.privatekey,
algorithm=self.digest,
backend=default_backend(),
)
except TypeError as e:
if (
str(e) == "Algorithm must be a registered hash algorithm."
and self.digest is None
):
self.module.fail_json(
msg="Signing with Ed25519 and Ed448 keys requires cryptography 2.8 or newer."
)
raise
certificate = cert_builder.sign(
private_key=self.privatekey,
algorithm=self.digest,
)
self.cert = certificate
@@ -201,7 +178,7 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
"notAfter": get_not_valid_after(self.cert).strftime(
"%Y%m%d%H%M%SZ"
),
"serial_number": cryptography_serial_number_of_cert(self.cert),
"serial_number": self.cert.serial_number,
}
)

View File

@@ -26,13 +26,12 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
# crypto_utils
MINIMAL_CRYPTOGRAPHY_VERSION = "1.2"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
try:
import cryptography
from cryptography import x509
from cryptography.hazmat.backends import default_backend
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
except ImportError:
@@ -54,9 +53,9 @@ class CRLInfoRetrieval:
self.crl_pem = identify_pem_format(self.content)
try:
if self.crl_pem:
self.crl = x509.load_pem_x509_crl(self.content, default_backend())
self.crl = x509.load_pem_x509_crl(self.content)
else:
self.crl = x509.load_der_x509_crl(self.content, default_backend())
self.crl = x509.load_der_x509_crl(self.content)
except ValueError as e:
self.module.fail_json(msg=f"Error while decoding CRL: {e}")

View File

@@ -45,7 +45,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
)
MINIMAL_CRYPTOGRAPHY_VERSION = "1.3"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
try:
@@ -309,19 +309,11 @@ def parse_crl_distribution_points(module, crl_distribution_points):
if parse_crl_distribution_point["relative_name"] is not None:
if not parse_crl_distribution_point["relative_name"]:
raise OpenSSLObjectError("relative_name must not be empty")
try:
params["relative_name"] = (
cryptography_parse_relative_distinguished_name(
parse_crl_distribution_point["relative_name"]
)
params["relative_name"] = (
cryptography_parse_relative_distinguished_name(
parse_crl_distribution_point["relative_name"]
)
except Exception:
# If cryptography's version is < 1.6, the error is probably caused by that
if CRYPTOGRAPHY_VERSION < LooseVersion("1.6"):
raise OpenSSLObjectError(
"Cannot specify relative_name for cryptography < 1.6"
)
raise
)
if parse_crl_distribution_point["crl_issuer"] is not None:
if not parse_crl_distribution_point["crl_issuer"]:
raise OpenSSLObjectError("crl_issuer must not be empty")
@@ -348,7 +340,6 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
super(CertificateSigningRequestCryptographyBackend, self).__init__(
module, "cryptography"
)
self.cryptography_backend = cryptography.hazmat.backends.default_backend()
if self.version != 1:
module.warn(
"The cryptography backend only supports version 1. (The only valid value according to RFC 2986.)"
@@ -410,21 +401,12 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
)
if self.ocspMustStaple:
try:
# This only works with cryptography >= 2.1
csr = csr.add_extension(
cryptography.x509.TLSFeature(
[cryptography.x509.TLSFeatureType.status_request]
),
critical=self.ocspMustStaple_critical,
)
except AttributeError:
csr = csr.add_extension(
cryptography.x509.UnrecognizedExtension(
CRYPTOGRAPHY_MUST_STAPLE_NAME, CRYPTOGRAPHY_MUST_STAPLE_VALUE
),
critical=self.ocspMustStaple_critical,
)
csr = csr.add_extension(
cryptography.x509.TLSFeature(
[cryptography.x509.TLSFeatureType.status_request]
),
critical=self.ocspMustStaple_critical,
)
if self.name_constraints_permitted or self.name_constraints_excluded:
try:
@@ -493,16 +475,7 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
f'Unsupported digest "{self.digest}"'
)
try:
self.csr = csr.sign(self.privatekey, digest, self.cryptography_backend)
except TypeError as e:
if (
str(e) == "Algorithm must be a registered hash algorithm."
and digest is None
):
self.module.fail_json(
msg="Signing with Ed25519 and Ed448 keys requires cryptography 2.8 or newer."
)
raise
self.csr = csr.sign(self.privatekey, digest)
except UnicodeError as e:
# This catches IDNAErrors, which happens when a bad name is passed as a SAN
# (https://github.com/ansible-collections/community.crypto/issues/105).
@@ -636,22 +609,8 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
return bc_ext is None
def _check_ocspMustStaple(extensions):
try:
# This only works with cryptography >= 2.1
tlsfeature_ext = _find_extension(
extensions, cryptography.x509.TLSFeature
)
has_tlsfeature = True
except AttributeError:
tlsfeature_ext = next(
(
ext
for ext in extensions
if ext.value.oid == CRYPTOGRAPHY_MUST_STAPLE_NAME
),
None,
)
has_tlsfeature = False
tlsfeature_ext = _find_extension(extensions, cryptography.x509.TLSFeature)
has_tlsfeature = True
if self.ocspMustStaple:
if (
not tlsfeature_ext

View File

@@ -29,7 +29,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
)
MINIMAL_CRYPTOGRAPHY_VERSION = "1.3"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
try:
@@ -267,20 +267,13 @@ class CSRInfoRetrievalCryptography(CSRInfoRetrieval):
def _get_ocsp_must_staple(self):
try:
try:
# This only works with cryptography >= 2.1
tlsfeature_ext = self.csr.extensions.get_extension_for_class(
x509.TLSFeature
)
value = (
cryptography.x509.TLSFeatureType.status_request
in tlsfeature_ext.value
)
except AttributeError:
# Fallback for cryptography < 2.1
oid = x509.oid.ObjectIdentifier("1.3.6.1.5.5.7.1.24")
tlsfeature_ext = self.csr.extensions.get_extension_for_oid(oid)
value = tlsfeature_ext.value.value == b"\x30\x03\x02\x01\x05"
# This only works with cryptography >= 2.1
tlsfeature_ext = self.csr.extensions.get_extension_for_class(
x509.TLSFeature
)
value = (
cryptography.x509.TLSFeatureType.status_request in tlsfeature_ext.value
)
return value, tlsfeature_ext.critical
except cryptography.x509.ExtensionNotFound:
return None, False

View File

@@ -16,11 +16,6 @@ from ansible_collections.community.crypto.plugins.module_utils.argspec import (
ArgumentSpec,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
CRYPTOGRAPHY_HAS_ED448,
CRYPTOGRAPHY_HAS_ED25519,
CRYPTOGRAPHY_HAS_X448,
CRYPTOGRAPHY_HAS_X25519,
CRYPTOGRAPHY_HAS_X25519_FULL,
OpenSSLObjectError,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.privatekey_info import (
@@ -39,7 +34,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
)
MINIMAL_CRYPTOGRAPHY_VERSION = "1.2.3"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
try:
@@ -48,8 +43,12 @@ try:
import cryptography.hazmat.backends
import cryptography.hazmat.primitives.asymmetric.dsa
import cryptography.hazmat.primitives.asymmetric.ec
import cryptography.hazmat.primitives.asymmetric.ed448
import cryptography.hazmat.primitives.asymmetric.ed25519
import cryptography.hazmat.primitives.asymmetric.rsa
import cryptography.hazmat.primitives.asymmetric.utils
import cryptography.hazmat.primitives.asymmetric.x448
import cryptography.hazmat.primitives.asymmetric.x25519
import cryptography.hazmat.primitives.serialization
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
@@ -320,27 +319,6 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
self._add_curve("brainpoolP384r1", "BrainpoolP384R1", deprecated=True)
self._add_curve("brainpoolP512r1", "BrainpoolP512R1", deprecated=True)
self.cryptography_backend = cryptography.hazmat.backends.default_backend()
if not CRYPTOGRAPHY_HAS_X25519 and self.type == "X25519":
self.module.fail_json(
msg="Your cryptography version does not support X25519"
)
if not CRYPTOGRAPHY_HAS_X25519_FULL and self.type == "X25519":
self.module.fail_json(
msg="Your cryptography version does not support X25519 serialization"
)
if not CRYPTOGRAPHY_HAS_X448 and self.type == "X448":
self.module.fail_json(msg="Your cryptography version does not support X448")
if not CRYPTOGRAPHY_HAS_ED25519 and self.type == "Ed25519":
self.module.fail_json(
msg="Your cryptography version does not support Ed25519"
)
if not CRYPTOGRAPHY_HAS_ED448 and self.type == "Ed448":
self.module.fail_json(
msg="Your cryptography version does not support Ed448"
)
def _get_wanted_format(self):
if self.format not in ("auto", "auto_ignore"):
return self.format
@@ -357,28 +335,27 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key(
public_exponent=65537, # OpenSSL always uses this
key_size=self.size,
backend=self.cryptography_backend,
)
)
if self.type == "DSA":
self.private_key = (
cryptography.hazmat.primitives.asymmetric.dsa.generate_private_key(
key_size=self.size, backend=self.cryptography_backend
key_size=self.size
)
)
if CRYPTOGRAPHY_HAS_X25519_FULL and self.type == "X25519":
if self.type == "X25519":
self.private_key = (
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.generate()
)
if CRYPTOGRAPHY_HAS_X448 and self.type == "X448":
if self.type == "X448":
self.private_key = (
cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey.generate()
)
if CRYPTOGRAPHY_HAS_ED25519 and self.type == "Ed25519":
if self.type == "Ed25519":
self.private_key = (
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.generate()
)
if CRYPTOGRAPHY_HAS_ED448 and self.type == "Ed448":
if self.type == "Ed448":
self.private_key = (
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey.generate()
)
@@ -390,7 +367,6 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
self.private_key = (
cryptography.hazmat.primitives.asymmetric.ec.generate_private_key(
curve=self.curves[self.curve]["create"](self.size),
backend=self.cryptography_backend,
)
)
except cryptography.exceptions.UnsupportedAlgorithm:
@@ -462,43 +438,37 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
# Interpret bytes depending on format.
format = identify_private_key_format(data)
if format == "raw":
if len(data) == 56 and CRYPTOGRAPHY_HAS_X448:
if len(data) == 56:
return cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey.from_private_bytes(
data
)
if len(data) == 57 and CRYPTOGRAPHY_HAS_ED448:
if len(data) == 57:
return cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey.from_private_bytes(
data
)
if len(data) == 32:
if CRYPTOGRAPHY_HAS_X25519 and (
self.type == "X25519" or not CRYPTOGRAPHY_HAS_ED25519
):
if self.type == "X25519":
return cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
data
)
if CRYPTOGRAPHY_HAS_ED25519 and (
self.type == "Ed25519" or not CRYPTOGRAPHY_HAS_X25519
):
if self.type == "Ed25519":
return cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
data
)
try:
return cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
data
)
except Exception:
return cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
data
)
if CRYPTOGRAPHY_HAS_X25519 and CRYPTOGRAPHY_HAS_ED25519:
try:
return cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
data
)
except Exception:
return cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
data
)
raise PrivateKeyError("Cannot load raw key")
else:
return (
cryptography.hazmat.primitives.serialization.load_pem_private_key(
data,
None if self.passphrase is None else to_bytes(self.passphrase),
backend=self.cryptography_backend,
)
)
except Exception as e:
@@ -523,7 +493,6 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
cryptography.hazmat.primitives.serialization.load_pem_private_key(
self.existing_private_key_bytes,
None if self.passphrase is None else to_bytes(self.passphrase),
backend=self.cryptography_backend,
)
)
except Exception:
@@ -544,22 +513,22 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
return (
self.type == "DSA" and self.size == self.existing_private_key.key_size
)
if CRYPTOGRAPHY_HAS_X25519 and isinstance(
if isinstance(
self.existing_private_key,
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey,
):
return self.type == "X25519"
if CRYPTOGRAPHY_HAS_X448 and isinstance(
if isinstance(
self.existing_private_key,
cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey,
):
return self.type == "X448"
if CRYPTOGRAPHY_HAS_ED25519 and isinstance(
if isinstance(
self.existing_private_key,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey,
):
return self.type == "Ed25519"
if CRYPTOGRAPHY_HAS_ED448 and isinstance(
if isinstance(
self.existing_private_key,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey,
):

View File

@@ -14,10 +14,6 @@ from ansible_collections.community.crypto.plugins.module_utils.argspec import (
ArgumentSpec,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
CRYPTOGRAPHY_HAS_ED448,
CRYPTOGRAPHY_HAS_ED25519,
CRYPTOGRAPHY_HAS_X448,
CRYPTOGRAPHY_HAS_X25519,
OpenSSLObjectError,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
@@ -32,7 +28,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
)
MINIMAL_CRYPTOGRAPHY_VERSION = "1.2.3"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
try:
@@ -41,8 +37,12 @@ try:
import cryptography.hazmat.backends
import cryptography.hazmat.primitives.asymmetric.dsa
import cryptography.hazmat.primitives.asymmetric.ec
import cryptography.hazmat.primitives.asymmetric.ed448
import cryptography.hazmat.primitives.asymmetric.ed25519
import cryptography.hazmat.primitives.asymmetric.rsa
import cryptography.hazmat.primitives.asymmetric.utils
import cryptography.hazmat.primitives.asymmetric.x448
import cryptography.hazmat.primitives.asymmetric.x25519
import cryptography.hazmat.primitives.serialization
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
@@ -136,8 +136,6 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
module=module, backend="cryptography"
)
self.cryptography_backend = cryptography.hazmat.backends.default_backend()
def get_private_key_data(self):
"""Return bytes for self.src_private_key in output format"""
# Select export format and encoding
@@ -199,14 +197,14 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
if format == "raw":
if passphrase is not None:
raise PrivateKeyError("Cannot load raw key with passphrase")
if len(data) == 56 and CRYPTOGRAPHY_HAS_X448:
if len(data) == 56:
return (
format,
cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey.from_private_bytes(
data
),
)
if len(data) == 57 and CRYPTOGRAPHY_HAS_ED448:
if len(data) == 57:
return (
format,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey.from_private_bytes(
@@ -214,54 +212,39 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
),
)
if len(data) == 32:
if CRYPTOGRAPHY_HAS_X25519 and not CRYPTOGRAPHY_HAS_ED25519:
return (
format,
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
data
),
)
if CRYPTOGRAPHY_HAS_ED25519 and not CRYPTOGRAPHY_HAS_X25519:
return (
format,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
data
),
)
if CRYPTOGRAPHY_HAS_X25519 and CRYPTOGRAPHY_HAS_ED25519:
if isinstance(
current_hint,
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey,
):
try:
return (
format,
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
data
),
)
except Exception:
return (
format,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
data
),
)
else:
try:
return (
format,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
data
),
)
except Exception:
return (
format,
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
data
),
)
if isinstance(
current_hint,
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey,
):
try:
return (
format,
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
data
),
)
except Exception:
return (
format,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
data
),
)
else:
try:
return (
format,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
data
),
)
except Exception:
return (
format,
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
data
),
)
raise PrivateKeyError("Cannot load raw key")
else:
return (
@@ -269,7 +252,6 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
cryptography.hazmat.primitives.serialization.load_pem_private_key(
data,
None if passphrase is None else to_bytes(passphrase),
backend=self.cryptography_backend,
),
)
except Exception as e:

View File

@@ -13,8 +13,6 @@ from ansible.module_utils import six
from ansible.module_utils.basic import missing_required_lib
from ansible.module_utils.common.text.converters import to_bytes, to_native
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
CRYPTOGRAPHY_HAS_ED448,
CRYPTOGRAPHY_HAS_ED25519,
OpenSSLObjectError,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.math import (
@@ -33,7 +31,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
)
MINIMAL_CRYPTOGRAPHY_VERSION = "1.2.3"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
try:
@@ -115,13 +113,9 @@ def _is_cryptography_key_consistent(
result = _check_dsa_consistency(key_public_data, key_private_data)
if result is not None:
return result
try:
signature = key.sign(
SIGNATURE_TEST_DATA, cryptography.hazmat.primitives.hashes.SHA256()
)
except AttributeError:
# sign() was added in cryptography 1.5, but we support older versions
return None
signature = key.sign(
SIGNATURE_TEST_DATA, cryptography.hazmat.primitives.hashes.SHA256()
)
try:
key.public_key().verify(
signature,
@@ -134,16 +128,12 @@ def _is_cryptography_key_consistent(
if isinstance(
key, cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey
):
try:
signature = key.sign(
SIGNATURE_TEST_DATA,
cryptography.hazmat.primitives.asymmetric.ec.ECDSA(
cryptography.hazmat.primitives.hashes.SHA256()
),
)
except AttributeError:
# sign() was added in cryptography 1.5, but we support older versions
return None
signature = key.sign(
SIGNATURE_TEST_DATA,
cryptography.hazmat.primitives.asymmetric.ec.ECDSA(
cryptography.hazmat.primitives.hashes.SHA256()
),
)
try:
key.public_key().verify(
signature,
@@ -156,13 +146,11 @@ def _is_cryptography_key_consistent(
except cryptography.exceptions.InvalidSignature:
return False
has_simple_sign_function = False
if CRYPTOGRAPHY_HAS_ED25519 and isinstance(
if isinstance(
key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey
):
has_simple_sign_function = True
if CRYPTOGRAPHY_HAS_ED448 and isinstance(
key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey
):
if isinstance(key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey):
has_simple_sign_function = True
if has_simple_sign_function:
signature = key.sign(SIGNATURE_TEST_DATA)

View File

@@ -11,10 +11,6 @@ from ansible.module_utils import six
from ansible.module_utils.basic import missing_required_lib
from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
CRYPTOGRAPHY_HAS_ED448,
CRYPTOGRAPHY_HAS_ED25519,
CRYPTOGRAPHY_HAS_X448,
CRYPTOGRAPHY_HAS_X25519,
OpenSSLObjectError,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
@@ -26,11 +22,15 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
)
MINIMAL_CRYPTOGRAPHY_VERSION = "1.2.3"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
try:
import cryptography
import cryptography.hazmat.primitives.asymmetric.ed448
import cryptography.hazmat.primitives.asymmetric.ed25519
import cryptography.hazmat.primitives.asymmetric.x448
import cryptography.hazmat.primitives.asymmetric.x25519
from cryptography.hazmat.primitives import serialization
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
@@ -58,19 +58,17 @@ def _get_cryptography_public_key_info(key):
key_public_data["q"] = parameter_numbers.q
key_public_data["g"] = parameter_numbers.g
key_public_data["y"] = public_numbers.y
elif CRYPTOGRAPHY_HAS_X25519 and isinstance(
elif isinstance(
key, cryptography.hazmat.primitives.asymmetric.x25519.X25519PublicKey
):
key_type = "X25519"
elif CRYPTOGRAPHY_HAS_X448 and isinstance(
key, cryptography.hazmat.primitives.asymmetric.x448.X448PublicKey
):
elif isinstance(key, cryptography.hazmat.primitives.asymmetric.x448.X448PublicKey):
key_type = "X448"
elif CRYPTOGRAPHY_HAS_ED25519 and isinstance(
elif isinstance(
key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey
):
key_type = "Ed25519"
elif CRYPTOGRAPHY_HAS_ED448 and isinstance(
elif isinstance(
key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey
):
key_type = "Ed448"

View File

@@ -26,7 +26,6 @@ from ansible_collections.community.crypto.plugins.module_utils.time import ( #
try:
from cryptography import x509
from cryptography.hazmat.backends import default_backend as cryptography_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.serialization import load_pem_private_key
except ImportError:
@@ -151,7 +150,6 @@ def load_privatekey(
result = load_pem_private_key(
priv_key_detail,
None if passphrase is None else to_bytes(passphrase),
cryptography_backend(),
)
except TypeError:
raise OpenSSLBadPassphraseError(
@@ -175,9 +173,7 @@ def load_publickey(path=None, content=None, backend=None):
if backend == "cryptography":
try:
return serialization.load_pem_public_key(
content, backend=cryptography_backend()
)
return serialization.load_pem_public_key(content)
except Exception as e:
raise OpenSSLObjectError(f"Error while deserializing key: {e}")
@@ -198,16 +194,12 @@ def load_certificate(
if backend == "cryptography":
if der_support_enabled is False or identify_pem_format(cert_content):
try:
return x509.load_pem_x509_certificate(
cert_content, cryptography_backend()
)
return x509.load_pem_x509_certificate(cert_content)
except ValueError as exc:
raise OpenSSLObjectError(exc)
elif der_support_enabled:
try:
return x509.load_der_x509_certificate(
cert_content, cryptography_backend()
)
return x509.load_der_x509_certificate(cert_content)
except ValueError as exc:
raise OpenSSLObjectError(f"Cannot parse DER certificate: {exc}")
@@ -224,7 +216,7 @@ def load_certificate_request(path, content=None, backend="cryptography"):
raise OpenSSLObjectError(exc)
if backend == "cryptography":
try:
return x509.load_pem_x509_csr(csr_content, cryptography_backend())
return x509.load_pem_x509_csr(csr_content)
except ValueError as exc:
raise OpenSSLObjectError(exc)