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

@@ -18,7 +18,7 @@ notes:
another ACME server, please L(create an issue,https://github.com/ansible-collections/community.crypto/issues/new/choose)
to help us supporting it. Feedback that an ACME server not mentioned does work is also appreciated.
requirements:
- either openssl or L(cryptography,https://cryptography.io/) >= 1.5
- either openssl or L(cryptography,https://cryptography.io/) >= 3.4
options:
acme_version:
description:

View File

@@ -22,7 +22,7 @@ attributes:
- If relative timestamps are used and O(ignore_timestamps=false), the module is not idempotent.
- The option O(force=true) generally disables idempotency.
requirements:
- cryptography >= 1.6 (if using V(selfsigned) or V(ownca) provider)
- cryptography >= 3.4 (if using V(selfsigned) or V(ownca) provider)
options:
force:
description:
@@ -304,7 +304,6 @@ options:
ignored.
- A value of V(never_create) never creates a SKI. If the CSR provides one, that one is used.
- This is only used by the V(ownca) provider.
- Note that this is only supported if the C(cryptography) backend is used!
type: str
choices: [create_if_not_provided, always_create, never_create]
default: create_if_not_provided
@@ -316,7 +315,6 @@ options:
- The Authority Key Identifier is generated from the CA certificate's Subject Key Identifier,
if available. If it is not available, the CA certificate's public key will be used.
- This is only used by the V(ownca) provider.
- Note that this is only supported if the C(cryptography) backend is used!
type: bool
default: true
"""
@@ -403,7 +401,6 @@ options:
ignored.
- A value of V(never_create) never creates a SKI. If the CSR provides one, that one is used.
- This is only used by the V(selfsigned) provider.
- Note that this is only supported if the C(cryptography) backend is used!
type: str
choices: [create_if_not_provided, always_create, never_create]
default: create_if_not_provided

View File

@@ -18,7 +18,7 @@ attributes:
idempotent:
support: full
requirements:
- cryptography >= 1.3
- cryptography >= 3.4
options:
digest:
description:
@@ -237,7 +237,6 @@ options:
- Create the Subject Key Identifier from the public key.
- Please note that commercial CAs can ignore the value, respectively use a value of their own choice instead. Specifying
this option is mostly useful for self-signed certificates or for own CAs.
- Note that this is only supported if the C(cryptography) backend is used!
type: bool
default: false
subject_key_identifier:
@@ -247,7 +246,6 @@ options:
- Please note that commercial CAs ignore this value, respectively use a value of their own choice. Specifying this option
is mostly useful for self-signed certificates or for own CAs.
- Note that this option can only be used if O(create_subject_key_identifier) is V(false).
- Note that this is only supported if the C(cryptography) backend is used!
type: str
authority_key_identifier:
description:
@@ -255,7 +253,6 @@ options:
- 'Example: V(00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22:33).'
- Please note that commercial CAs ignore this value, respectively use a value of their own choice. Specifying this option
is mostly useful for self-signed certificates or for own CAs.
- Note that this is only supported if the C(cryptography) backend is used!
- The C(AuthorityKeyIdentifier) extension will only be added if at least one of O(authority_key_identifier), O(authority_cert_issuer)
and O(authority_cert_serial_number) is specified.
type: str
@@ -268,7 +265,6 @@ options:
- If specified, O(authority_cert_serial_number) must also be specified.
- Please note that commercial CAs ignore this value, respectively use a value of their own choice. Specifying this option
is mostly useful for self-signed certificates or for own CAs.
- Note that this is only supported if the C(cryptography) backend is used!
- The C(AuthorityKeyIdentifier) extension will only be added if at least one of O(authority_key_identifier), O(authority_cert_issuer)
and O(authority_cert_serial_number) is specified.
type: list
@@ -277,7 +273,6 @@ options:
description:
- The authority cert serial number.
- If specified, O(authority_cert_issuer) must also be specified.
- Note that this is only supported if the C(cryptography) backend is used!
- Please note that commercial CAs ignore this value, respectively use a value of their own choice. Specifying this option
is mostly useful for self-signed certificates or for own CAs.
- The C(AuthorityKeyIdentifier) extension will only be added if at least one of O(authority_key_identifier), O(authority_cert_issuer)
@@ -288,7 +283,6 @@ options:
crl_distribution_points:
description:
- Allows to specify one or multiple CRL distribution points.
- Only supported by the C(cryptography) backend.
type: list
elements: dict
suboptions:
@@ -304,7 +298,6 @@ options:
- Describes how the CRL can be retrieved relative to the CRL issuer.
- Mutually exclusive with O(crl_distribution_points[].full_name).
- 'Example: V(/CN=example.com).'
- Can only be used when cryptography >= 1.6 is installed.
type: list
elements: str
crl_issuer:

View File

@@ -22,7 +22,7 @@ attributes:
details:
- The option O(regenerate=always) generally disables idempotency.
requirements:
- cryptography >= 1.2.3 (older versions might work as well)
- cryptography >= 3.4
options:
size:
description:
@@ -32,9 +32,6 @@ options:
type:
description:
- The algorithm used to generate the TLS/SSL private key.
- Note that V(ECC), V(X25519), V(X448), V(Ed25519), and V(Ed448) require the C(cryptography) backend. V(X25519) needs
cryptography 2.5 or newer, while V(X448), V(Ed25519), and V(Ed448) require cryptography 2.6 or newer. For V(ECC),
the minimal cryptography version required depends on the O(curve) option.
type: str
default: RSA
choices: [DSA, ECC, Ed25519, Ed448, RSA, X25519, X448]
@@ -101,7 +98,6 @@ options:
parameters are as expected.
- If set to V(regenerate) (default), generates a new private key.
- If set to V(convert), the key will be converted to the new format instead.
- Only supported by the C(cryptography) backend.
type: str
default: regenerate
choices: [regenerate, convert]

View File

@@ -10,7 +10,7 @@ class ModuleDocFragment:
# Standard files documentation fragment
DOCUMENTATION = r"""
requirements:
- cryptography >= 1.2.3 (older versions might work as well)
- cryptography >= 3.4
attributes:
diff_mode:
support: none

View File

@@ -29,7 +29,6 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.utils import
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
CRYPTOGRAPHY_TIMEZONE,
cryptography_name_to_oid,
cryptography_serial_number_of_cert,
get_not_valid_after,
get_not_valid_before,
)
@@ -75,11 +74,6 @@ else:
HAS_CURRENT_CRYPTOGRAPHY = LooseVersion(CRYPTOGRAPHY_VERSION) >= LooseVersion(
CRYPTOGRAPHY_MINIMAL_VERSION
)
try:
if HAS_CURRENT_CRYPTOGRAPHY:
_cryptography_backend = cryptography.hazmat.backends.default_backend()
except Exception:
CRYPTOGRAPHY_ERROR = traceback.format_exc()
class CryptographyChainMatcher(ChainMatcher):
@@ -150,9 +144,7 @@ class CryptographyChainMatcher(ChainMatcher):
chain = chain[:1]
for cert in chain:
try:
x509 = cryptography.x509.load_pem_x509_certificate(
to_bytes(cert), cryptography.hazmat.backends.default_backend()
)
x509 = cryptography.x509.load_pem_x509_certificate(to_bytes(cert))
matches = True
if not self._match_subject(x509.subject, self.subject):
matches = False
@@ -204,7 +196,6 @@ class CryptographyBackend(CryptoBackend):
key = cryptography.hazmat.primitives.serialization.load_pem_private_key(
key_content,
password=to_bytes(passphrase) if passphrase is not None else None,
backend=_cryptography_backend,
)
except Exception as e:
raise KeyParsingError(f"error while loading key: {e}")
@@ -323,7 +314,7 @@ class CryptographyBackend(CryptoBackend):
)
return {
"mac_obj": lambda: cryptography.hazmat.primitives.hmac.HMAC(
key_bytes, hashalg(), _cryptography_backend
key_bytes, hashalg()
),
"type": "hmac",
"alg": alg,
@@ -346,7 +337,7 @@ class CryptographyBackend(CryptoBackend):
csr_content = read_file(csr_filename)
else:
csr_content = to_bytes(csr_content)
csr = cryptography.x509.load_pem_x509_csr(csr_content, _cryptography_backend)
csr = cryptography.x509.load_pem_x509_csr(csr_content)
identifiers = set()
result = []
@@ -410,9 +401,7 @@ class CryptographyBackend(CryptoBackend):
cert_content = to_bytes(extract_first_pem(to_text(cert_content)) or "")
try:
cert = cryptography.x509.load_pem_x509_certificate(
cert_content, _cryptography_backend
)
cert = cryptography.x509.load_pem_x509_certificate(cert_content)
except Exception as e:
if cert_filename is None:
raise BackendException(f"Cannot parse certificate: {e}")
@@ -443,9 +432,7 @@ class CryptographyBackend(CryptoBackend):
cert_content = to_bytes(extract_first_pem(to_text(cert_content)) or "")
try:
cert = cryptography.x509.load_pem_x509_certificate(
cert_content, _cryptography_backend
)
cert = cryptography.x509.load_pem_x509_certificate(cert_content)
except Exception as e:
if cert_filename is None:
raise BackendException(f"Cannot parse certificate: {e}")
@@ -472,7 +459,7 @@ class CryptographyBackend(CryptoBackend):
return CertificateInformation(
not_valid_after=get_not_valid_after(cert),
not_valid_before=get_not_valid_before(cert),
serial_number=cryptography_serial_number_of_cert(cert),
serial_number=cert.serial_number,
subject_key_identifier=ski,
authority_key_identifier=aki,
)

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)

View File

@@ -438,7 +438,7 @@ class KeypairBackendCryptography(KeypairBackend):
if result == "SSH" and not HAS_OPENSSH_PRIVATE_FORMAT:
self.module.fail_json(
msg=missing_required_lib(
"cryptography >= 3.0",
"cryptography >= 3.4",
reason="to load/dump private keys in the default OpenSSH format for OpenSSH >= 7.8 "
+ "or for ed25519 keys",
)
@@ -549,7 +549,7 @@ def select_backend(module, backend):
else:
module.fail_json(
msg="Cannot find either the OpenSSH binary in the PATH "
+ "or cryptography >= 2.6 installed on this system"
+ "or cryptography >= 3.4 installed on this system"
)
if backend == "opensshbin":
@@ -558,7 +558,7 @@ def select_backend(module, backend):
return backend, KeypairBackendOpensshBin(module)
elif backend == "cryptography":
if not can_use_cryptography:
module.fail_json(msg=missing_required_lib("cryptography >= 2.6"))
module.fail_json(msg=missing_required_lib("cryptography >= 3.4"))
return backend, KeypairBackendCryptography(module)
else:
raise ValueError(f"Unsupported value for backend: {backend}")

View File

@@ -25,7 +25,7 @@ try:
Ed25519PublicKey,
)
if LooseVersion(CRYPTOGRAPHY_VERSION) >= LooseVersion("3.0"):
if LooseVersion(CRYPTOGRAPHY_VERSION) >= LooseVersion("3.4"):
HAS_OPENSSH_PRIVATE_FORMAT = True
else:
HAS_OPENSSH_PRIVATE_FORMAT = False

View File

@@ -22,7 +22,7 @@ seealso:
description: The specification of the C(tls-alpn-01) challenge (RFC 8737).
link: https://www.rfc-editor.org/rfc/rfc8737.html
requirements:
- "cryptography >= 1.3"
- "cryptography >= 3.4"
extends_documentation_fragment:
- community.crypto.attributes
attributes:
@@ -184,8 +184,7 @@ try:
import cryptography.x509
import cryptography.x509.oid
HAS_CRYPTOGRAPHY = LooseVersion(cryptography.__version__) >= LooseVersion("1.3")
_cryptography_backend = cryptography.hazmat.backends.default_backend()
HAS_CRYPTOGRAPHY = LooseVersion(cryptography.__version__) >= LooseVersion("3.4")
except ImportError:
CRYPTOGRAPHY_IMP_ERR = traceback.format_exc()
HAS_CRYPTOGRAPHY = False
@@ -216,10 +215,10 @@ def main():
# Some callbacks die when exception is provided with value None
if CRYPTOGRAPHY_IMP_ERR:
module.fail_json(
msg=missing_required_lib("cryptography >= 1.3"),
msg=missing_required_lib("cryptography >= 3.4"),
exception=CRYPTOGRAPHY_IMP_ERR,
)
module.fail_json(msg=missing_required_lib("cryptography >= 1.3"))
module.fail_json(msg=missing_required_lib("cryptography >= 3.4"))
try:
# Get parameters
@@ -242,7 +241,6 @@ def main():
if private_key_passphrase is not None
else None
),
backend=_cryptography_backend,
)
)
except Exception as e:
@@ -283,7 +281,6 @@ def main():
regular_certificate = cert_builder.sign(
private_key,
cryptography.hazmat.primitives.hashes.SHA256(),
_cryptography_backend,
)
# Process challenge
@@ -312,7 +309,6 @@ def main():
challenge_certificate = cert_builder.sign(
private_key,
cryptography.hazmat.primitives.hashes.SHA256(),
_cryptography_backend,
)
module.exit_json(

View File

@@ -18,7 +18,7 @@ description:
that the signature is correct. It ignores validity dates and key usage completely. If you need to verify that a generated
chain is valid, please use C(openssl verify ...).
requirements:
- "cryptography >= 1.5"
- "cryptography >= 3.4"
extends_documentation_fragment:
- community.crypto.attributes
- community.crypto.attributes.idempotent_not_modify_state
@@ -126,10 +126,6 @@ import traceback
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.common.text.converters import to_bytes
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
CRYPTOGRAPHY_HAS_ED448_SIGN,
CRYPTOGRAPHY_HAS_ED25519_SIGN,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.pem import (
split_pem_list,
)
@@ -152,8 +148,7 @@ try:
import cryptography.x509
import cryptography.x509.oid
HAS_CRYPTOGRAPHY = LooseVersion(cryptography.__version__) >= LooseVersion("1.5")
_cryptography_backend = cryptography.hazmat.backends.default_backend()
HAS_CRYPTOGRAPHY = LooseVersion(cryptography.__version__) >= LooseVersion("3.4")
except ImportError:
CRYPTOGRAPHY_IMP_ERR = traceback.format_exc()
HAS_CRYPTOGRAPHY = False
@@ -201,12 +196,12 @@ def is_parent(module, cert, potential_parent):
cert.cert.signature_hash_algorithm
),
)
elif CRYPTOGRAPHY_HAS_ED25519_SIGN and isinstance(
elif isinstance(
public_key,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
):
public_key.verify(cert.cert.signature, cert.cert.tbs_certificate_bytes)
elif CRYPTOGRAPHY_HAS_ED448_SIGN and isinstance(
elif isinstance(
public_key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey
):
public_key.verify(cert.cert.signature, cert.cert.tbs_certificate_bytes)
@@ -232,9 +227,7 @@ def parse_PEM_list(module, text, source, fail_on_error=True):
for cert_pem in split_pem_list(text):
# Try to load PEM certificate
try:
cert = cryptography.x509.load_pem_x509_certificate(
to_bytes(cert_pem), _cryptography_backend
)
cert = cryptography.x509.load_pem_x509_certificate(to_bytes(cert_pem))
result.append(Certificate(cert_pem, cert))
except Exception as e:
msg = f"Cannot parse certificate #{len(result) + 1} from {source}: {e}"
@@ -338,7 +331,7 @@ def main():
if not HAS_CRYPTOGRAPHY:
module.fail_json(
msg=missing_required_lib("cryptography >= 1.5"),
msg=missing_required_lib("cryptography >= 3.4"),
exception=CRYPTOGRAPHY_IMP_ERR,
)

View File

@@ -154,22 +154,6 @@ openssl:
import traceback
from ansible.module_utils.basic import AnsibleModule
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
CRYPTOGRAPHY_HAS_DSA,
CRYPTOGRAPHY_HAS_DSA_SIGN,
CRYPTOGRAPHY_HAS_EC,
CRYPTOGRAPHY_HAS_EC_SIGN,
CRYPTOGRAPHY_HAS_ED448,
CRYPTOGRAPHY_HAS_ED448_SIGN,
CRYPTOGRAPHY_HAS_ED25519,
CRYPTOGRAPHY_HAS_ED25519_SIGN,
CRYPTOGRAPHY_HAS_RSA,
CRYPTOGRAPHY_HAS_RSA_SIGN,
CRYPTOGRAPHY_HAS_X448,
CRYPTOGRAPHY_HAS_X25519,
CRYPTOGRAPHY_HAS_X25519_FULL,
HAS_CRYPTOGRAPHY,
)
try:
@@ -185,9 +169,11 @@ try:
except ImportError:
UnsupportedAlgorithm = Exception
CryptographyInternalError = Exception
HAS_CRYPTOGRAPHY = False
CRYPTOGRAPHY_VERSION = None
CRYPTOGRAPHY_IMP_ERR = traceback.format_exc()
else:
HAS_CRYPTOGRAPHY = True
CRYPTOGRAPHY_VERSION = cryptography.__version__
CRYPTOGRAPHY_IMP_ERR = None
@@ -222,64 +208,153 @@ def add_crypto_information(module):
result["python_cryptography_import_error"] = CRYPTOGRAPHY_IMP_ERR
return result
has_ed25519 = CRYPTOGRAPHY_HAS_ED25519
if has_ed25519:
try:
from cryptography.hazmat.primitives.asymmetric.ed25519 import (
Ed25519PrivateKey,
)
# Test for DSA
has_dsa = False
has_dsa_sign = False
try:
# added in 0.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/dsa/
import cryptography.hazmat.primitives.asymmetric.dsa
has_dsa = True
try:
# added later in 1.5
cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey.sign
has_dsa_sign = True
except AttributeError:
pass
except ImportError:
pass
# Test for RSA
has_rsa = False
has_rsa_sign = False
try:
# added in 0.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/
import cryptography.hazmat.primitives.asymmetric.rsa
has_rsa = True
try:
# added later in 1.4
cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey.sign
has_rsa_sign = True
except AttributeError:
pass
except ImportError:
pass
# Test for Ed25519
has_ed25519 = False
has_ed25519_sign = False
try:
# added in 2.6 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ed25519/
import cryptography.hazmat.primitives.asymmetric.ed25519
from cryptography.hazmat.primitives.asymmetric.ed25519 import (
Ed25519PrivateKey,
)
try:
Ed25519PrivateKey.from_private_bytes(b"")
except ValueError:
pass
except UnsupportedAlgorithm:
has_ed25519 = False
has_ed448 = CRYPTOGRAPHY_HAS_ED448
if has_ed448:
has_ed25519 = True
try:
from cryptography.hazmat.primitives.asymmetric.ed448 import Ed448PrivateKey
# added with the primitive in 2.6
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.sign
has_ed25519_sign = True
except AttributeError:
pass
except (ImportError, UnsupportedAlgorithm):
pass
# Test for Ed448
has_ed448 = False
has_ed448_sign = False
try:
# added in 2.6 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ed448/
import cryptography.hazmat.primitives.asymmetric.ed448
from cryptography.hazmat.primitives.asymmetric.ed448 import Ed448PrivateKey
try:
Ed448PrivateKey.from_private_bytes(b"")
except ValueError:
pass
except UnsupportedAlgorithm:
has_ed448 = False
has_x25519 = CRYPTOGRAPHY_HAS_X25519
if has_x25519:
has_ed448 = True
try:
from cryptography.hazmat.primitives.asymmetric.x25519 import (
X25519PrivateKey,
)
# added with the primitive in 2.6
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey.sign
has_ed448_sign = True
except AttributeError:
pass
except (ImportError, UnsupportedAlgorithm):
pass
if CRYPTOGRAPHY_HAS_X25519_FULL:
X25519PrivateKey.from_private_bytes(b"")
# Test for X25519
has_x25519 = False
has_x25519_full = False
try:
# added in 2.0 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/x25519/
import cryptography.hazmat.primitives.asymmetric.x25519
try:
# added later in 2.5
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.private_bytes
full = True
except AttributeError:
full = False
try:
if full:
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
b""
)
else:
# Some versions do not support serialization and deserialization - use generate() instead
X25519PrivateKey.generate()
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.generate()
except ValueError:
pass
except UnsupportedAlgorithm:
has_x25519 = False
has_x448 = CRYPTOGRAPHY_HAS_X448
if has_x448:
has_x25519 = True
has_x25519_full = full
except (ImportError, UnsupportedAlgorithm):
pass
# Test for X448
has_x448 = False
try:
# added in 2.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/x448/
import cryptography.hazmat.primitives.asymmetric.x448
try:
from cryptography.hazmat.primitives.asymmetric.x448 import X448PrivateKey
X448PrivateKey.from_private_bytes(b"")
except ValueError:
pass
except UnsupportedAlgorithm:
has_x448 = False
has_x448 = True
except (ImportError, UnsupportedAlgorithm):
pass
# Test for ECC
has_ec = False
has_ec_sign = False
curves = []
if CRYPTOGRAPHY_HAS_EC:
import cryptography.hazmat.backends
try:
# added in 0.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/
import cryptography.hazmat.primitives.asymmetric.ec
backend = cryptography.hazmat.backends.default_backend()
has_ec = True
try:
# added later in 1.5
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey.sign
has_ec_sign = True
except AttributeError:
pass
except ImportError:
pass
else:
for curve_name, constructor_name in CURVES:
ecclass = cryptography.hazmat.primitives.asymmetric.ec.__dict__.get(
constructor_name
@@ -287,7 +362,7 @@ def add_crypto_information(module):
if ecclass:
try:
cryptography.hazmat.primitives.asymmetric.ec.generate_private_key(
curve=ecclass(), backend=backend
curve=ecclass()
)
curves.append(curve_name)
except UnsupportedAlgorithm:
@@ -300,21 +375,22 @@ def add_crypto_information(module):
# curves removed.
pass
# Compose result
info = {
"version": CRYPTOGRAPHY_VERSION,
"curves": curves,
"has_ec": CRYPTOGRAPHY_HAS_EC,
"has_ec_sign": CRYPTOGRAPHY_HAS_EC_SIGN,
"has_ec": has_ec,
"has_ec_sign": has_ec_sign,
"has_ed25519": has_ed25519,
"has_ed25519_sign": has_ed25519 and CRYPTOGRAPHY_HAS_ED25519_SIGN,
"has_ed25519_sign": has_ed25519_sign,
"has_ed448": has_ed448,
"has_ed448_sign": has_ed448 and CRYPTOGRAPHY_HAS_ED448_SIGN,
"has_dsa": CRYPTOGRAPHY_HAS_DSA,
"has_dsa_sign": CRYPTOGRAPHY_HAS_DSA_SIGN,
"has_rsa": CRYPTOGRAPHY_HAS_RSA,
"has_rsa_sign": CRYPTOGRAPHY_HAS_RSA_SIGN,
"has_ed448_sign": has_ed448_sign,
"has_dsa": has_dsa,
"has_dsa_sign": has_dsa_sign,
"has_rsa": has_rsa,
"has_rsa_sign": has_rsa_sign,
"has_x25519": has_x25519,
"has_x25519_serialization": has_x25519 and CRYPTOGRAPHY_HAS_X25519_FULL,
"has_x25519_serialization": has_x25519 and has_x25519_full,
"has_x448": has_x448,
}
result["python_cryptography_capabilities"] = info

View File

@@ -20,7 +20,7 @@ description:
notes:
- O(path) must be specified as the output location of the certificate.
requirements:
- cryptography >= 1.6
- cryptography >= 3.4
extends_documentation_fragment:
- community.crypto.attributes
- community.crypto.attributes.files
@@ -581,7 +581,7 @@ except ImportError:
else:
CRYPTOGRAPHY_FOUND = True
MINIMAL_CRYPTOGRAPHY_VERSION = "1.6"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
def validate_cert_expiry(cert_expiry):

View File

@@ -121,7 +121,7 @@ notes:
- When using ca_cert on OS X it has been reported that in some conditions the validate will always succeed.
requirements:
- "Python >= 3.10 when O(get_certificate_chain=true)"
- "cryptography >= 1.6"
- "cryptography >= 3.4"
seealso:
- plugin: community.crypto.to_serial
@@ -292,14 +292,13 @@ 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:
import cryptography
import cryptography.exceptions
import cryptography.x509
from cryptography.hazmat.backends import default_backend as cryptography_backend
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
except ImportError:
@@ -528,9 +527,7 @@ def main():
result["cert"] = cert
if backend == "cryptography":
x509 = cryptography.x509.load_pem_x509_certificate(
to_bytes(cert), cryptography_backend()
)
x509 = cryptography.x509.load_pem_x509_certificate(to_bytes(cert))
result["subject"] = {}
for attribute in x509.subject:
result["subject"][cryptography_oid_to_name(attribute.oid, short=True)] = (

View File

@@ -15,8 +15,7 @@ description:
V(rsa), V(dsa), V(rsa1), V(ed25519) or V(ecdsa) private keys.
requirements:
- ssh-keygen (if O(backend=openssh))
- cryptography >= 2.6 (if O(backend=cryptography) and OpenSSH < 7.8 is installed)
- cryptography >= 3.0 (if O(backend=cryptography) and OpenSSH >= 7.8 is installed)
- cryptography >= 3.4 (if O(backend=cryptography))
extends_documentation_fragment:
- ansible.builtin.files
- community.crypto.attributes

View File

@@ -15,7 +15,7 @@ description:
- In case the CSR signature cannot be validated, the module will fail. In this case, all return variables are still returned.
- It uses the cryptography python library to interact with OpenSSL.
requirements:
- cryptography >= 1.3
- cryptography >= 3.4
author:
- Felix Fontein (@felixfontein)
- Yanis Guenane (@Spredzy)

View File

@@ -17,7 +17,7 @@ description:
- The module can use the cryptography Python library, or the C(openssl) executable. By default, it tries to detect which
one is available. This can be overridden with the O(select_crypto_backend) option.
requirements:
- Either cryptography >= 2.0
- Either cryptography >= 3.4
- Or OpenSSL binary C(openssl)
author:
- Thom Wiggers (@thomwiggers)
@@ -148,7 +148,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
)
MINIMAL_CRYPTOGRAPHY_VERSION = "2.0"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
try:
@@ -322,7 +322,6 @@ class DHParameterCryptography(DHParameterBase):
def __init__(self, module):
super(DHParameterCryptography, self).__init__(module)
self.crypto_backend = cryptography.hazmat.backends.default_backend()
def _do_generate(self, module):
"""Actually generate the DH params."""
@@ -330,7 +329,6 @@ class DHParameterCryptography(DHParameterBase):
params = cryptography.hazmat.primitives.asymmetric.dh.generate_parameters(
generator=2,
key_size=self.size,
backend=self.crypto_backend,
)
# Serialize parameters
result = params.parameter_bytes(
@@ -349,7 +347,7 @@ class DHParameterCryptography(DHParameterBase):
with open(self.path, "rb") as f:
data = f.read()
params = cryptography.hazmat.primitives.serialization.load_pem_parameters(
data, backend=self.crypto_backend
data
)
except Exception:
return False

View File

@@ -15,7 +15,7 @@ description:
- This module allows one to (re-)generate PKCS#12.
- The module uses the cryptography Python library.
requirements:
- cryptography >= 3.0
- cryptography >= 3.4
extends_documentation_fragment:
- ansible.builtin.files
- community.crypto.attributes
@@ -305,7 +305,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
)
MINIMAL_CRYPTOGRAPHY_VERSION = "3.0"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
try:

View File

@@ -17,7 +17,7 @@ description:
V(none) is returned for RV(key_is_consistent).
- It uses the cryptography python library to interact with OpenSSL.
requirements:
- cryptography >= 1.2.3
- cryptography >= 3.4
author:
- Felix Fontein (@felixfontein)
- Yanis Guenane (@Spredzy)

View File

@@ -15,8 +15,7 @@ description:
not supported), use the M(community.crypto.openssh_keypair) module to manage these.
- The module uses the cryptography Python library.
requirements:
- cryptography >= 1.2.3 (older versions might work as well)
- Needs cryptography >= 1.4 if O(format) is C(OpenSSH)
- cryptography >= 3.4
author:
- Yanis Guenane (@Spredzy)
- Felix Fontein (@felixfontein)
@@ -211,13 +210,11 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
)
MINIMAL_CRYPTOGRAPHY_VERSION = "1.2.3"
MINIMAL_CRYPTOGRAPHY_VERSION_OPENSSH = "1.4"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
try:
import cryptography
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization as crypto_serialization
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
@@ -354,7 +351,7 @@ class PublicKey(OpenSSLObject):
if self.format == "OpenSSH":
# Read and dump public key. Makes sure that the comment is stripped off.
current_publickey = crypto_serialization.load_ssh_public_key(
publickey_content, backend=default_backend()
publickey_content
)
publickey_content = current_publickey.public_bytes(
crypto_serialization.Encoding.OpenSSH,
@@ -362,7 +359,7 @@ class PublicKey(OpenSSLObject):
)
else:
current_publickey = crypto_serialization.load_pem_public_key(
publickey_content, backend=default_backend()
publickey_content
)
publickey_content = current_publickey.public_bytes(
crypto_serialization.Encoding.PEM,
@@ -442,16 +439,12 @@ def main():
mutually_exclusive=(["privatekey_path", "privatekey_content"],),
)
minimal_cryptography_version = MINIMAL_CRYPTOGRAPHY_VERSION
if module.params["format"] == "OpenSSH":
minimal_cryptography_version = MINIMAL_CRYPTOGRAPHY_VERSION_OPENSSH
backend = module.params["select_crypto_backend"]
if backend == "auto":
# Detection what is possible
can_use_cryptography = (
CRYPTOGRAPHY_FOUND
and CRYPTOGRAPHY_VERSION >= LooseVersion(minimal_cryptography_version)
and CRYPTOGRAPHY_VERSION >= LooseVersion(MINIMAL_CRYPTOGRAPHY_VERSION)
)
# Decision
@@ -461,7 +454,7 @@ def main():
# Success?
if backend == "auto":
module.fail_json(
msg=f"Cannot detect the required Python library cryptography (>= {minimal_cryptography_version})",
msg=f"Cannot detect the required Python library cryptography (>= {MINIMAL_CRYPTOGRAPHY_VERSION})",
)
if module.params["format"] == "OpenSSH" and backend != "cryptography":
@@ -471,7 +464,7 @@ def main():
if not CRYPTOGRAPHY_FOUND:
module.fail_json(
msg=missing_required_lib(
f"cryptography >= {minimal_cryptography_version}"
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
),
exception=CRYPTOGRAPHY_IMP_ERR,
)

View File

@@ -14,7 +14,7 @@ description:
- It uses the cryptography python library to interact with OpenSSL.
version_added: 1.7.0
requirements:
- cryptography >= 1.2.3
- cryptography >= 3.4
author:
- Felix Fontein (@felixfontein)
extends_documentation_fragment:

View File

@@ -14,7 +14,7 @@ description:
- This module allows one to sign data using a private key.
- The module uses the cryptography Python library.
requirements:
- cryptography >= 1.4 (some key types require newer versions)
- cryptography >= 3.4
author:
- Patrick Pichler (@aveexy)
- Markus Teufelberger (@MarkusTeufelberger)
@@ -62,10 +62,6 @@ options:
type: str
default: auto
choices: [auto, cryptography]
notes:
- "When using the C(cryptography) backend, the following key types require at least the following C(cryptography) version:\n
RSA keys: C(cryptography) >= 1.4\nDSA and ECDSA keys: C(cryptography) >= 1.5\ned448 and ed25519 keys: C(cryptography)
>= 2.6."
seealso:
- module: community.crypto.openssl_signature_info
- module: community.crypto.openssl_privatekey
@@ -108,7 +104,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
)
MINIMAL_CRYPTOGRAPHY_VERSION = "1.4"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
try:
@@ -126,11 +122,6 @@ else:
from ansible.module_utils.basic import AnsibleModule, 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_DSA_SIGN,
CRYPTOGRAPHY_HAS_EC_SIGN,
CRYPTOGRAPHY_HAS_ED448_SIGN,
CRYPTOGRAPHY_HAS_ED25519_SIGN,
CRYPTOGRAPHY_HAS_RSA_SIGN,
OpenSSLObjectError,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
@@ -191,42 +182,37 @@ class SignatureCryptography(SignatureBase):
signature = None
if CRYPTOGRAPHY_HAS_DSA_SIGN:
if isinstance(
private_key,
cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey,
):
signature = private_key.sign(_in, _hash)
if isinstance(
private_key,
cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey,
):
signature = private_key.sign(_in, _hash)
if CRYPTOGRAPHY_HAS_EC_SIGN:
if isinstance(
private_key,
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey,
):
signature = private_key.sign(
_in, cryptography.hazmat.primitives.asymmetric.ec.ECDSA(_hash)
)
elif isinstance(
private_key,
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey,
):
signature = private_key.sign(
_in, cryptography.hazmat.primitives.asymmetric.ec.ECDSA(_hash)
)
if CRYPTOGRAPHY_HAS_ED25519_SIGN:
if isinstance(
private_key,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey,
):
signature = private_key.sign(_in)
elif isinstance(
private_key,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey,
):
signature = private_key.sign(_in)
if CRYPTOGRAPHY_HAS_ED448_SIGN:
if isinstance(
private_key,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey,
):
signature = private_key.sign(_in)
elif isinstance(
private_key,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey,
):
signature = private_key.sign(_in)
if CRYPTOGRAPHY_HAS_RSA_SIGN:
if isinstance(
private_key,
cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey,
):
signature = private_key.sign(_in, _padding, _hash)
elif isinstance(
private_key,
cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey,
):
signature = private_key.sign(_in, _padding, _hash)
if signature is None:
self.module.fail_json(

View File

@@ -14,7 +14,7 @@ description:
- This module allows one to verify a signature for a file by a certificate.
- The module uses the cryptography Python library.
requirements:
- cryptography >= 1.4 (some key types require newer versions)
- cryptography >= 3.4
author:
- Patrick Pichler (@aveexy)
- Markus Teufelberger (@MarkusTeufelberger)
@@ -51,10 +51,6 @@ options:
type: str
default: auto
choices: [auto, cryptography]
notes:
- "When using the C(cryptography) backend, the following key types require at least the following C(cryptography) version:\n
RSA keys: C(cryptography) >= 1.4\nDSA and ECDSA keys: C(cryptography) >= 1.5\ned448 and ed25519 keys: C(cryptography)
>= 2.6."
seealso:
- module: community.crypto.openssl_signature
- module: community.crypto.x509_certificate
@@ -97,7 +93,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
)
MINIMAL_CRYPTOGRAPHY_VERSION = "1.4"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
try:
@@ -115,11 +111,6 @@ else:
from ansible.module_utils.basic import AnsibleModule, 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_DSA_SIGN,
CRYPTOGRAPHY_HAS_EC_SIGN,
CRYPTOGRAPHY_HAS_ED448_SIGN,
CRYPTOGRAPHY_HAS_ED25519_SIGN,
CRYPTOGRAPHY_HAS_RSA_SIGN,
OpenSSLObjectError,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
@@ -181,74 +172,53 @@ class SignatureInfoCryptography(SignatureInfoBase):
verified = False
valid = False
if CRYPTOGRAPHY_HAS_DSA_SIGN:
try:
if isinstance(
public_key,
cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey,
):
public_key.verify(_signature, _in, _hash)
verified = True
valid = True
except cryptography.exceptions.InvalidSignature:
try:
if isinstance(
public_key,
cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey,
):
public_key.verify(_signature, _in, _hash)
verified = True
valid = False
valid = True
if CRYPTOGRAPHY_HAS_EC_SIGN:
try:
if isinstance(
public_key,
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey,
):
public_key.verify(
_signature,
_in,
cryptography.hazmat.primitives.asymmetric.ec.ECDSA(_hash),
)
verified = True
valid = True
except cryptography.exceptions.InvalidSignature:
elif isinstance(
public_key,
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey,
):
public_key.verify(
_signature,
_in,
cryptography.hazmat.primitives.asymmetric.ec.ECDSA(_hash),
)
verified = True
valid = False
valid = True
if CRYPTOGRAPHY_HAS_ED25519_SIGN:
try:
if isinstance(
public_key,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
):
public_key.verify(_signature, _in)
verified = True
valid = True
except cryptography.exceptions.InvalidSignature:
elif isinstance(
public_key,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
):
public_key.verify(_signature, _in)
verified = True
valid = False
valid = True
if CRYPTOGRAPHY_HAS_ED448_SIGN:
try:
if isinstance(
public_key,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey,
):
public_key.verify(_signature, _in)
verified = True
valid = True
except cryptography.exceptions.InvalidSignature:
elif isinstance(
public_key,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey,
):
public_key.verify(_signature, _in)
verified = True
valid = False
valid = True
if CRYPTOGRAPHY_HAS_RSA_SIGN:
try:
if isinstance(
public_key,
cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey,
):
public_key.verify(_signature, _in, _padding, _hash)
verified = True
valid = True
except cryptography.exceptions.InvalidSignature:
elif isinstance(
public_key,
cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey,
):
public_key.verify(_signature, _in, _padding, _hash)
verified = True
valid = False
valid = True
except cryptography.exceptions.InvalidSignature:
verified = True
valid = False
if not verified:
self.module.fail_json(

View File

@@ -85,8 +85,6 @@ seealso:
- module: community.crypto.x509_certificate
- module: community.crypto.x509_certificate_pipe
- module: community.crypto.x509_certificate_info
requirements:
- cryptography >= 1.6 if O(verify_cert_parsable=true)
"""
EXAMPLES = r"""
@@ -132,12 +130,11 @@ from ansible_collections.community.crypto.plugins.module_utils.io import (
)
MINIMAL_CRYPTOGRAPHY_VERSION = "1.6"
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None
try:
import cryptography # noqa: F401, pylint: disable=unused-import
from cryptography.hazmat.backends import default_backend
from cryptography.x509 import load_der_x509_certificate
except ImportError:
CRYPTOGRAPHY_IMP_ERR = traceback.format_exc()
@@ -234,7 +231,7 @@ class X509CertificateConvertModule(OpenSSLObject):
exception=CRYPTOGRAPHY_IMP_ERR,
)
try:
load_der_x509_certificate(self.input, default_backend())
load_der_x509_certificate(self.input)
except Exception as exc:
module.fail_json(msg=f"Error while parsing certificate: {exc}")

View File

@@ -20,7 +20,7 @@ description:
L(collections,https://docs.ansible.com/ansible/latest/user_guide/collections_using.html#using-collections-in-a-playbook)
keyword, the new name M(community.crypto.x509_certificate_info) should be used to avoid a deprecation warning.
requirements:
- cryptography >= 1.6
- cryptography >= 3.4
author:
- Felix Fontein (@felixfontein)
- Yanis Guenane (@Spredzy)

View File

@@ -15,7 +15,7 @@ description:
- Certificates on the revocation list can be either specified by serial number and (optionally) their issuer, or as a path
to a certificate file in PEM format.
requirements:
- cryptography >= 1.2
- cryptography >= 3.4
author:
- Felix Fontein (@felixfontein)
extends_documentation_fragment:
@@ -455,7 +455,6 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptograp
cryptography_key_needs_digest_for_signing,
cryptography_name_to_oid,
cryptography_oid_to_name,
cryptography_serial_number_of_cert,
)
from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.crl_info import (
get_crl_info,
@@ -483,13 +482,12 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
)
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
from cryptography.hazmat.primitives.serialization import Encoding
from cryptography.x509 import (
CertificateRevocationListBuilder,
@@ -585,7 +583,7 @@ class CRL(OpenSSLObject):
cert = load_certificate(
rc["path"], content=rc["content"], backend="cryptography"
)
result["serial_number"] = cryptography_serial_number_of_cert(cert)
result["serial_number"] = cert.serial_number
except OpenSSLObjectError as e:
if rc["content"] is not None:
module.fail_json(
@@ -642,11 +640,11 @@ class CRL(OpenSSLObject):
data = f.read()
self.actual_format = "pem" if identify_pem_format(data) else "der"
if self.actual_format == "pem":
self.crl = x509.load_pem_x509_crl(data, default_backend())
self.crl = x509.load_pem_x509_crl(data)
if self.return_content:
self.crl_content = data
else:
self.crl = x509.load_der_x509_crl(data, default_backend())
self.crl = x509.load_der_x509_crl(data)
if self.return_content:
self.crl_content = base64.b64encode(data)
except Exception:
@@ -783,7 +781,6 @@ class CRL(OpenSSLObject):
return True
def _generate_crl(self):
backend = default_backend()
crl = CertificateRevocationListBuilder()
try:
@@ -830,12 +827,12 @@ class CRL(OpenSSLObject):
x509.InvalidityDate(entry["invalidity_date"]),
entry["invalidity_date_critical"],
)
crl = crl.add_revoked_certificate(revoked_cert.build(backend))
crl = crl.add_revoked_certificate(revoked_cert.build())
digest = None
if cryptography_key_needs_digest_for_signing(self.privatekey):
digest = self.digest
self.crl = crl.sign(self.privatekey, digest, backend=backend)
self.crl = crl.sign(self.privatekey, digest)
if self.format == "pem":
return self.crl.public_bytes(Encoding.PEM)
else:

View File

@@ -13,7 +13,7 @@ short_description: Retrieve information on Certificate Revocation Lists (CRLs)
description:
- This module allows one to retrieve information on Certificate Revocation Lists (CRLs).
requirements:
- cryptography >= 1.2
- cryptography >= 3.4
author:
- Felix Fontein (@felixfontein)
extends_documentation_fragment: