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

@@ -145,8 +145,6 @@ stages:
parameters: parameters:
testFormat: devel/linux-community/{0} testFormat: devel/linux-community/{0}
targets: targets:
- name: Debian Bullseye
test: debian-bullseye/3.9
- name: Debian Bookworm - name: Debian Bookworm
test: debian-bookworm/3.11 test: debian-bookworm/3.11
- name: ArchLinux - name: ArchLinux

View File

@@ -45,7 +45,7 @@ Tested with the current ansible-core-2.17, ansible-core 2.18, and ansible-core 2
The exact requirements for every module are listed in the module documentation. The exact requirements for every module are listed in the module documentation.
Most modules require a recent enough version of [the Python cryptography library](https://pypi.org/project/cryptography/). See the module documentations for the minimal version supported for each module. Most modules require a recent enough version of [the Python cryptography library](https://pypi.org/project/cryptography/); the minimum supported version by this collection is 3.4. See the module documentations for the minimal version supported for each module.
## Collection Documentation ## Collection Documentation

View File

@@ -0,0 +1,8 @@
minor_changes:
- "No longer provide cryptography's ``backend`` parameter. This will break with cryptography < 3.1 (https://github.com/ansible-collections/community.crypto/pull/878)."
- "Remove various compatibility code for cryptography < 3.4 (https://github.com/ansible-collections/community.crypto/pull/878)."
- "On cryptography 36.0.0+, always use ``public_bytes()`` for X.509 extension objects instead of using cryptography internals to obtain DER value of extension (https://github.com/ansible-collections/community.crypto/pull/878)."
removed_features:
- "crypto.basic module utils - remove ``CRYPTOGRAPHY_HAS_*`` flags. All tested features are supported since cryptography 3.0 (https://github.com/ansible-collections/community.crypto/pull/878)."
- "crypto.cryptography_support module utils - remove ``cryptography_serial_number_of_cert()`` helper function (https://github.com/ansible-collections/community.crypto/pull/878)."
- "The collection no longer supports cryptography < 3.4 (https://github.com/ansible-collections/community.crypto/pull/878)."

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) 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. to help us supporting it. Feedback that an ACME server not mentioned does work is also appreciated.
requirements: requirements:
- either openssl or L(cryptography,https://cryptography.io/) >= 1.5 - either openssl or L(cryptography,https://cryptography.io/) >= 3.4
options: options:
acme_version: acme_version:
description: description:

View File

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

View File

@@ -18,7 +18,7 @@ attributes:
idempotent: idempotent:
support: full support: full
requirements: requirements:
- cryptography >= 1.3 - cryptography >= 3.4
options: options:
digest: digest:
description: description:
@@ -237,7 +237,6 @@ options:
- Create the Subject Key Identifier from the public key. - 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 - 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. 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 type: bool
default: false default: false
subject_key_identifier: 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 - 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. 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 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 type: str
authority_key_identifier: authority_key_identifier:
description: 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).' - '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 - 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. 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) - 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. and O(authority_cert_serial_number) is specified.
type: str type: str
@@ -268,7 +265,6 @@ options:
- If specified, O(authority_cert_serial_number) must also be specified. - 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 - 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. 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) - 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. and O(authority_cert_serial_number) is specified.
type: list type: list
@@ -277,7 +273,6 @@ options:
description: description:
- The authority cert serial number. - The authority cert serial number.
- If specified, O(authority_cert_issuer) must also be specified. - 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 - 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. 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) - 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: crl_distribution_points:
description: description:
- Allows to specify one or multiple CRL distribution points. - Allows to specify one or multiple CRL distribution points.
- Only supported by the C(cryptography) backend.
type: list type: list
elements: dict elements: dict
suboptions: suboptions:
@@ -304,7 +298,6 @@ options:
- Describes how the CRL can be retrieved relative to the CRL issuer. - Describes how the CRL can be retrieved relative to the CRL issuer.
- Mutually exclusive with O(crl_distribution_points[].full_name). - Mutually exclusive with O(crl_distribution_points[].full_name).
- 'Example: V(/CN=example.com).' - 'Example: V(/CN=example.com).'
- Can only be used when cryptography >= 1.6 is installed.
type: list type: list
elements: str elements: str
crl_issuer: crl_issuer:

View File

@@ -22,7 +22,7 @@ attributes:
details: details:
- The option O(regenerate=always) generally disables idempotency. - The option O(regenerate=always) generally disables idempotency.
requirements: requirements:
- cryptography >= 1.2.3 (older versions might work as well) - cryptography >= 3.4
options: options:
size: size:
description: description:
@@ -32,9 +32,6 @@ options:
type: type:
description: description:
- The algorithm used to generate the TLS/SSL private key. - 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 type: str
default: RSA default: RSA
choices: [DSA, ECC, Ed25519, Ed448, RSA, X25519, X448] choices: [DSA, ECC, Ed25519, Ed448, RSA, X25519, X448]
@@ -101,7 +98,6 @@ options:
parameters are as expected. parameters are as expected.
- If set to V(regenerate) (default), generates a new private key. - 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. - If set to V(convert), the key will be converted to the new format instead.
- Only supported by the C(cryptography) backend.
type: str type: str
default: regenerate default: regenerate
choices: [regenerate, convert] choices: [regenerate, convert]

View File

@@ -10,7 +10,7 @@ class ModuleDocFragment:
# Standard files documentation fragment # Standard files documentation fragment
DOCUMENTATION = r""" DOCUMENTATION = r"""
requirements: requirements:
- cryptography >= 1.2.3 (older versions might work as well) - cryptography >= 3.4
attributes: attributes:
diff_mode: diff_mode:
support: none 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 ( from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
CRYPTOGRAPHY_TIMEZONE, CRYPTOGRAPHY_TIMEZONE,
cryptography_name_to_oid, cryptography_name_to_oid,
cryptography_serial_number_of_cert,
get_not_valid_after, get_not_valid_after,
get_not_valid_before, get_not_valid_before,
) )
@@ -75,11 +74,6 @@ else:
HAS_CURRENT_CRYPTOGRAPHY = LooseVersion(CRYPTOGRAPHY_VERSION) >= LooseVersion( HAS_CURRENT_CRYPTOGRAPHY = LooseVersion(CRYPTOGRAPHY_VERSION) >= LooseVersion(
CRYPTOGRAPHY_MINIMAL_VERSION 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): class CryptographyChainMatcher(ChainMatcher):
@@ -150,9 +144,7 @@ class CryptographyChainMatcher(ChainMatcher):
chain = chain[:1] chain = chain[:1]
for cert in chain: for cert in chain:
try: try:
x509 = cryptography.x509.load_pem_x509_certificate( x509 = cryptography.x509.load_pem_x509_certificate(to_bytes(cert))
to_bytes(cert), cryptography.hazmat.backends.default_backend()
)
matches = True matches = True
if not self._match_subject(x509.subject, self.subject): if not self._match_subject(x509.subject, self.subject):
matches = False matches = False
@@ -204,7 +196,6 @@ class CryptographyBackend(CryptoBackend):
key = cryptography.hazmat.primitives.serialization.load_pem_private_key( key = cryptography.hazmat.primitives.serialization.load_pem_private_key(
key_content, key_content,
password=to_bytes(passphrase) if passphrase is not None else None, password=to_bytes(passphrase) if passphrase is not None else None,
backend=_cryptography_backend,
) )
except Exception as e: except Exception as e:
raise KeyParsingError(f"error while loading key: {e}") raise KeyParsingError(f"error while loading key: {e}")
@@ -323,7 +314,7 @@ class CryptographyBackend(CryptoBackend):
) )
return { return {
"mac_obj": lambda: cryptography.hazmat.primitives.hmac.HMAC( "mac_obj": lambda: cryptography.hazmat.primitives.hmac.HMAC(
key_bytes, hashalg(), _cryptography_backend key_bytes, hashalg()
), ),
"type": "hmac", "type": "hmac",
"alg": alg, "alg": alg,
@@ -346,7 +337,7 @@ class CryptographyBackend(CryptoBackend):
csr_content = read_file(csr_filename) csr_content = read_file(csr_filename)
else: else:
csr_content = to_bytes(csr_content) 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() identifiers = set()
result = [] result = []
@@ -410,9 +401,7 @@ class CryptographyBackend(CryptoBackend):
cert_content = to_bytes(extract_first_pem(to_text(cert_content)) or "") cert_content = to_bytes(extract_first_pem(to_text(cert_content)) or "")
try: try:
cert = cryptography.x509.load_pem_x509_certificate( cert = cryptography.x509.load_pem_x509_certificate(cert_content)
cert_content, _cryptography_backend
)
except Exception as e: except Exception as e:
if cert_filename is None: if cert_filename is None:
raise BackendException(f"Cannot parse certificate: {e}") 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 "") cert_content = to_bytes(extract_first_pem(to_text(cert_content)) or "")
try: try:
cert = cryptography.x509.load_pem_x509_certificate( cert = cryptography.x509.load_pem_x509_certificate(cert_content)
cert_content, _cryptography_backend
)
except Exception as e: except Exception as e:
if cert_filename is None: if cert_filename is None:
raise BackendException(f"Cannot parse certificate: {e}") raise BackendException(f"Cannot parse certificate: {e}")
@@ -472,7 +459,7 @@ class CryptographyBackend(CryptoBackend):
return CertificateInformation( return CertificateInformation(
not_valid_after=get_not_valid_after(cert), not_valid_after=get_not_valid_after(cert),
not_valid_before=get_not_valid_before(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, subject_key_identifier=ski,
authority_key_identifier=aki, authority_key_identifier=aki,
) )

View File

@@ -5,155 +5,13 @@
from __future__ import annotations from __future__ import annotations
from ansible_collections.community.crypto.plugins.module_utils.version import (
LooseVersion,
)
try: try:
import cryptography import cryptography # noqa: F401, pylint: disable=unused-import
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
HAS_CRYPTOGRAPHY = True HAS_CRYPTOGRAPHY = True
except ImportError: except ImportError:
# Error handled in the calling module. # 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 HAS_CRYPTOGRAPHY = False

View File

@@ -27,9 +27,11 @@ try:
import cryptography import cryptography
from cryptography import x509 from cryptography import x509
from cryptography.exceptions import InvalidSignature from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import padding 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 _HAS_CRYPTOGRAPHY = True
except ImportError: except ImportError:
@@ -37,36 +39,15 @@ except ImportError:
# Error handled in the calling module. # Error handled in the calling module.
pass 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: try:
import cryptography.hazmat.primitives.asymmetric.ed448 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: except ImportError:
pass 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: try:
# This is a separate try/except since this is only present in cryptography 36.0.0 or newer # 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 ( 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 ._obj2txt import obj2txt
from ._objects import NORMALIZE_NAMES, NORMALIZE_NAMES_SHORT, OID_LOOKUP, OID_MAP from ._objects import NORMALIZE_NAMES, NORMALIZE_NAMES_SHORT, OID_LOOKUP, OID_MAP
from .basic import ( 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, OpenSSLObjectError,
) )
CRYPTOGRAPHY_TIMEZONE = False CRYPTOGRAPHY_TIMEZONE = False
_CRYPTOGRAPHY_36_0_OR_NEWER = False
if _HAS_CRYPTOGRAPHY: if _HAS_CRYPTOGRAPHY:
CRYPTOGRAPHY_TIMEZONE = LooseVersion(cryptography.__version__) >= LooseVersion( CRYPTOGRAPHY_TIMEZONE = LooseVersion(cryptography.__version__) >= LooseVersion(
"42.0.0" "42.0.0"
) )
_CRYPTOGRAPHY_36_0_OR_NEWER = LooseVersion(
cryptography.__version__
) >= LooseVersion("36.0")
DOTTED_OID = re.compile(r"^\d+(?:\.\d+)+$") DOTTED_OID = re.compile(r"^\d+(?:\.\d+)+$")
def cryptography_get_extensions_from_cert(cert): def cryptography_get_extensions_from_cert(cert):
result = dict() 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 # Since cryptography will not give us the DER value for an extension
# (that is only stored for unrecognized extensions), we have to re-do # (that is only stored for unrecognized extensions), we have to re-do
# the extension parsing ourselves. # the extension parsing ourselves.
from cryptography.hazmat.backends import default_backend
backend = 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 x509_obj = cert._x509
# With cryptography 35.0.0, we can no longer use obj2txt. Unfortunately it still does # 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 oid = exts[i].oid.dotted_string
result[oid] = entry 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 return result
def cryptography_get_extensions_from_csr(csr): def cryptography_get_extensions_from_csr(csr):
result = dict() 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 # Since cryptography will not give us the DER value for an extension
# (that is only stored for unrecognized extensions), we have to re-do # (that is only stored for unrecognized extensions), we have to re-do
# the extension parsing ourselves. # the extension parsing ourselves.
from cryptography.hazmat.backends import default_backend
backend = 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._lib.X509_REQ_get_extensions(csr._x509_req)
extensions = backend._ffi.gc( extensions = backend._ffi.gc(
@@ -220,18 +190,6 @@ def cryptography_get_extensions_from_csr(csr):
oid = exts[i].oid.dotted_string oid = exts[i].oid.dotted_string
result[oid] = entry 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 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. 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 key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey
): ):
return False return False
if CRYPTOGRAPHY_HAS_ED448 and isinstance( if isinstance(key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey):
key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey
):
return False return False
return True 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(). Needs special logic for Ed25519 and Ed448 keys, since they do not have public_numbers().
""" """
if CRYPTOGRAPHY_HAS_ED25519: res = _compare_public_keys(
res = _compare_public_keys( key1,
key1, key2,
key2, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey, )
) if res is not None:
if res is not None: return res
return res res = _compare_public_keys(
if CRYPTOGRAPHY_HAS_ED448: key1, key2, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey
res = _compare_public_keys( )
key1, key2, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey if res is not None:
) return res
if res is not None:
return res
return key1.public_numbers() == key2.public_numbers() 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) a = isinstance(key1, clazz)
b = isinstance(key2, clazz) b = isinstance(key2, clazz)
if not (a or b): if not (a or b):
return None return None
if not a or not b: if not a or not b:
return False 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() encryption_algorithm = cryptography.hazmat.primitives.serialization.NoEncryption()
a = key1.private_bytes( a = key1.private_bytes(
serialization.Encoding.Raw, 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(). Needs special logic for Ed25519, X25519, and Ed448 keys, since they do not have private_numbers().
""" """
if CRYPTOGRAPHY_HAS_ED25519: res = _compare_private_keys(
res = _compare_private_keys( key1,
key1, key2,
key2, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey, )
) if res is not None:
if res is not None: return res
return res res = _compare_private_keys(
if CRYPTOGRAPHY_HAS_X25519: key1,
res = _compare_private_keys( key2,
key1, cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey,
key2, )
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey, if res is not None:
has_no_private_bytes=not CRYPTOGRAPHY_HAS_X25519_FULL, return res
) res = _compare_private_keys(
if res is not None: key1, key2, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey
return res )
if CRYPTOGRAPHY_HAS_ED448: if res is not None:
res = _compare_private_keys( return res
key1, key2, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey res = _compare_private_keys(
) key1, key2, cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey
if res is not None: )
return res if res is not None:
if CRYPTOGRAPHY_HAS_X448: 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() 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): def parse_pkcs12(pkcs12_bytes, passphrase=None):
"""Returns a tuple (private_key, certificate, additional_certificates, friendly_name).""" """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: if passphrase is not None:
passphrase = to_bytes(passphrase) passphrase = to_bytes(passphrase)
@@ -825,6 +754,8 @@ def _parse_pkcs12_35_0_0(pkcs12_bytes, passphrase=None):
friendly_name = None friendly_name = None
if certificate: if certificate:
# See https://github.com/pyca/cryptography/issues/5760#issuecomment-842687238 # See https://github.com/pyca/cryptography/issues/5760#issuecomment-842687238
from cryptography.hazmat.backends import default_backend
backend = default_backend() backend = default_backend()
# This code basically does what load_key_and_certificates() does, but without error-checking. # 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. Check whether the given signature of the given data was signed by the given public key object.
""" """
try: try:
if CRYPTOGRAPHY_HAS_RSA_SIGN and isinstance( if isinstance(
signer_public_key, signer_public_key,
cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey, 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 signature, data, padding.PKCS1v15(), hash_algorithm
) )
return True return True
if CRYPTOGRAPHY_HAS_EC_SIGN and isinstance( if isinstance(
signer_public_key, signer_public_key,
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey, 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), cryptography.hazmat.primitives.asymmetric.ec.ECDSA(hash_algorithm),
) )
return True return True
if CRYPTOGRAPHY_HAS_DSA_SIGN and isinstance( if isinstance(
signer_public_key, signer_public_key,
cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey, cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey,
): ):
signer_public_key.verify(signature, data, hash_algorithm) signer_public_key.verify(signature, data, hash_algorithm)
return True return True
if CRYPTOGRAPHY_HAS_ED25519_SIGN and isinstance( if isinstance(
signer_public_key, signer_public_key,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
): ):
signer_public_key.verify(signature, data) signer_public_key.verify(signature, data)
return True return True
if CRYPTOGRAPHY_HAS_ED448_SIGN and isinstance( if isinstance(
signer_public_key, signer_public_key,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey, 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_IMP_ERR = None
CRYPTOGRAPHY_VERSION = 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.module_utils.common.text.converters import to_bytes, to_native
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import ( from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
CRYPTOGRAPHY_TIMEZONE, CRYPTOGRAPHY_TIMEZONE,
cryptography_serial_number_of_cert,
get_not_valid_after, get_not_valid_after,
) )
from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.certificate import ( from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.certificate import (
@@ -179,9 +178,7 @@ class EntrustCertificateBackend(CertificateBackend):
serial_number = None serial_number = None
expiry = None expiry = None
if self.backend == "cryptography": if self.backend == "cryptography":
serial_number = ( serial_number = f"{self.existing_certificate.serial_number:X}"
f"{cryptography_serial_number_of_cert(self.existing_certificate):X}"
)
expiry = get_not_valid_after(self.existing_certificate) expiry = get_not_valid_after(self.existing_certificate)
# get some information about the expiry of this 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_decode_name,
cryptography_get_extensions_from_cert, cryptography_get_extensions_from_cert,
cryptography_oid_to_name, cryptography_oid_to_name,
cryptography_serial_number_of_cert,
get_not_valid_after, get_not_valid_after,
get_not_valid_before, 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 CRYPTOGRAPHY_IMP_ERR = None
try: try:
@@ -341,20 +340,12 @@ class CertificateInfoRetrievalCryptography(CertificateInfoRetrieval):
def _get_ocsp_must_staple(self): def _get_ocsp_must_staple(self):
try: try:
try: tlsfeature_ext = self.cert.extensions.get_extension_for_class(
# This only works with cryptography >= 2.1 x509.TLSFeature
tlsfeature_ext = self.cert.extensions.get_extension_for_class( )
x509.TLSFeature value = (
) cryptography.x509.TLSFeatureType.status_request in tlsfeature_ext.value
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"
return value, tlsfeature_ext.critical return value, tlsfeature_ext.critical
except cryptography.x509.ExtensionNotFound: except cryptography.x509.ExtensionNotFound:
return None, False return None, False
@@ -416,7 +407,7 @@ class CertificateInfoRetrievalCryptography(CertificateInfoRetrieval):
return None, None, None return None, None, None
def _get_serial_number(self): def _get_serial_number(self):
return cryptography_serial_number_of_cert(self.cert) return self.cert.serial_number
def _get_all_extensions(self): def _get_all_extensions(self):
return cryptography_get_extensions_from_cert(self.cert) 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_TIMEZONE,
cryptography_compare_public_keys, cryptography_compare_public_keys,
cryptography_key_needs_digest_for_signing, cryptography_key_needs_digest_for_signing,
cryptography_serial_number_of_cert,
cryptography_verify_certificate_signature, cryptography_verify_certificate_signature,
get_not_valid_after, get_not_valid_after,
get_not_valid_before, get_not_valid_before,
@@ -44,7 +43,6 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
try: try:
import cryptography import cryptography
from cryptography import x509 from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import Encoding from cryptography.hazmat.primitives.serialization import Encoding
except ImportError: except ImportError:
pass pass
@@ -187,21 +185,10 @@ class OwnCACertificateBackendCryptography(CertificateBackend):
critical=False, critical=False,
) )
try: certificate = cert_builder.sign(
certificate = cert_builder.sign( private_key=self.ca_private_key,
private_key=self.ca_private_key, algorithm=self.digest,
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
self.cert = certificate self.cert = certificate
@@ -288,7 +275,7 @@ class OwnCACertificateBackendCryptography(CertificateBackend):
"notAfter": get_not_valid_after(self.cert).strftime( "notAfter": get_not_valid_after(self.cert).strftime(
"%Y%m%d%H%M%SZ" "%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 ( from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
CRYPTOGRAPHY_TIMEZONE, CRYPTOGRAPHY_TIMEZONE,
cryptography_key_needs_digest_for_signing, cryptography_key_needs_digest_for_signing,
cryptography_serial_number_of_cert,
cryptography_verify_certificate_signature, cryptography_verify_certificate_signature,
get_not_valid_after, get_not_valid_after,
get_not_valid_before, get_not_valid_before,
@@ -34,7 +33,6 @@ from ansible_collections.community.crypto.plugins.module_utils.time import (
try: try:
import cryptography import cryptography
from cryptography import x509 from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import Encoding from cryptography.hazmat.primitives.serialization import Encoding
except ImportError: except ImportError:
pass pass
@@ -90,17 +88,7 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
self.module.fail_json( self.module.fail_json(
msg=f'Unsupported digest "{module.params["selfsigned_digest"]}"' msg=f'Unsupported digest "{module.params["selfsigned_digest"]}"'
) )
try: self.csr = csr.sign(self.privatekey, digest)
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
if cryptography_key_needs_digest_for_signing(self.privatekey): if cryptography_key_needs_digest_for_signing(self.privatekey):
if self.digest is None: if self.digest is None:
@@ -139,21 +127,10 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
except ValueError as e: except ValueError as e:
raise CertificateError(str(e)) raise CertificateError(str(e))
try: certificate = cert_builder.sign(
certificate = cert_builder.sign( private_key=self.privatekey,
private_key=self.privatekey, algorithm=self.digest,
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
self.cert = certificate self.cert = certificate
@@ -201,7 +178,7 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
"notAfter": get_not_valid_after(self.cert).strftime( "notAfter": get_not_valid_after(self.cert).strftime(
"%Y%m%d%H%M%SZ" "%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 # crypto_utils
MINIMAL_CRYPTOGRAPHY_VERSION = "1.2" MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
CRYPTOGRAPHY_IMP_ERR = None CRYPTOGRAPHY_IMP_ERR = None
try: try:
import cryptography import cryptography
from cryptography import x509 from cryptography import x509
from cryptography.hazmat.backends import default_backend
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__) CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
except ImportError: except ImportError:
@@ -54,9 +53,9 @@ class CRLInfoRetrieval:
self.crl_pem = identify_pem_format(self.content) self.crl_pem = identify_pem_format(self.content)
try: try:
if self.crl_pem: 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: 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: except ValueError as e:
self.module.fail_json(msg=f"Error while decoding CRL: {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 CRYPTOGRAPHY_IMP_ERR = None
try: 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 parse_crl_distribution_point["relative_name"] is not None:
if not parse_crl_distribution_point["relative_name"]: if not parse_crl_distribution_point["relative_name"]:
raise OpenSSLObjectError("relative_name must not be empty") raise OpenSSLObjectError("relative_name must not be empty")
try: params["relative_name"] = (
params["relative_name"] = ( cryptography_parse_relative_distinguished_name(
cryptography_parse_relative_distinguished_name( parse_crl_distribution_point["relative_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 parse_crl_distribution_point["crl_issuer"] is not None:
if not parse_crl_distribution_point["crl_issuer"]: if not parse_crl_distribution_point["crl_issuer"]:
raise OpenSSLObjectError("crl_issuer must not be empty") raise OpenSSLObjectError("crl_issuer must not be empty")
@@ -348,7 +340,6 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
super(CertificateSigningRequestCryptographyBackend, self).__init__( super(CertificateSigningRequestCryptographyBackend, self).__init__(
module, "cryptography" module, "cryptography"
) )
self.cryptography_backend = cryptography.hazmat.backends.default_backend()
if self.version != 1: if self.version != 1:
module.warn( module.warn(
"The cryptography backend only supports version 1. (The only valid value according to RFC 2986.)" "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: if self.ocspMustStaple:
try: csr = csr.add_extension(
# This only works with cryptography >= 2.1 cryptography.x509.TLSFeature(
csr = csr.add_extension( [cryptography.x509.TLSFeatureType.status_request]
cryptography.x509.TLSFeature( ),
[cryptography.x509.TLSFeatureType.status_request] critical=self.ocspMustStaple_critical,
), )
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,
)
if self.name_constraints_permitted or self.name_constraints_excluded: if self.name_constraints_permitted or self.name_constraints_excluded:
try: try:
@@ -493,16 +475,7 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
f'Unsupported digest "{self.digest}"' f'Unsupported digest "{self.digest}"'
) )
try: try:
self.csr = csr.sign(self.privatekey, digest, self.cryptography_backend) self.csr = csr.sign(self.privatekey, digest)
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
except UnicodeError as e: except UnicodeError as e:
# This catches IDNAErrors, which happens when a bad name is passed as a SAN # This catches IDNAErrors, which happens when a bad name is passed as a SAN
# (https://github.com/ansible-collections/community.crypto/issues/105). # (https://github.com/ansible-collections/community.crypto/issues/105).
@@ -636,22 +609,8 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
return bc_ext is None return bc_ext is None
def _check_ocspMustStaple(extensions): def _check_ocspMustStaple(extensions):
try: tlsfeature_ext = _find_extension(extensions, cryptography.x509.TLSFeature)
# This only works with cryptography >= 2.1 has_tlsfeature = True
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
if self.ocspMustStaple: if self.ocspMustStaple:
if ( if (
not tlsfeature_ext 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 CRYPTOGRAPHY_IMP_ERR = None
try: try:
@@ -267,20 +267,13 @@ class CSRInfoRetrievalCryptography(CSRInfoRetrieval):
def _get_ocsp_must_staple(self): def _get_ocsp_must_staple(self):
try: try:
try: # This only works with cryptography >= 2.1
# This only works with cryptography >= 2.1 tlsfeature_ext = self.csr.extensions.get_extension_for_class(
tlsfeature_ext = self.csr.extensions.get_extension_for_class( x509.TLSFeature
x509.TLSFeature )
) value = (
value = ( cryptography.x509.TLSFeatureType.status_request in tlsfeature_ext.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"
return value, tlsfeature_ext.critical return value, tlsfeature_ext.critical
except cryptography.x509.ExtensionNotFound: except cryptography.x509.ExtensionNotFound:
return None, False return None, False

View File

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

View File

@@ -14,10 +14,6 @@ from ansible_collections.community.crypto.plugins.module_utils.argspec import (
ArgumentSpec, ArgumentSpec,
) )
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import ( from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
CRYPTOGRAPHY_HAS_ED448,
CRYPTOGRAPHY_HAS_ED25519,
CRYPTOGRAPHY_HAS_X448,
CRYPTOGRAPHY_HAS_X25519,
OpenSSLObjectError, OpenSSLObjectError,
) )
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import ( 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 CRYPTOGRAPHY_IMP_ERR = None
try: try:
@@ -41,8 +37,12 @@ try:
import cryptography.hazmat.backends import cryptography.hazmat.backends
import cryptography.hazmat.primitives.asymmetric.dsa import cryptography.hazmat.primitives.asymmetric.dsa
import cryptography.hazmat.primitives.asymmetric.ec 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.rsa
import cryptography.hazmat.primitives.asymmetric.utils import cryptography.hazmat.primitives.asymmetric.utils
import cryptography.hazmat.primitives.asymmetric.x448
import cryptography.hazmat.primitives.asymmetric.x25519
import cryptography.hazmat.primitives.serialization import cryptography.hazmat.primitives.serialization
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__) CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
@@ -136,8 +136,6 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
module=module, backend="cryptography" module=module, backend="cryptography"
) )
self.cryptography_backend = cryptography.hazmat.backends.default_backend()
def get_private_key_data(self): def get_private_key_data(self):
"""Return bytes for self.src_private_key in output format""" """Return bytes for self.src_private_key in output format"""
# Select export format and encoding # Select export format and encoding
@@ -199,14 +197,14 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
if format == "raw": if format == "raw":
if passphrase is not None: if passphrase is not None:
raise PrivateKeyError("Cannot load raw key with passphrase") raise PrivateKeyError("Cannot load raw key with passphrase")
if len(data) == 56 and CRYPTOGRAPHY_HAS_X448: if len(data) == 56:
return ( return (
format, format,
cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey.from_private_bytes( cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey.from_private_bytes(
data data
), ),
) )
if len(data) == 57 and CRYPTOGRAPHY_HAS_ED448: if len(data) == 57:
return ( return (
format, format,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey.from_private_bytes( cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey.from_private_bytes(
@@ -214,54 +212,39 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
), ),
) )
if len(data) == 32: if len(data) == 32:
if CRYPTOGRAPHY_HAS_X25519 and not CRYPTOGRAPHY_HAS_ED25519: if isinstance(
return ( current_hint,
format, cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey,
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes( ):
data try:
), return (
) format,
if CRYPTOGRAPHY_HAS_ED25519 and not CRYPTOGRAPHY_HAS_X25519: cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
return ( data
format, ),
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes( )
data except Exception:
), return (
) format,
if CRYPTOGRAPHY_HAS_X25519 and CRYPTOGRAPHY_HAS_ED25519: cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
if isinstance( data
current_hint, ),
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey, )
): else:
try: try:
return ( return (
format, format,
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes( cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
data data
), ),
) )
except Exception: except Exception:
return ( return (
format, format,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes( cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
data 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") raise PrivateKeyError("Cannot load raw key")
else: else:
return ( return (
@@ -269,7 +252,6 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
cryptography.hazmat.primitives.serialization.load_pem_private_key( cryptography.hazmat.primitives.serialization.load_pem_private_key(
data, data,
None if passphrase is None else to_bytes(passphrase), None if passphrase is None else to_bytes(passphrase),
backend=self.cryptography_backend,
), ),
) )
except Exception as e: 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.basic import missing_required_lib
from ansible.module_utils.common.text.converters import to_bytes, to_native from ansible.module_utils.common.text.converters import to_bytes, to_native
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import ( from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
CRYPTOGRAPHY_HAS_ED448,
CRYPTOGRAPHY_HAS_ED25519,
OpenSSLObjectError, OpenSSLObjectError,
) )
from ansible_collections.community.crypto.plugins.module_utils.crypto.math import ( 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 CRYPTOGRAPHY_IMP_ERR = None
try: try:
@@ -115,13 +113,9 @@ def _is_cryptography_key_consistent(
result = _check_dsa_consistency(key_public_data, key_private_data) result = _check_dsa_consistency(key_public_data, key_private_data)
if result is not None: if result is not None:
return result return result
try: signature = key.sign(
signature = key.sign( SIGNATURE_TEST_DATA, cryptography.hazmat.primitives.hashes.SHA256()
SIGNATURE_TEST_DATA, cryptography.hazmat.primitives.hashes.SHA256() )
)
except AttributeError:
# sign() was added in cryptography 1.5, but we support older versions
return None
try: try:
key.public_key().verify( key.public_key().verify(
signature, signature,
@@ -134,16 +128,12 @@ def _is_cryptography_key_consistent(
if isinstance( if isinstance(
key, cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey key, cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey
): ):
try: signature = key.sign(
signature = key.sign( SIGNATURE_TEST_DATA,
SIGNATURE_TEST_DATA, cryptography.hazmat.primitives.asymmetric.ec.ECDSA(
cryptography.hazmat.primitives.asymmetric.ec.ECDSA( cryptography.hazmat.primitives.hashes.SHA256()
cryptography.hazmat.primitives.hashes.SHA256() ),
), )
)
except AttributeError:
# sign() was added in cryptography 1.5, but we support older versions
return None
try: try:
key.public_key().verify( key.public_key().verify(
signature, signature,
@@ -156,13 +146,11 @@ def _is_cryptography_key_consistent(
except cryptography.exceptions.InvalidSignature: except cryptography.exceptions.InvalidSignature:
return False return False
has_simple_sign_function = False has_simple_sign_function = False
if CRYPTOGRAPHY_HAS_ED25519 and isinstance( if isinstance(
key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey
): ):
has_simple_sign_function = True has_simple_sign_function = True
if CRYPTOGRAPHY_HAS_ED448 and isinstance( if isinstance(key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey):
key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey
):
has_simple_sign_function = True has_simple_sign_function = True
if has_simple_sign_function: if has_simple_sign_function:
signature = key.sign(SIGNATURE_TEST_DATA) 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.basic import missing_required_lib
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import ( from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
CRYPTOGRAPHY_HAS_ED448,
CRYPTOGRAPHY_HAS_ED25519,
CRYPTOGRAPHY_HAS_X448,
CRYPTOGRAPHY_HAS_X25519,
OpenSSLObjectError, OpenSSLObjectError,
) )
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import ( 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 CRYPTOGRAPHY_IMP_ERR = None
try: try:
import cryptography 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 from cryptography.hazmat.primitives import serialization
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__) 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["q"] = parameter_numbers.q
key_public_data["g"] = parameter_numbers.g key_public_data["g"] = parameter_numbers.g
key_public_data["y"] = public_numbers.y key_public_data["y"] = public_numbers.y
elif CRYPTOGRAPHY_HAS_X25519 and isinstance( elif isinstance(
key, cryptography.hazmat.primitives.asymmetric.x25519.X25519PublicKey key, cryptography.hazmat.primitives.asymmetric.x25519.X25519PublicKey
): ):
key_type = "X25519" key_type = "X25519"
elif CRYPTOGRAPHY_HAS_X448 and isinstance( elif isinstance(key, cryptography.hazmat.primitives.asymmetric.x448.X448PublicKey):
key, cryptography.hazmat.primitives.asymmetric.x448.X448PublicKey
):
key_type = "X448" key_type = "X448"
elif CRYPTOGRAPHY_HAS_ED25519 and isinstance( elif isinstance(
key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey
): ):
key_type = "Ed25519" key_type = "Ed25519"
elif CRYPTOGRAPHY_HAS_ED448 and isinstance( elif isinstance(
key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey
): ):
key_type = "Ed448" key_type = "Ed448"

View File

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

View File

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

View File

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

View File

@@ -22,7 +22,7 @@ seealso:
description: The specification of the C(tls-alpn-01) challenge (RFC 8737). description: The specification of the C(tls-alpn-01) challenge (RFC 8737).
link: https://www.rfc-editor.org/rfc/rfc8737.html link: https://www.rfc-editor.org/rfc/rfc8737.html
requirements: requirements:
- "cryptography >= 1.3" - "cryptography >= 3.4"
extends_documentation_fragment: extends_documentation_fragment:
- community.crypto.attributes - community.crypto.attributes
attributes: attributes:
@@ -184,8 +184,7 @@ try:
import cryptography.x509 import cryptography.x509
import cryptography.x509.oid import cryptography.x509.oid
HAS_CRYPTOGRAPHY = LooseVersion(cryptography.__version__) >= LooseVersion("1.3") HAS_CRYPTOGRAPHY = LooseVersion(cryptography.__version__) >= LooseVersion("3.4")
_cryptography_backend = cryptography.hazmat.backends.default_backend()
except ImportError: except ImportError:
CRYPTOGRAPHY_IMP_ERR = traceback.format_exc() CRYPTOGRAPHY_IMP_ERR = traceback.format_exc()
HAS_CRYPTOGRAPHY = False HAS_CRYPTOGRAPHY = False
@@ -216,10 +215,10 @@ def main():
# Some callbacks die when exception is provided with value None # Some callbacks die when exception is provided with value None
if CRYPTOGRAPHY_IMP_ERR: if CRYPTOGRAPHY_IMP_ERR:
module.fail_json( module.fail_json(
msg=missing_required_lib("cryptography >= 1.3"), msg=missing_required_lib("cryptography >= 3.4"),
exception=CRYPTOGRAPHY_IMP_ERR, 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: try:
# Get parameters # Get parameters
@@ -242,7 +241,6 @@ def main():
if private_key_passphrase is not None if private_key_passphrase is not None
else None else None
), ),
backend=_cryptography_backend,
) )
) )
except Exception as e: except Exception as e:
@@ -283,7 +281,6 @@ def main():
regular_certificate = cert_builder.sign( regular_certificate = cert_builder.sign(
private_key, private_key,
cryptography.hazmat.primitives.hashes.SHA256(), cryptography.hazmat.primitives.hashes.SHA256(),
_cryptography_backend,
) )
# Process challenge # Process challenge
@@ -312,7 +309,6 @@ def main():
challenge_certificate = cert_builder.sign( challenge_certificate = cert_builder.sign(
private_key, private_key,
cryptography.hazmat.primitives.hashes.SHA256(), cryptography.hazmat.primitives.hashes.SHA256(),
_cryptography_backend,
) )
module.exit_json( 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 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 ...). chain is valid, please use C(openssl verify ...).
requirements: requirements:
- "cryptography >= 1.5" - "cryptography >= 3.4"
extends_documentation_fragment: extends_documentation_fragment:
- community.crypto.attributes - community.crypto.attributes
- community.crypto.attributes.idempotent_not_modify_state - 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.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.common.text.converters import to_bytes 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 ( from ansible_collections.community.crypto.plugins.module_utils.crypto.pem import (
split_pem_list, split_pem_list,
) )
@@ -152,8 +148,7 @@ try:
import cryptography.x509 import cryptography.x509
import cryptography.x509.oid import cryptography.x509.oid
HAS_CRYPTOGRAPHY = LooseVersion(cryptography.__version__) >= LooseVersion("1.5") HAS_CRYPTOGRAPHY = LooseVersion(cryptography.__version__) >= LooseVersion("3.4")
_cryptography_backend = cryptography.hazmat.backends.default_backend()
except ImportError: except ImportError:
CRYPTOGRAPHY_IMP_ERR = traceback.format_exc() CRYPTOGRAPHY_IMP_ERR = traceback.format_exc()
HAS_CRYPTOGRAPHY = False HAS_CRYPTOGRAPHY = False
@@ -201,12 +196,12 @@ def is_parent(module, cert, potential_parent):
cert.cert.signature_hash_algorithm cert.cert.signature_hash_algorithm
), ),
) )
elif CRYPTOGRAPHY_HAS_ED25519_SIGN and isinstance( elif isinstance(
public_key, public_key,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
): ):
public_key.verify(cert.cert.signature, cert.cert.tbs_certificate_bytes) 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, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey
): ):
public_key.verify(cert.cert.signature, cert.cert.tbs_certificate_bytes) 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): for cert_pem in split_pem_list(text):
# Try to load PEM certificate # Try to load PEM certificate
try: try:
cert = cryptography.x509.load_pem_x509_certificate( cert = cryptography.x509.load_pem_x509_certificate(to_bytes(cert_pem))
to_bytes(cert_pem), _cryptography_backend
)
result.append(Certificate(cert_pem, cert)) result.append(Certificate(cert_pem, cert))
except Exception as e: except Exception as e:
msg = f"Cannot parse certificate #{len(result) + 1} from {source}: {e}" msg = f"Cannot parse certificate #{len(result) + 1} from {source}: {e}"
@@ -338,7 +331,7 @@ def main():
if not HAS_CRYPTOGRAPHY: if not HAS_CRYPTOGRAPHY:
module.fail_json( module.fail_json(
msg=missing_required_lib("cryptography >= 1.5"), msg=missing_required_lib("cryptography >= 3.4"),
exception=CRYPTOGRAPHY_IMP_ERR, exception=CRYPTOGRAPHY_IMP_ERR,
) )

View File

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

View File

@@ -20,7 +20,7 @@ description:
notes: notes:
- O(path) must be specified as the output location of the certificate. - O(path) must be specified as the output location of the certificate.
requirements: requirements:
- cryptography >= 1.6 - cryptography >= 3.4
extends_documentation_fragment: extends_documentation_fragment:
- community.crypto.attributes - community.crypto.attributes
- community.crypto.attributes.files - community.crypto.attributes.files
@@ -581,7 +581,7 @@ except ImportError:
else: else:
CRYPTOGRAPHY_FOUND = True CRYPTOGRAPHY_FOUND = True
MINIMAL_CRYPTOGRAPHY_VERSION = "1.6" MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
def validate_cert_expiry(cert_expiry): 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. - When using ca_cert on OS X it has been reported that in some conditions the validate will always succeed.
requirements: requirements:
- "Python >= 3.10 when O(get_certificate_chain=true)" - "Python >= 3.10 when O(get_certificate_chain=true)"
- "cryptography >= 1.6" - "cryptography >= 3.4"
seealso: seealso:
- plugin: community.crypto.to_serial - 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 CRYPTOGRAPHY_IMP_ERR = None
try: try:
import cryptography import cryptography
import cryptography.exceptions import cryptography.exceptions
import cryptography.x509 import cryptography.x509
from cryptography.hazmat.backends import default_backend as cryptography_backend
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__) CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
except ImportError: except ImportError:
@@ -528,9 +527,7 @@ def main():
result["cert"] = cert result["cert"] = cert
if backend == "cryptography": if backend == "cryptography":
x509 = cryptography.x509.load_pem_x509_certificate( x509 = cryptography.x509.load_pem_x509_certificate(to_bytes(cert))
to_bytes(cert), cryptography_backend()
)
result["subject"] = {} result["subject"] = {}
for attribute in x509.subject: for attribute in x509.subject:
result["subject"][cryptography_oid_to_name(attribute.oid, short=True)] = ( 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. V(rsa), V(dsa), V(rsa1), V(ed25519) or V(ecdsa) private keys.
requirements: requirements:
- ssh-keygen (if O(backend=openssh)) - ssh-keygen (if O(backend=openssh))
- cryptography >= 2.6 (if O(backend=cryptography) and OpenSSH < 7.8 is installed) - cryptography >= 3.4 (if O(backend=cryptography))
- cryptography >= 3.0 (if O(backend=cryptography) and OpenSSH >= 7.8 is installed)
extends_documentation_fragment: extends_documentation_fragment:
- ansible.builtin.files - ansible.builtin.files
- community.crypto.attributes - 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. - 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. - It uses the cryptography python library to interact with OpenSSL.
requirements: requirements:
- cryptography >= 1.3 - cryptography >= 3.4
author: author:
- Felix Fontein (@felixfontein) - Felix Fontein (@felixfontein)
- Yanis Guenane (@Spredzy) - 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 - 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. one is available. This can be overridden with the O(select_crypto_backend) option.
requirements: requirements:
- Either cryptography >= 2.0 - Either cryptography >= 3.4
- Or OpenSSL binary C(openssl) - Or OpenSSL binary C(openssl)
author: author:
- Thom Wiggers (@thomwiggers) - 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 CRYPTOGRAPHY_IMP_ERR = None
try: try:
@@ -322,7 +322,6 @@ class DHParameterCryptography(DHParameterBase):
def __init__(self, module): def __init__(self, module):
super(DHParameterCryptography, self).__init__(module) super(DHParameterCryptography, self).__init__(module)
self.crypto_backend = cryptography.hazmat.backends.default_backend()
def _do_generate(self, module): def _do_generate(self, module):
"""Actually generate the DH params.""" """Actually generate the DH params."""
@@ -330,7 +329,6 @@ class DHParameterCryptography(DHParameterBase):
params = cryptography.hazmat.primitives.asymmetric.dh.generate_parameters( params = cryptography.hazmat.primitives.asymmetric.dh.generate_parameters(
generator=2, generator=2,
key_size=self.size, key_size=self.size,
backend=self.crypto_backend,
) )
# Serialize parameters # Serialize parameters
result = params.parameter_bytes( result = params.parameter_bytes(
@@ -349,7 +347,7 @@ class DHParameterCryptography(DHParameterBase):
with open(self.path, "rb") as f: with open(self.path, "rb") as f:
data = f.read() data = f.read()
params = cryptography.hazmat.primitives.serialization.load_pem_parameters( params = cryptography.hazmat.primitives.serialization.load_pem_parameters(
data, backend=self.crypto_backend data
) )
except Exception: except Exception:
return False return False

View File

@@ -15,7 +15,7 @@ description:
- This module allows one to (re-)generate PKCS#12. - This module allows one to (re-)generate PKCS#12.
- The module uses the cryptography Python library. - The module uses the cryptography Python library.
requirements: requirements:
- cryptography >= 3.0 - cryptography >= 3.4
extends_documentation_fragment: extends_documentation_fragment:
- ansible.builtin.files - ansible.builtin.files
- community.crypto.attributes - 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 CRYPTOGRAPHY_IMP_ERR = None
try: try:

View File

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

View File

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

View File

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

View File

@@ -14,7 +14,7 @@ description:
- This module allows one to sign data using a private key. - This module allows one to sign data using a private key.
- The module uses the cryptography Python library. - The module uses the cryptography Python library.
requirements: requirements:
- cryptography >= 1.4 (some key types require newer versions) - cryptography >= 3.4
author: author:
- Patrick Pichler (@aveexy) - Patrick Pichler (@aveexy)
- Markus Teufelberger (@MarkusTeufelberger) - Markus Teufelberger (@MarkusTeufelberger)
@@ -62,10 +62,6 @@ options:
type: str type: str
default: auto default: auto
choices: [auto, cryptography] 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: seealso:
- module: community.crypto.openssl_signature_info - module: community.crypto.openssl_signature_info
- module: community.crypto.openssl_privatekey - 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 CRYPTOGRAPHY_IMP_ERR = None
try: try:
@@ -126,11 +122,6 @@ else:
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import ( 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, OpenSSLObjectError,
) )
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import ( from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
@@ -191,42 +182,37 @@ class SignatureCryptography(SignatureBase):
signature = None signature = None
if CRYPTOGRAPHY_HAS_DSA_SIGN: if isinstance(
if isinstance( private_key,
private_key, cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey,
cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey, ):
): signature = private_key.sign(_in, _hash)
signature = private_key.sign(_in, _hash)
if CRYPTOGRAPHY_HAS_EC_SIGN: elif isinstance(
if isinstance( private_key,
private_key, cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey,
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey, ):
): signature = private_key.sign(
signature = private_key.sign( _in, cryptography.hazmat.primitives.asymmetric.ec.ECDSA(_hash)
_in, cryptography.hazmat.primitives.asymmetric.ec.ECDSA(_hash) )
)
if CRYPTOGRAPHY_HAS_ED25519_SIGN: elif isinstance(
if isinstance( private_key,
private_key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey,
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey, ):
): signature = private_key.sign(_in)
signature = private_key.sign(_in)
if CRYPTOGRAPHY_HAS_ED448_SIGN: elif isinstance(
if isinstance( private_key,
private_key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey,
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey, ):
): signature = private_key.sign(_in)
signature = private_key.sign(_in)
if CRYPTOGRAPHY_HAS_RSA_SIGN: elif isinstance(
if isinstance( private_key,
private_key, cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey,
cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey, ):
): signature = private_key.sign(_in, _padding, _hash)
signature = private_key.sign(_in, _padding, _hash)
if signature is None: if signature is None:
self.module.fail_json( 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. - This module allows one to verify a signature for a file by a certificate.
- The module uses the cryptography Python library. - The module uses the cryptography Python library.
requirements: requirements:
- cryptography >= 1.4 (some key types require newer versions) - cryptography >= 3.4
author: author:
- Patrick Pichler (@aveexy) - Patrick Pichler (@aveexy)
- Markus Teufelberger (@MarkusTeufelberger) - Markus Teufelberger (@MarkusTeufelberger)
@@ -51,10 +51,6 @@ options:
type: str type: str
default: auto default: auto
choices: [auto, cryptography] 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: seealso:
- module: community.crypto.openssl_signature - module: community.crypto.openssl_signature
- module: community.crypto.x509_certificate - 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 CRYPTOGRAPHY_IMP_ERR = None
try: try:
@@ -115,11 +111,6 @@ else:
from ansible.module_utils.basic import AnsibleModule, missing_required_lib from ansible.module_utils.basic import AnsibleModule, missing_required_lib
from ansible.module_utils.common.text.converters import to_native from ansible.module_utils.common.text.converters import to_native
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import ( 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, OpenSSLObjectError,
) )
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import ( from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
@@ -181,74 +172,53 @@ class SignatureInfoCryptography(SignatureInfoBase):
verified = False verified = False
valid = False valid = False
if CRYPTOGRAPHY_HAS_DSA_SIGN: try:
try: if isinstance(
if isinstance( public_key,
public_key, cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey,
cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey, ):
): public_key.verify(_signature, _in, _hash)
public_key.verify(_signature, _in, _hash)
verified = True
valid = True
except cryptography.exceptions.InvalidSignature:
verified = True verified = True
valid = False valid = True
if CRYPTOGRAPHY_HAS_EC_SIGN: elif isinstance(
try: public_key,
if isinstance( cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey,
public_key, ):
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey, public_key.verify(
): _signature,
public_key.verify( _in,
_signature, cryptography.hazmat.primitives.asymmetric.ec.ECDSA(_hash),
_in, )
cryptography.hazmat.primitives.asymmetric.ec.ECDSA(_hash),
)
verified = True
valid = True
except cryptography.exceptions.InvalidSignature:
verified = True verified = True
valid = False valid = True
if CRYPTOGRAPHY_HAS_ED25519_SIGN: elif isinstance(
try: public_key,
if isinstance( cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
public_key, ):
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey, public_key.verify(_signature, _in)
):
public_key.verify(_signature, _in)
verified = True
valid = True
except cryptography.exceptions.InvalidSignature:
verified = True verified = True
valid = False valid = True
if CRYPTOGRAPHY_HAS_ED448_SIGN: elif isinstance(
try: public_key,
if isinstance( cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey,
public_key, ):
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey, public_key.verify(_signature, _in)
):
public_key.verify(_signature, _in)
verified = True
valid = True
except cryptography.exceptions.InvalidSignature:
verified = True verified = True
valid = False valid = True
if CRYPTOGRAPHY_HAS_RSA_SIGN: elif isinstance(
try: public_key,
if isinstance( cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey,
public_key, ):
cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey, public_key.verify(_signature, _in, _padding, _hash)
):
public_key.verify(_signature, _in, _padding, _hash)
verified = True
valid = True
except cryptography.exceptions.InvalidSignature:
verified = True verified = True
valid = False valid = True
except cryptography.exceptions.InvalidSignature:
verified = True
valid = False
if not verified: if not verified:
self.module.fail_json( self.module.fail_json(

View File

@@ -85,8 +85,6 @@ seealso:
- module: community.crypto.x509_certificate - module: community.crypto.x509_certificate
- module: community.crypto.x509_certificate_pipe - module: community.crypto.x509_certificate_pipe
- module: community.crypto.x509_certificate_info - module: community.crypto.x509_certificate_info
requirements:
- cryptography >= 1.6 if O(verify_cert_parsable=true)
""" """
EXAMPLES = r""" 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 CRYPTOGRAPHY_IMP_ERR = None
try: try:
import cryptography # noqa: F401, pylint: disable=unused-import import cryptography # noqa: F401, pylint: disable=unused-import
from cryptography.hazmat.backends import default_backend
from cryptography.x509 import load_der_x509_certificate from cryptography.x509 import load_der_x509_certificate
except ImportError: except ImportError:
CRYPTOGRAPHY_IMP_ERR = traceback.format_exc() CRYPTOGRAPHY_IMP_ERR = traceback.format_exc()
@@ -234,7 +231,7 @@ class X509CertificateConvertModule(OpenSSLObject):
exception=CRYPTOGRAPHY_IMP_ERR, exception=CRYPTOGRAPHY_IMP_ERR,
) )
try: try:
load_der_x509_certificate(self.input, default_backend()) load_der_x509_certificate(self.input)
except Exception as exc: except Exception as exc:
module.fail_json(msg=f"Error while parsing certificate: {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) 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. keyword, the new name M(community.crypto.x509_certificate_info) should be used to avoid a deprecation warning.
requirements: requirements:
- cryptography >= 1.6 - cryptography >= 3.4
author: author:
- Felix Fontein (@felixfontein) - Felix Fontein (@felixfontein)
- Yanis Guenane (@Spredzy) - 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 - 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. to a certificate file in PEM format.
requirements: requirements:
- cryptography >= 1.2 - cryptography >= 3.4
author: author:
- Felix Fontein (@felixfontein) - Felix Fontein (@felixfontein)
extends_documentation_fragment: extends_documentation_fragment:
@@ -455,7 +455,6 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptograp
cryptography_key_needs_digest_for_signing, cryptography_key_needs_digest_for_signing,
cryptography_name_to_oid, cryptography_name_to_oid,
cryptography_oid_to_name, cryptography_oid_to_name,
cryptography_serial_number_of_cert,
) )
from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.crl_info import ( from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.crl_info import (
get_crl_info, 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 CRYPTOGRAPHY_IMP_ERR = None
try: try:
import cryptography import cryptography
from cryptography import x509 from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import Encoding from cryptography.hazmat.primitives.serialization import Encoding
from cryptography.x509 import ( from cryptography.x509 import (
CertificateRevocationListBuilder, CertificateRevocationListBuilder,
@@ -585,7 +583,7 @@ class CRL(OpenSSLObject):
cert = load_certificate( cert = load_certificate(
rc["path"], content=rc["content"], backend="cryptography" 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: except OpenSSLObjectError as e:
if rc["content"] is not None: if rc["content"] is not None:
module.fail_json( module.fail_json(
@@ -642,11 +640,11 @@ class CRL(OpenSSLObject):
data = f.read() data = f.read()
self.actual_format = "pem" if identify_pem_format(data) else "der" self.actual_format = "pem" if identify_pem_format(data) else "der"
if self.actual_format == "pem": 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: if self.return_content:
self.crl_content = data self.crl_content = data
else: else:
self.crl = x509.load_der_x509_crl(data, default_backend()) self.crl = x509.load_der_x509_crl(data)
if self.return_content: if self.return_content:
self.crl_content = base64.b64encode(data) self.crl_content = base64.b64encode(data)
except Exception: except Exception:
@@ -783,7 +781,6 @@ class CRL(OpenSSLObject):
return True return True
def _generate_crl(self): def _generate_crl(self):
backend = default_backend()
crl = CertificateRevocationListBuilder() crl = CertificateRevocationListBuilder()
try: try:
@@ -830,12 +827,12 @@ class CRL(OpenSSLObject):
x509.InvalidityDate(entry["invalidity_date"]), x509.InvalidityDate(entry["invalidity_date"]),
entry["invalidity_date_critical"], entry["invalidity_date_critical"],
) )
crl = crl.add_revoked_certificate(revoked_cert.build(backend)) crl = crl.add_revoked_certificate(revoked_cert.build())
digest = None digest = None
if cryptography_key_needs_digest_for_signing(self.privatekey): if cryptography_key_needs_digest_for_signing(self.privatekey):
digest = self.digest digest = self.digest
self.crl = crl.sign(self.privatekey, digest, backend=backend) self.crl = crl.sign(self.privatekey, digest)
if self.format == "pem": if self.format == "pem":
return self.crl.public_bytes(Encoding.PEM) return self.crl.public_bytes(Encoding.PEM)
else: else:

View File

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

View File

@@ -37,4 +37,4 @@
- import_tasks: ../tests/validate.yml - import_tasks: ../tests/validate.yml
when: cryptography_version.stdout is version('1.5', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -37,4 +37,4 @@
- import_tasks: ../tests/validate.yml - import_tasks: ../tests/validate.yml
when: cryptography_version.stdout is version('1.5', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -41,4 +41,4 @@
- import_tasks: ../tests/validate.yml - import_tasks: ../tests/validate.yml
when: cryptography_version.stdout is version('1.5', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -364,7 +364,6 @@
set_fact: set_fact:
cert_8_obtain_results: "{{ certificate_obtain_result }}" cert_8_obtain_results: "{{ certificate_obtain_result }}"
cert_8_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}" cert_8_alternate: "{{ 0 if select_crypto_backend == 'cryptography' else 0 }}"
when: cryptography_version.stdout is version('1.3', '>=')
## DISSECT CERTIFICATES ####################################################################### ## DISSECT CERTIFICATES #######################################################################
# Make sure certificates are valid. Root certificate for Pebble equals the chain certificate. # Make sure certificates are valid. Root certificate for Pebble equals the chain certificate.
@@ -402,7 +401,6 @@
command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-8-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-8-chain.pem" "{{ remote_tmp_dir }}/cert-8.pem"' command: '{{ openssl_binary }} verify -CAfile "{{ remote_tmp_dir }}/cert-8-root.pem" -untrusted "{{ remote_tmp_dir }}/cert-8-chain.pem" "{{ remote_tmp_dir }}/cert-8.pem"'
ignore_errors: true ignore_errors: true
register: cert_8_valid register: cert_8_valid
when: cryptography_version.stdout is version('1.3', '>=')
# Dump certificate info # Dump certificate info
- name: Dumping cert 1 - name: Dumping cert 1
@@ -431,7 +429,6 @@
- name: Dumping cert 8 - name: Dumping cert 8
command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-8.pem" -noout -text' command: '{{ openssl_binary }} x509 -in "{{ remote_tmp_dir }}/cert-8.pem" -noout -text'
register: cert_8_text register: cert_8_text
when: cryptography_version.stdout is version('1.3', '>=')
# Dump certificate info # Dump certificate info
- name: Dumping cert 1 - name: Dumping cert 1
@@ -468,7 +465,6 @@
x509_certificate_info: x509_certificate_info:
path: "{{ remote_tmp_dir }}/cert-8.pem" path: "{{ remote_tmp_dir }}/cert-8.pem"
register: cert_8_info register: cert_8_info
when: cryptography_version.stdout is version('1.3', '>=')
## GET ACCOUNT ORDERS ######################################################################### ## GET ACCOUNT ORDERS #########################################################################
- name: Don't retrieve orders - name: Don't retrieve orders

View File

@@ -118,4 +118,4 @@
- import_tasks: ../tests/validate.yml - import_tasks: ../tests/validate.yml
when: cryptography_version.stdout is version('1.5', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -159,7 +159,6 @@
assert: assert:
that: that:
- "'IP Address:127.0.0.1' in cert_8_text.stdout or 'IP:127.0.0.1' in cert_8_text.stdout" - "'IP Address:127.0.0.1' in cert_8_text.stdout or 'IP:127.0.0.1' in cert_8_text.stdout"
when: cryptography_version.stdout is version('1.3', '>=')
- name: Validate that orders were not retrieved - name: Validate that orders were not retrieved
assert: assert:

View File

@@ -37,4 +37,4 @@
- import_tasks: ../tests/validate.yml - import_tasks: ../tests/validate.yml
when: cryptography_version.stdout is version('1.5', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -147,11 +147,6 @@
- validate_1 is changed - validate_1 is changed
- validate_1.account_uri == account.account_uri - validate_1.account_uri == account.account_uri
- name: "({{ select_crypto_backend }}) Wait until we know that the challenges have been validated for ansible-core <= 2.11"
pause:
seconds: 5
when: ansible_version.full is version('2.12', '<')
- name: "({{ select_crypto_backend }}) Get order information" - name: "({{ select_crypto_backend }}) Get order information"
acme_certificate_order_info: acme_certificate_order_info:
acme_directory: "{{ acme_directory_url }}" acme_directory: "{{ acme_directory_url }}"

View File

@@ -33,4 +33,4 @@
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('1.5', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -40,4 +40,4 @@
- import_tasks: ../tests/validate.yml - import_tasks: ../tests/validate.yml
when: cryptography_version.stdout is version('1.5', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -37,4 +37,4 @@
- import_tasks: ../tests/validate.yml - import_tasks: ../tests/validate.yml
when: cryptography_version.stdout is version('1.5', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -35,4 +35,4 @@
terms_agreed: true terms_agreed: true
account_email: "example@example.org" account_email: "example@example.org"
when: cryptography_version.stdout is version('1.5', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -37,4 +37,4 @@
- import_tasks: ../tests/validate.yml - import_tasks: ../tests/validate.yml
when: cryptography_version.stdout is version('1.5', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -10,11 +10,6 @@
- block: - block:
- name: Make sure testhost directory exists
file:
path: '{{ remote_tmp_dir }}/files/'
state: directory
when: ansible_version.string is version('2.10', '<')
- name: Copy test files to testhost - name: Copy test files to testhost
copy: copy:
src: '{{ role_path }}/files/' src: '{{ role_path }}/files/'
@@ -29,4 +24,4 @@
- name: Run tests with created certificates - name: Run tests with created certificates
import_tasks: created.yml import_tasks: created.yml
when: cryptography_version.stdout is version('1.5', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -27,7 +27,7 @@
- result.extensions_by_oid['2.5.29.15'].critical == true - result.extensions_by_oid['2.5.29.15'].critical == true
- result.extensions_by_oid['2.5.29.15'].value in ['AwMA/4A=', 'AwMH/4A='] - result.extensions_by_oid['2.5.29.15'].value in ['AwMA/4A=', 'AwMH/4A=']
# Subject Alternative Names # Subject Alternative Names
- result.subject_alt_name[1] == ("DNS:âņsïbłè.com" if cryptography_version.stdout is version('2.1', '<') else "DNS:xn--sb-oia0a7a53bya.com") - result.subject_alt_name[1] == "DNS:xn--sb-oia0a7a53bya.com"
- result_unicode.subject_alt_name[1] == "DNS:âņsïbłè.com" - result_unicode.subject_alt_name[1] == "DNS:âņsïbłè.com"
- result_idna.subject_alt_name[1] == "DNS:xn--sb-oia0a7a53bya.com" - result_idna.subject_alt_name[1] == "DNS:xn--sb-oia0a7a53bya.com"
- result.extensions_by_oid['2.5.29.17'].critical == false - result.extensions_by_oid['2.5.29.17'].critical == false
@@ -54,7 +54,6 @@
expected_authority_cert_issuer: expected_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
- "IP:1.2.3.4" - "IP:1.2.3.4"
when: cryptography_version.stdout is version('1.3', '>=')
- name: "Get CSR info" - name: "Get CSR info"
set_fact: set_fact:
@@ -76,7 +75,6 @@
expected_authority_cert_issuer: expected_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
- "IP:1.2.3.4" - "IP:1.2.3.4"
when: cryptography_version.stdout is version('1.3', '>=')
- name: "Get CSR info" - name: "Get CSR info"
set_fact: set_fact:
@@ -89,7 +87,6 @@
- result.authority_key_identifier == "44:55:66:77" - result.authority_key_identifier == "44:55:66:77"
- result.authority_cert_issuer is none - result.authority_cert_issuer is none
- result.authority_cert_serial_number is none - result.authority_cert_serial_number is none
when: cryptography_version.stdout is version('1.3', '>=')
- name: Get invalid certificate info - name: Get invalid certificate info
set_fact: set_fact:

View File

@@ -84,10 +84,10 @@
- "pathlen:23" - "pathlen:23"
basic_constraints_critical: true basic_constraints_critical: true
ocsp_must_staple: true ocsp_must_staple: true
subject_key_identifier: '{{ "00:11:22:33" if cryptography_version.stdout is version("1.3", ">=") else omit }}' subject_key_identifier: "00:11:22:33"
authority_key_identifier: '{{ "44:55:66:77" if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_key_identifier: "44:55:66:77"
authority_cert_issuer: '{{ value_for_authority_cert_issuer if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_issuer: '{{ value_for_authority_cert_issuer }}'
authority_cert_serial_number: '{{ 12345 if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_serial_number: 12345
vars: vars:
value_for_authority_cert_issuer: value_for_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
@@ -113,8 +113,8 @@
- "IP:DEAD:BEEF::1" - "IP:DEAD:BEEF::1"
basic_constraints: basic_constraints:
- "CA:FALSE" - "CA:FALSE"
authority_cert_issuer: '{{ value_for_authority_cert_issuer if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_issuer: '{{ value_for_authority_cert_issuer }}'
authority_cert_serial_number: '{{ 12345 if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_serial_number: 12345
vars: vars:
value_for_authority_cert_issuer: value_for_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
@@ -125,8 +125,8 @@
path: '{{ remote_tmp_dir }}/csr_4.csr' path: '{{ remote_tmp_dir }}/csr_4.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
useCommonNameForSAN: false useCommonNameForSAN: false
authority_key_identifier: '{{ "44:55:66:77" if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_key_identifier: "44:55:66:77"
- name: Running tests - name: Running tests
include_tasks: impl.yml include_tasks: impl.yml
when: cryptography_version.stdout is version('1.3', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -39,4 +39,4 @@
- name: Running tests - name: Running tests
include_tasks: impl.yml include_tasks: impl.yml
when: cryptography_version.stdout is version('1.2.3', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -44,4 +44,4 @@
- name: Running tests - name: Running tests
include_tasks: impl.yml include_tasks: impl.yml
when: cryptography_version.stdout is version('1.2.3', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -25,8 +25,8 @@
- result.public_key_data.size == (default_rsa_key_size_certificates | int) - result.public_key_data.size == (default_rsa_key_size_certificates | int)
- "result.subject_alt_name == [ - "result.subject_alt_name == [
'DNS:www.ansible.com', 'DNS:www.ansible.com',
'DNS:' ~ ('öç' if cryptography_version.stdout is version('2.1', '<') else 'xn--7ca3a') ~ '.com', 'DNS:xn--7ca3a.com',
'DNS:' ~ ('www.öç' if cryptography_version.stdout is version('2.1', '<') else 'xn--74h') ~ '.com', 'DNS:xn--74h.com',
'IP:1.2.3.4', 'IP:1.2.3.4',
'IP:::1', 'IP:::1',
'email:test@example.org', 'email:test@example.org',
@@ -35,7 +35,7 @@
- "result_idna.subject_alt_name == [ - "result_idna.subject_alt_name == [
'DNS:www.ansible.com', 'DNS:www.ansible.com',
'DNS:xn--7ca3a.com', 'DNS:xn--7ca3a.com',
'DNS:' ~ ('www.xn--7ca3a' if cryptography_version.stdout is version('2.1', '<') else 'xn--74h') ~ '.com', 'DNS:xn--74h.com',
'IP:1.2.3.4', 'IP:1.2.3.4',
'IP:::1', 'IP:::1',
'email:test@example.org', 'email:test@example.org',
@@ -44,7 +44,7 @@
- "result_unicode.subject_alt_name == [ - "result_unicode.subject_alt_name == [
'DNS:www.ansible.com', 'DNS:www.ansible.com',
'DNS:öç.com', 'DNS:öç.com',
'DNS:' ~ ('www.öç' if cryptography_version.stdout is version('2.1', '<') else '☺') ~ '.com', 'DNS:.com',
'IP:1.2.3.4', 'IP:1.2.3.4',
'IP:::1', 'IP:::1',
'email:test@example.org', 'email:test@example.org',
@@ -60,8 +60,6 @@
- result.extensions_by_oid['2.5.29.17'].critical == false - result.extensions_by_oid['2.5.29.17'].critical == false
- > - >
result.extensions_by_oid['2.5.29.17'].value == ( result.extensions_by_oid['2.5.29.17'].value == (
'MIGCgg93d3cuYW5zaWJsZS5jb22CDXhuLS03Y2EzYS5jb22CEXd3dy54bi0tN2NhM2EuY29thwQBAgMEhxAAAAAAAAAAAAAAAAAAAAABgRB0ZXN0QGV4YW1wbGUub3JnhiNodHRwczovL2V4YW1wbGUub3JnL3Rlc3QvaW5kZXguaHRtbA=='
if cryptography_version.stdout is version('2.1', '<') else
'MHyCD3d3dy5hbnNpYmxlLmNvbYINeG4tLTdjYTNhLmNvbYILeG4tLTc0aC5jb22HBAECAwSHEAAAAAAAAAAAAAAAAAAAAAGBEHRlc3RAZXhhbXBsZS5vcmeGI2h0dHBzOi8vZXhhbXBsZS5vcmcvdGVzdC9pbmRleC5odG1s' 'MHyCD3d3dy5hbnNpYmxlLmNvbYINeG4tLTdjYTNhLmNvbYILeG4tLTc0aC5jb22HBAECAwSHEAAAAAAAAAAAAAAAAAAAAAGBEHRlc3RAZXhhbXBsZS5vcmeGI2h0dHBzOi8vZXhhbXBsZS5vcmcvdGVzdC9pbmRleC5odG1s'
) )
# Basic Constraints # Basic Constraints
@@ -86,7 +84,6 @@
expected_authority_cert_issuer: expected_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
- "IP:1.2.3.4" - "IP:1.2.3.4"
when: cryptography_version.stdout is version('1.3', '>=')
- name: Get certificate info - name: Get certificate info
set_fact: set_fact:
@@ -108,7 +105,6 @@
expected_authority_cert_issuer: expected_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
- "IP:1.2.3.4" - "IP:1.2.3.4"
when: cryptography_version.stdout is version('1.3', '>=')
- name: Get certificate info - name: Get certificate info
set_fact: set_fact:
@@ -121,7 +117,6 @@
- result.authority_key_identifier == "44:55:66:77" - result.authority_key_identifier == "44:55:66:77"
- result.authority_cert_issuer is none - result.authority_cert_issuer is none
- result.authority_cert_serial_number is none - result.authority_cert_serial_number is none
when: cryptography_version.stdout is version('1.3', '>=')
- name: Get certificate info for packaged cert 1 - name: Get certificate info for packaged cert 1
set_fact: set_fact:

View File

@@ -76,8 +76,7 @@
subject_alt_name: subject_alt_name:
- "DNS:www.ansible.com" - "DNS:www.ansible.com"
- "DNS:öç.com" - "DNS:öç.com"
# cryptography < 2.1 cannot handle certain Unicode characters - "DNS:☺.com"
- "DNS:{{ 'www.öç' if cryptography_version.stdout is version('2.1', '<') else '☺' }}.com"
- "IP:1.2.3.4" - "IP:1.2.3.4"
- "IP:::1" - "IP:::1"
- "email:test@example.org" - "email:test@example.org"
@@ -87,10 +86,10 @@
- "pathlen:23" - "pathlen:23"
basic_constraints_critical: true basic_constraints_critical: true
ocsp_must_staple: true ocsp_must_staple: true
subject_key_identifier: '{{ "00:11:22:33" if cryptography_version.stdout is version("1.3", ">=") else omit }}' subject_key_identifier: "00:11:22:33"
authority_key_identifier: '{{ "44:55:66:77" if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_key_identifier: "44:55:66:77"
authority_cert_issuer: '{{ value_for_authority_cert_issuer if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_issuer: "{{ value_for_authority_cert_issuer }}"
authority_cert_serial_number: '{{ 12345 if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_serial_number: 12345
vars: vars:
value_for_authority_cert_issuer: value_for_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
@@ -116,8 +115,8 @@
- "IP:DEAD:BEEF::1" - "IP:DEAD:BEEF::1"
basic_constraints: basic_constraints:
- "CA:FALSE" - "CA:FALSE"
authority_cert_issuer: '{{ value_for_authority_cert_issuer if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_issuer: '{{ value_for_authority_cert_issuer }}'
authority_cert_serial_number: '{{ 12345 if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_serial_number: 12345
vars: vars:
value_for_authority_cert_issuer: value_for_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
@@ -128,7 +127,7 @@
path: '{{ remote_tmp_dir }}/csr_4.csr' path: '{{ remote_tmp_dir }}/csr_4.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
useCommonNameForSAN: false useCommonNameForSAN: false
authority_key_identifier: '{{ "44:55:66:77" if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_key_identifier: "44:55:66:77"
- name: Generate selfsigned certificates - name: Generate selfsigned certificates
x509_certificate: x509_certificate:
@@ -147,4 +146,4 @@
- name: Running tests - name: Running tests
include_tasks: impl.yml include_tasks: impl.yml
when: cryptography_version.stdout is version('1.6', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -94,13 +94,6 @@
src: "{{ remote_tmp_dir }}/ca-crl1.crl" src: "{{ remote_tmp_dir }}/ca-crl1.crl"
register: content register: content
- name: Retrieve CRL 1 infos from DER (raw bytes)
set_fact:
crl_1_info_4: >-
{{ content.content | b64decode | community.crypto.x509_crl_info }}
# Ansible 2.9 and ansible-base 2.10 on Python 2 mangle bytes, so do not run this on these versions
when: ansible_version.string is version('2.11', '>=') or ansible_python.version.major > 2
- name: Retrieve CRL 1 infos from DER (Base64 encoded) - name: Retrieve CRL 1 infos from DER (Base64 encoded)
set_fact: set_fact:
crl_1_info_5: >- crl_1_info_5: >-
@@ -109,9 +102,7 @@
- name: Validate CRL 1 - name: Validate CRL 1
assert: assert:
that: that:
- crl_1_info_4 is not defined or crl_1_info_4.format == 'der'
- crl_1_info_5.format == 'der' - crl_1_info_5.format == 'der'
- crl_1_info_4 is not defined or crl_1_info_4 == crl_1_info_5
- name: Create CRL 2 - name: Create CRL 2
x509_crl: x509_crl:
@@ -195,22 +186,15 @@
revoked_certificates: revoked_certificates:
- serial_number: 1234 - serial_number: 1234
revocation_date: 20191001000000Z revocation_date: 20191001000000Z
# * cryptography < 2.1 strips username and password from URIs. To avoid problems, we do
# not pass usernames and passwords for URIs when the cryptography version is < 2.1.
# * Python 3.5 before 3.5.8 rc 1 has a bug in urllib.parse.urlparse() that results in an
# error if a Unicode netloc has a username or password included.
# (https://github.com/ansible-collections/community.crypto/pull/436#issuecomment-1101737134)
# This affects the Python 3.5 included in Ansible 2.9's default test container; to avoid
# this, we also do not pass usernames and passwords for Python 3.5.
issuer: issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
- "DNS:ffóò.ḃâŗ.çøṁ" - "DNS:ffóò.ḃâŗ.çøṁ"
- "email:foo@ḃâŗ.çøṁ" - "email:foo@ḃâŗ.çøṁ"
- "URI:https://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'admin:hunter2@' }}ffóò.ḃâŗ.çøṁ/baz?foo=bar" - "URI:https://admin:hunter2@ffóò.ḃâŗ.çøṁ/baz?foo=bar"
- "URI:https://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'goo@' }}www.straße.de" - "URI:https://goo@www.straße.de"
- "URI:https://straße.de:8080" - "URI:https://straße.de:8080"
- "URI:http://gefäß.org" - "URI:http://gefäß.org"
- "URI:http://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'a:b@' }}ä:1" - "URI:http://a:b@ä:1"
issuer_critical: true issuer_critical: true
register: crl_3 register: crl_3
@@ -229,11 +213,11 @@
- "DNS:ca.example.org" - "DNS:ca.example.org"
- "DNS:xn--ff-3jad.xn--2ca8uh37e.xn--7ca8a981n" - "DNS:xn--ff-3jad.xn--2ca8uh37e.xn--7ca8a981n"
- "email:foo@xn--2ca8uh37e.xn--7ca8a981n" - "email:foo@xn--2ca8uh37e.xn--7ca8a981n"
- "URI:https://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'admin:hunter2@' }}xn--ff-3jad.xn--2ca8uh37e.xn--7ca8a981n/baz?foo=bar" - "URI:https://admin:hunter2@xn--ff-3jad.xn--2ca8uh37e.xn--7ca8a981n/baz?foo=bar"
- "URI:https://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'goo@' }}www.xn--strae-oqa.de" - "URI:https://goo@www.xn--strae-oqa.de"
- "URI:https://xn--strae-oqa.de:8080" - "URI:https://xn--strae-oqa.de:8080"
- "URI:http://xn--gef-7kay.org" - "URI:http://xn--gef-7kay.org"
- "URI:http://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'a:b@' }}xn--4ca:1" - "URI:http://a:b@xn--4ca:1"
issuer_critical: true issuer_critical: true
ignore_timestamps: true ignore_timestamps: true
name_encoding: idna name_encoding: idna
@@ -254,11 +238,11 @@
- "DNS:ca.example.org" - "DNS:ca.example.org"
- "DNS:ffóò.ḃâŗ.çøṁ" - "DNS:ffóò.ḃâŗ.çøṁ"
- "email:foo@ḃâŗ.çøṁ" - "email:foo@ḃâŗ.çøṁ"
- "URI:https://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'admin:hunter2@' }}ffóò.ḃâŗ.çøṁ/baz?foo=bar" - "URI:https://admin:hunter2@ffóò.ḃâŗ.çøṁ/baz?foo=bar"
- "URI:https://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'goo@' }}www.straße.de" - "URI:https://goo@www.straße.de"
- "URI:https://straße.de:8080" - "URI:https://straße.de:8080"
- "URI:http://gefäß.org" - "URI:http://gefäß.org"
- "URI:http://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'a:b@' }}ä:1" - "URI:http://a:b@ä:1"
issuer_critical: true issuer_critical: true
ignore_timestamps: true ignore_timestamps: true
name_encoding: unicode name_encoding: unicode

View File

@@ -88,4 +88,4 @@
- name: Running tests - name: Running tests
include_tasks: impl.yml include_tasks: impl.yml
when: cryptography_version.stdout is version('1.2', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -37,7 +37,7 @@
that: that:
- result is success or skip_tests - result is success or skip_tests
when: cryptography_version.stdout is version('1.6', '>=') when: cryptography_version.stdout is version('3.4', '>=')
- block: - block:

View File

@@ -19,7 +19,7 @@
- set_fact: - set_fact:
backends: "{{ backends + ['cryptography'] }}" backends: "{{ backends + ['cryptography'] }}"
when: cryptography_version.stdout is version('3.0', '>=') and bcrypt_version.stdout is version('3.1.5', '>=') when: cryptography_version.stdout is version('3.4', '>=') and bcrypt_version.stdout is version('3.1.5', '>=')
- include_tasks: ../tests/core.yml - include_tasks: ../tests/core.yml
loop: "{{ backends }}" loop: "{{ backends }}"
@@ -47,4 +47,4 @@
loop_var: backend loop_var: backend
- include_tasks: ../tests/cryptography_backend.yml - include_tasks: ../tests/cryptography_backend.yml
when: cryptography_version.stdout is version('3.0', '>=') and bcrypt_version.stdout is version('3.1.5', '>=') when: cryptography_version.stdout is version('3.4', '>=') and bcrypt_version.stdout is version('3.1.5', '>=')

View File

@@ -884,7 +884,7 @@
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
register: everything_info register: everything_info
- name: "({{ select_crypto_backend }}) Ed25519 and Ed448 tests (for cryptography >= 2.6)" - name: "({{ select_crypto_backend }}) Ed25519 and Ed448 tests"
block: block:
- name: "({{ select_crypto_backend }}) Generate privatekeys" - name: "({{ select_crypto_backend }}) Generate privatekeys"
openssl_privatekey: openssl_privatekey:
@@ -926,9 +926,9 @@
register: generate_csr_ed25519_ed448_idempotent register: generate_csr_ed25519_ed448_idempotent
ignore_errors: true ignore_errors: true
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('2.6', '>=') when: select_crypto_backend == 'cryptography'
- name: "({{ select_crypto_backend }}) CRL distribution endpoints (for cryptography >= 1.6)" - name: "({{ select_crypto_backend }}) CRL distribution endpoints"
block: block:
- name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints" - name: "({{ select_crypto_backend }}) Create CSR with CRL distribution endpoints"
openssl_csr: openssl_csr:
@@ -1015,4 +1015,4 @@
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
register: crl_distribution_endpoints_5 register: crl_distribution_endpoints_5
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.6', '>=') when: select_crypto_backend == 'cryptography'

View File

@@ -29,4 +29,4 @@
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('1.3', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -77,15 +77,6 @@
- generate_csr_invalid_san is failed - generate_csr_invalid_san is failed
- "'Subject Alternative Name' in generate_csr_invalid_san.msg" - "'Subject Alternative Name' in generate_csr_invalid_san.msg"
- name: "({{ select_crypto_backend }}) Validate invalid SAN (2/2)"
# Note that modern cryptography versions simply accept this name.
# The error has been observed with cryptography 1.7.2 and 1.9, but not with 2.3 and newer.
assert:
that:
- generate_csr_invalid_san_2 is failed
- "'The label system:kube-controller-manager is not a valid A-label' in generate_csr_invalid_san_2.msg"
when: cryptography_version.stdout is version('2.0', '<')
- name: "({{ select_crypto_backend }}) Validate OCSP Must Staple CSR (test - everything)" - name: "({{ select_crypto_backend }}) Validate OCSP Must Staple CSR (test - everything)"
shell: "{{ openssl_binary }} req -noout -in {{ remote_tmp_dir }}/csr_ocsp.csr -text" shell: "{{ openssl_binary }} req -noout -in {{ remote_tmp_dir }}/csr_ocsp.csr -text"
register: csr_ocsp register: csr_ocsp
@@ -313,18 +304,7 @@
"IP:::1:0:0/112", "IP:::1:0:0/112",
] ]
- name: "({{ select_crypto_backend }}) Verify Ed25519 and Ed448 tests (for cryptography >= 2.6, < 2.8)" - name: "({{ select_crypto_backend }}) Verify Ed25519 and Ed448 tests"
assert:
that:
- generate_csr_ed25519_ed448.results[0] is failed
- generate_csr_ed25519_ed448.results[1] is failed
- generate_csr_ed25519_ed448.results[0].msg == 'Signing with Ed25519 and Ed448 keys requires cryptography 2.8 or newer.'
- generate_csr_ed25519_ed448.results[1].msg == 'Signing with Ed25519 and Ed448 keys requires cryptography 2.8 or newer.'
- generate_csr_ed25519_ed448_idempotent.results[0] is failed
- generate_csr_ed25519_ed448_idempotent.results[1] is failed
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('2.6', '>=') and cryptography_version.stdout is version('2.8', '<') and generate_csr_ed25519_ed448_privatekey is not failed
- name: "({{ select_crypto_backend }}) Verify Ed25519 and Ed448 tests (for cryptography >= 2.8)"
assert: assert:
that: that:
- generate_csr_ed25519_ed448 is succeeded - generate_csr_ed25519_ed448 is succeeded
@@ -333,9 +313,9 @@
- generate_csr_ed25519_ed448_idempotent is succeeded - generate_csr_ed25519_ed448_idempotent is succeeded
- generate_csr_ed25519_ed448_idempotent.results[0] is not changed - generate_csr_ed25519_ed448_idempotent.results[0] is not changed
- generate_csr_ed25519_ed448_idempotent.results[1] is not changed - generate_csr_ed25519_ed448_idempotent.results[1] is not changed
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('2.8', '>=') and generate_csr_ed25519_ed448_privatekey is not failed when: select_crypto_backend == 'cryptography' and generate_csr_ed25519_ed448_privatekey is not failed
- name: "({{ select_crypto_backend }}) Verify CRL distribution endpoints (for cryptography >= 1.6)" - name: "({{ select_crypto_backend }}) Verify CRL distribution endpoints"
assert: assert:
that: that:
- crl_distribution_endpoints_1 is changed - crl_distribution_endpoints_1 is changed
@@ -343,4 +323,4 @@
- crl_distribution_endpoints_3 is changed - crl_distribution_endpoints_3 is changed
- crl_distribution_endpoints_4 is changed - crl_distribution_endpoints_4 is changed
- crl_distribution_endpoints_5 is changed - crl_distribution_endpoints_5 is changed
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.6', '>=') when: select_crypto_backend == 'cryptography'

View File

@@ -41,7 +41,7 @@
- result.extensions_by_oid['2.5.29.15'].critical == true - result.extensions_by_oid['2.5.29.15'].critical == true
- result.extensions_by_oid['2.5.29.15'].value in ['AwMA/4A=', 'AwMH/4A='] - result.extensions_by_oid['2.5.29.15'].value in ['AwMA/4A=', 'AwMH/4A=']
# Subject Alternative Names # Subject Alternative Names
- result.subject_alt_name[1] == ("DNS:âņsïbłè.com" if cryptography_version.stdout is version('2.1', '<') else "DNS:xn--sb-oia0a7a53bya.com") - result.subject_alt_name[1] == "DNS:xn--sb-oia0a7a53bya.com"
- result_unicode.subject_alt_name[1] == "DNS:âņsïbłè.com" - result_unicode.subject_alt_name[1] == "DNS:âņsïbłè.com"
- result_idna.subject_alt_name[1] == "DNS:xn--sb-oia0a7a53bya.com" - result_idna.subject_alt_name[1] == "DNS:xn--sb-oia0a7a53bya.com"
- result.extensions_by_oid['2.5.29.17'].critical == false - result.extensions_by_oid['2.5.29.17'].critical == false
@@ -68,7 +68,6 @@
expected_authority_cert_issuer: expected_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
- "IP:1.2.3.4" - "IP:1.2.3.4"
when: cryptography_version.stdout is version('1.3', '>=')
- name: "({{ select_crypto_backend }}) Read CSR" - name: "({{ select_crypto_backend }}) Read CSR"
slurp: slurp:
@@ -111,7 +110,6 @@
expected_authority_cert_issuer: expected_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
- "IP:1.2.3.4" - "IP:1.2.3.4"
when: cryptography_version.stdout is version('1.3', '>=')
- name: "({{ select_crypto_backend }}) Get CSR info" - name: "({{ select_crypto_backend }}) Get CSR info"
openssl_csr_info: openssl_csr_info:
@@ -125,4 +123,3 @@
- result.authority_key_identifier == "44:55:66:77" - result.authority_key_identifier == "44:55:66:77"
- result.authority_cert_issuer is none - result.authority_cert_issuer is none
- result.authority_cert_serial_number is none - result.authority_cert_serial_number is none
when: cryptography_version.stdout is version('1.3', '>=')

View File

@@ -85,10 +85,10 @@
- "pathlen:23" - "pathlen:23"
basic_constraints_critical: true basic_constraints_critical: true
ocsp_must_staple: true ocsp_must_staple: true
subject_key_identifier: '{{ "00:11:22:33" if cryptography_version.stdout is version("1.3", ">=") else omit }}' subject_key_identifier: "00:11:22:33"
authority_key_identifier: '{{ "44:55:66:77" if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_key_identifier: "44:55:66:77"
authority_cert_issuer: '{{ value_for_authority_cert_issuer if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_issuer: '{{ value_for_authority_cert_issuer }}'
authority_cert_serial_number: '{{ 12345 if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_serial_number: 12345
vars: vars:
value_for_authority_cert_issuer: value_for_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
@@ -114,8 +114,8 @@
- "IP:DEAD:BEEF::1" - "IP:DEAD:BEEF::1"
basic_constraints: basic_constraints:
- "CA:FALSE" - "CA:FALSE"
authority_cert_issuer: '{{ value_for_authority_cert_issuer if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_issuer: '{{ value_for_authority_cert_issuer }}'
authority_cert_serial_number: '{{ 12345 if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_serial_number: 12345
vars: vars:
value_for_authority_cert_issuer: value_for_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
@@ -126,10 +126,10 @@
path: '{{ remote_tmp_dir }}/csr_4.csr' path: '{{ remote_tmp_dir }}/csr_4.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
useCommonNameForSAN: false useCommonNameForSAN: false
authority_key_identifier: '{{ "44:55:66:77" if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_key_identifier: "44:55:66:77"
- name: Running tests with cryptography backend - name: Running tests with cryptography backend
include_tasks: impl.yml include_tasks: impl.yml
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('1.3', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -24,4 +24,4 @@
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('1.3', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -44,4 +44,4 @@
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('2.0', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -68,7 +68,7 @@
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('3.0', '>=') when: cryptography_version.stdout is version('3.4', '>=')
when: >- when: >-
cryptography_version.stdout is version('3.0', '>=') cryptography_version.stdout is version('3.4', '>=')

View File

@@ -534,7 +534,7 @@
- privatekey_fmt_2_step_6.privatekey == (slurp.content | b64decode) - privatekey_fmt_2_step_6.privatekey == (slurp.content | b64decode)
when: privatekey_fmt_2_step_1 is not failed when: privatekey_fmt_2_step_1 is not failed
when: 'select_crypto_backend == "cryptography" and cryptography_version.stdout is version("2.6", ">=")' when: select_crypto_backend == "cryptography"
# Test regenerate option # Test regenerate option
@@ -871,4 +871,4 @@
- result.results[0].fingerprint == result.results[2].fingerprint - result.results[0].fingerprint == result.results[2].fingerprint
- result.results[0].fingerprint == result.results[3].fingerprint - result.results[0].fingerprint == result.results[3].fingerprint
- result.results[0].fingerprint != result.results[4].fingerprint - result.results[0].fingerprint != result.results[4].fingerprint
when: 'select_crypto_backend == "cryptography" and cryptography_version.stdout is version("2.6", ">=")' when: select_crypto_backend == "cryptography"

View File

@@ -50,4 +50,4 @@
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('0.5', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -213,7 +213,7 @@
- system_potentially_has_no_algorithm_support - system_potentially_has_no_algorithm_support
- privatekey_fmt_2_step_1 is failed - privatekey_fmt_2_step_1 is failed
- "'Cryptography backend does not support the algorithm required for ' in privatekey_fmt_2_step_1.msg" - "'Cryptography backend does not support the algorithm required for ' in privatekey_fmt_2_step_1.msg"
when: 'select_crypto_backend == "cryptography" and cryptography_version.stdout is version("2.6", ">=") and privatekey_fmt_2_step_1 is failed' when: 'select_crypto_backend == "cryptography" and privatekey_fmt_2_step_1 is failed'
- name: "({{ select_crypto_backend }}) Validate format 2" - name: "({{ select_crypto_backend }}) Validate format 2"
assert: assert:
@@ -224,4 +224,4 @@
- privatekey_fmt_2_step_4 is succeeded and privatekey_fmt_2_step_4 is not changed - privatekey_fmt_2_step_4 is succeeded and privatekey_fmt_2_step_4 is not changed
- privatekey_fmt_2_step_5 is succeeded and privatekey_fmt_2_step_5 is not changed - privatekey_fmt_2_step_5 is succeeded and privatekey_fmt_2_step_5 is not changed
- privatekey_fmt_2_step_6 is succeeded and privatekey_fmt_2_step_6 is changed - privatekey_fmt_2_step_6 is succeeded and privatekey_fmt_2_step_6 is changed
when: 'select_crypto_backend == "cryptography" and cryptography_version.stdout is version("2.6", ">=") and privatekey_fmt_2_step_1 is not failed' when: 'select_crypto_backend == "cryptography" and privatekey_fmt_2_step_1 is not failed'

View File

@@ -331,60 +331,58 @@
- convert_idem is not changed - convert_idem is not changed
- convert_file_info is not changed - convert_file_info is not changed
- when: supports_x25519 | bool - name: Convert (change format to raw, check mode)
block: openssl_privatekey_convert:
- name: Convert (change format to raw, check mode) src_path: '{{ remote_tmp_dir }}/privatekey_x25519.pem'
openssl_privatekey_convert: dest_path: '{{ remote_tmp_dir }}/output_3.pem'
src_path: '{{ remote_tmp_dir }}/privatekey_x25519.pem' format: raw
dest_path: '{{ remote_tmp_dir }}/output_3.pem' # select_crypto_backend: '{{ select_crypto_backend }}'
format: raw register: convert_not_idem_check
# select_crypto_backend: '{{ select_crypto_backend }}' check_mode: true
register: convert_not_idem_check
check_mode: true
- name: Convert (change format to raw) - name: Convert (change format to raw)
openssl_privatekey_convert: openssl_privatekey_convert:
src_path: '{{ remote_tmp_dir }}/privatekey_x25519.pem' src_path: '{{ remote_tmp_dir }}/privatekey_x25519.pem'
dest_path: '{{ remote_tmp_dir }}/output_3.pem' dest_path: '{{ remote_tmp_dir }}/output_3.pem'
format: raw format: raw
# select_crypto_backend: '{{ select_crypto_backend }}' # select_crypto_backend: '{{ select_crypto_backend }}'
register: convert_not_idem register: convert_not_idem
- assert: - assert:
that: that:
- convert_not_idem_check is changed - convert_not_idem_check is changed
- convert_not_idem is changed - convert_not_idem is changed
- name: "({{ select_crypto_backend }}) Collect file information" - name: "({{ select_crypto_backend }}) Collect file information"
community.internal_test_tools.files_collect: community.internal_test_tools.files_collect:
files: files:
- path: '{{ remote_tmp_dir }}/output_3.pem' - path: '{{ remote_tmp_dir }}/output_3.pem'
register: convert_file_info_data register: convert_file_info_data
- name: Convert (idempotent, check mode) - name: Convert (idempotent, check mode)
openssl_privatekey_convert: openssl_privatekey_convert:
src_path: '{{ remote_tmp_dir }}/privatekey_x25519.pem' src_path: '{{ remote_tmp_dir }}/privatekey_x25519.pem'
dest_path: '{{ remote_tmp_dir }}/output_3.pem' dest_path: '{{ remote_tmp_dir }}/output_3.pem'
format: raw format: raw
# select_crypto_backend: '{{ select_crypto_backend }}' # select_crypto_backend: '{{ select_crypto_backend }}'
register: convert_idem_check register: convert_idem_check
check_mode: true check_mode: true
- name: Convert (idempotent) - name: Convert (idempotent)
openssl_privatekey_convert: openssl_privatekey_convert:
src_path: '{{ remote_tmp_dir }}/privatekey_x25519.pem' src_path: '{{ remote_tmp_dir }}/privatekey_x25519.pem'
dest_path: '{{ remote_tmp_dir }}/output_3.pem' dest_path: '{{ remote_tmp_dir }}/output_3.pem'
format: raw format: raw
# select_crypto_backend: '{{ select_crypto_backend }}' # select_crypto_backend: '{{ select_crypto_backend }}'
register: convert_idem register: convert_idem
- name: "({{ select_crypto_backend }}) Check whether file changed" - name: "({{ select_crypto_backend }}) Check whether file changed"
community.internal_test_tools.files_diff: community.internal_test_tools.files_diff:
state: '{{ convert_file_info_data }}' state: '{{ convert_file_info_data }}'
register: convert_file_info register: convert_file_info
- assert: - assert:
that: that:
- convert_idem_check is not changed - convert_idem_check is not changed
- convert_idem is not changed - convert_idem is not changed
- convert_file_info is not changed - convert_file_info is not changed

View File

@@ -10,11 +10,9 @@
- name: Determine capabilities - name: Determine capabilities
set_fact: set_fact:
supports_x25519: '{{ cryptography_version.stdout is version("2.5", ">=") }}'
supports_ed25519: >- supports_ed25519: >-
{{ {{
cryptography_version.stdout is version("2.6", ">=") not (
and not (
ansible_os_family == "FreeBSD" and ansible_os_family == "FreeBSD" and
ansible_facts.distribution_version is version("12.1", ">=") and ansible_facts.distribution_version is version("12.1", ">=") and
ansible_facts.distribution_version is version("12.2", "<") ansible_facts.distribution_version is version("12.2", "<")
@@ -45,7 +43,6 @@
format: pkcs8 format: pkcs8
type: X25519 type: X25519
size: '{{ default_rsa_key_size }}' size: '{{ default_rsa_key_size }}'
condition: '{{ supports_x25519 }}'
- name: Run module with backend autodetection - name: Run module with backend autodetection
openssl_privatekey_convert: openssl_privatekey_convert:
@@ -61,4 +58,4 @@
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('1.2.3', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -43,4 +43,4 @@
include_tasks: impl.yml include_tasks: impl.yml
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('1.2.3', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -18,4 +18,4 @@
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('0.5', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -56,7 +56,7 @@
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
format: OpenSSH format: OpenSSH
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.4.0', '>=') when: select_crypto_backend == 'cryptography'
- name: "({{ select_crypto_backend }}) Generate publickey - OpenSSH format - test idempotence (issue 33256)" - name: "({{ select_crypto_backend }}) Generate publickey - OpenSSH format - test idempotence (issue 33256)"
openssl_publickey: openssl_publickey:
@@ -64,7 +64,7 @@
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
format: OpenSSH format: OpenSSH
select_crypto_backend: '{{ select_crypto_backend }}' select_crypto_backend: '{{ select_crypto_backend }}'
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.4.0', '>=') when: select_crypto_backend == 'cryptography'
register: publickey_ssh_idempotence register: publickey_ssh_idempotence
- name: "({{ select_crypto_backend }}) Generate publickey2 - standard" - name: "({{ select_crypto_backend }}) Generate publickey2 - standard"

View File

@@ -28,4 +28,4 @@
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('1.2.3', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -32,25 +32,25 @@
- name: "({{ select_crypto_backend }}) Validate public key - OpenSSH format (test - privatekey's publickey)" - name: "({{ select_crypto_backend }}) Validate public key - OpenSSH format (test - privatekey's publickey)"
shell: 'ssh-keygen -y -f {{ remote_tmp_dir }}/privatekey.pem' shell: 'ssh-keygen -y -f {{ remote_tmp_dir }}/privatekey.pem'
register: privatekey_publickey register: privatekey_publickey
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.4.0', '>=') when: select_crypto_backend == 'cryptography'
- name: "({{ select_crypto_backend }}) Validate public key - OpenSSH format (test - publickey)" - name: "({{ select_crypto_backend }}) Validate public key - OpenSSH format (test - publickey)"
slurp: slurp:
src: '{{ remote_tmp_dir }}/publickey-ssh.pub' src: '{{ remote_tmp_dir }}/publickey-ssh.pub'
register: publickey register: publickey
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.4.0', '>=') when: select_crypto_backend == 'cryptography'
- name: "({{ select_crypto_backend }}) Validate public key - OpenSSH format (assert)" - name: "({{ select_crypto_backend }}) Validate public key - OpenSSH format (assert)"
assert: assert:
that: that:
- privatekey_publickey.stdout == publickey.content | b64decode - privatekey_publickey.stdout == publickey.content | b64decode
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.4.0', '>=') when: select_crypto_backend == 'cryptography'
- name: "({{ select_crypto_backend }}) Validate public key - OpenSSH format - test idempotence (issue 33256)" - name: "({{ select_crypto_backend }}) Validate public key - OpenSSH format - test idempotence (issue 33256)"
assert: assert:
that: that:
- publickey_ssh_idempotence is not changed - publickey_ssh_idempotence is not changed
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('1.4.0', '>=') when: select_crypto_backend == 'cryptography'
- name: "({{ select_crypto_backend }}) Validate publickey2 (test - Ensure key has been removed)" - name: "({{ select_crypto_backend }}) Validate publickey2 (test - Ensure key has been removed)"
stat: stat:

View File

@@ -46,4 +46,4 @@
include_tasks: impl.yml include_tasks: impl.yml
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('1.2.3', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -26,18 +26,15 @@
- name: Add cryptography backend - name: Add cryptography backend
set_fact: set_fact:
backends: "{{ backends + [ { 'backend': 'cryptography' } ] }}" backends: "{{ backends + [ { 'backend': 'cryptography' } ] }}"
when: cryptography_version.stdout is version('1.4', '>=')
- name: Add RSA tests - name: Add RSA tests
set_fact: set_fact:
key_types: "{{ key_types + [ { 'type': 'RSA', 'size': default_rsa_key_size } ] }}" key_types: "{{ key_types + [ { 'type': 'RSA', 'size': default_rsa_key_size } ] }}"
when: cryptography_version.stdout is version('1.4', '>=')
- name: Add DSA + ECDSA tests - name: Add DSA + ECDSA tests
set_fact: set_fact:
key_types: "{{ key_types + [ { 'type': 'DSA', 'size': 2048 }, { 'type': 'ECC', 'curve': 'secp256r1' } ] }}" key_types: "{{ key_types + [ { 'type': 'DSA', 'size': 2048 }, { 'type': 'ECC', 'curve': 'secp256r1' } ] }}"
when: when:
- cryptography_version.stdout is version('1.5', '>=')
# FreeBSD 11 fails on secp256r1 keys # FreeBSD 11 fails on secp256r1 keys
- not ansible_os_family == 'FreeBSD' - not ansible_os_family == 'FreeBSD'
@@ -45,8 +42,6 @@
set_fact: set_fact:
key_types: "{{ key_types + [ { 'type': 'Ed25519' }, { 'type': 'Ed448' } ] }}" key_types: "{{ key_types + [ { 'type': 'Ed25519' }, { 'type': 'Ed448' } ] }}"
when: when:
# The module under tests works with >= 2.6, but we also need to be able to create a certificate which requires 2.8
- cryptography_version.stdout is version('2.8', '>=')
# FreeBSD doesn't have support for Ed448/25519 # FreeBSD doesn't have support for Ed448/25519
- not ansible_os_family == 'FreeBSD' - not ansible_os_family == 'FreeBSD'

View File

@@ -12,16 +12,10 @@
pkg_mgr: community.general.pkgng pkg_mgr: community.general.pkgng
ansible_pkg_mgr: community.general.pkgng ansible_pkg_mgr: community.general.pkgng
cacheable: true cacheable: true
when: ansible_os_family == 'FreeBSD' and ansible_version.string is version('2.10', '>=') when: ansible_os_family == 'FreeBSD'
- set_fact: - set_fact:
pkg_mgr: community.general.zypper pkg_mgr: community.general.zypper
ansible_pkg_mgr: community.general.zypper ansible_pkg_mgr: community.general.zypper
cacheable: true cacheable: true
when: ansible_os_family == 'Suse' and ansible_version.string is version('2.10', '>=') when: ansible_os_family == 'Suse'
- shell:
cmd: |
sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/*.repo
sed -i 's%#baseurl=http://mirror.centos.org/%baseurl=https://vault.centos.org/%g' /etc/yum.repos.d/*.repo
when: ansible_distribution in 'CentOS' and ansible_distribution_major_version == '7'

View File

@@ -141,4 +141,4 @@
- name: Running tests - name: Running tests
include_tasks: impl.yml include_tasks: impl.yml
# Make x509_certificate module happy # Make x509_certificate module happy
when: cryptography_version.stdout is version('1.6', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -12,4 +12,4 @@
include_tasks: impl.yml include_tasks: impl.yml
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('1.6', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -658,6 +658,6 @@
register: ownca_certificate_ed25519_ed448_2_idempotence register: ownca_certificate_ed25519_ed448_2_idempotence
ignore_errors: true ignore_errors: true
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('2.6', '>=') when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('3.4', '>=')
- import_tasks: ../tests/validate_ownca.yml - import_tasks: ../tests/validate_ownca.yml

View File

@@ -480,6 +480,6 @@
register: selfsigned_certificate_ed25519_ed448_idempotence register: selfsigned_certificate_ed25519_ed448_idempotence
ignore_errors: true ignore_errors: true
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('2.6', '>=') when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('3.4', '>=')
- import_tasks: ../tests/validate_selfsigned.yml - import_tasks: ../tests/validate_selfsigned.yml

View File

@@ -165,20 +165,7 @@
- ownca_authority_key_identifier_4 is not changed - ownca_authority_key_identifier_4 is not changed
- ownca_authority_key_identifier_5 is changed - ownca_authority_key_identifier_5 is changed
- name: (OwnCA validation, {{select_crypto_backend}}) Verify Ed25519 and Ed448 tests (for cryptography >= 2.6, < 2.8) - name: (OwnCA validation, {{select_crypto_backend}}) Verify Ed25519 and Ed448 tests
assert:
that:
- ownca_certificate_ed25519_ed448.results[0] is failed
- ownca_certificate_ed25519_ed448.results[1] is failed
- ownca_certificate_ed25519_ed448_idempotence.results[0] is failed
- ownca_certificate_ed25519_ed448_idempotence.results[1] is failed
- ownca_certificate_ed25519_ed448_2.results[0] is failed
- ownca_certificate_ed25519_ed448_2.results[1] is failed
- ownca_certificate_ed25519_ed448_2_idempotence.results[0] is failed
- ownca_certificate_ed25519_ed448_2_idempotence.results[1] is failed
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('2.6', '>=') and cryptography_version.stdout is version('2.8', '<') and ownca_certificate_ed25519_ed448_privatekey is not failed
- name: (OwnCA validation, {{select_crypto_backend}}) Verify Ed25519 and Ed448 tests (for cryptography >= 2.8)
assert: assert:
that: that:
- ownca_certificate_ed25519_ed448 is succeeded - ownca_certificate_ed25519_ed448 is succeeded
@@ -193,4 +180,4 @@
- ownca_certificate_ed25519_ed448_2_idempotence is succeeded - ownca_certificate_ed25519_ed448_2_idempotence is succeeded
- ownca_certificate_ed25519_ed448_2_idempotence.results[0] is not changed - ownca_certificate_ed25519_ed448_2_idempotence.results[0] is not changed
- ownca_certificate_ed25519_ed448_2_idempotence.results[1] is not changed - ownca_certificate_ed25519_ed448_2_idempotence.results[1] is not changed
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('2.8', '>=') and ownca_certificate_ed25519_ed448_privatekey is not failed when: select_crypto_backend == 'cryptography' and ownca_certificate_ed25519_ed448_privatekey is not failed

View File

@@ -195,16 +195,7 @@
- selfsigned_subject_key_identifier_4 is not changed - selfsigned_subject_key_identifier_4 is not changed
- selfsigned_subject_key_identifier_5 is changed - selfsigned_subject_key_identifier_5 is changed
- name: (Selfsigned validation, {{select_crypto_backend}}) Verify Ed25519 and Ed448 tests (for cryptography >= 2.6, < 2.8) - name: (Selfsigned validation, {{select_crypto_backend}}) Verify Ed25519 and Ed448 tests
assert:
that:
- selfsigned_certificate_ed25519_ed448.results[0] is failed
- selfsigned_certificate_ed25519_ed448.results[1] is failed
- selfsigned_certificate_ed25519_ed448_idempotence.results[0] is failed
- selfsigned_certificate_ed25519_ed448_idempotence.results[1] is failed
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('2.6', '>=') and cryptography_version.stdout is version('2.8', '<') and selfsigned_certificate_ed25519_ed448_privatekey is not failed
- name: (Selfsigned validation, {{select_crypto_backend}}) Verify Ed25519 and Ed448 tests (for cryptography >= 2.8)
assert: assert:
that: that:
- selfsigned_certificate_ed25519_ed448 is succeeded - selfsigned_certificate_ed25519_ed448 is succeeded
@@ -213,4 +204,4 @@
- selfsigned_certificate_ed25519_ed448_idempotence is succeeded - selfsigned_certificate_ed25519_ed448_idempotence is succeeded
- selfsigned_certificate_ed25519_ed448_idempotence.results[0] is not changed - selfsigned_certificate_ed25519_ed448_idempotence.results[0] is not changed
- selfsigned_certificate_ed25519_ed448_idempotence.results[1] is not changed - selfsigned_certificate_ed25519_ed448_idempotence.results[1] is not changed
when: select_crypto_backend == 'cryptography' and cryptography_version.stdout is version('2.8', '>=') and selfsigned_certificate_ed25519_ed448_privatekey is not failed when: select_crypto_backend == 'cryptography' and selfsigned_certificate_ed25519_ed448_privatekey is not failed

View File

@@ -70,7 +70,7 @@
- "DNS:www.ansible.com" - "DNS:www.ansible.com"
- "DNS:öç.com" - "DNS:öç.com"
# cryptography < 2.1 cannot handle certain Unicode characters # cryptography < 2.1 cannot handle certain Unicode characters
- "DNS:{{ 'www.öç' if cryptography_version.stdout is version('2.1', '<') else '☺' }}.com" - "DNS:.com"
- "IP:1.2.3.4" - "IP:1.2.3.4"
- "IP:::1" - "IP:::1"
- "email:test@example.org" - "email:test@example.org"
@@ -80,10 +80,10 @@
- "pathlen:23" - "pathlen:23"
basic_constraints_critical: true basic_constraints_critical: true
ocsp_must_staple: true ocsp_must_staple: true
subject_key_identifier: '{{ "00:11:22:33" if cryptography_version.stdout is version("1.3", ">=") else omit }}' subject_key_identifier: "00:11:22:33"
authority_key_identifier: '{{ "44:55:66:77" if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_key_identifier: "44:55:66:77"
authority_cert_issuer: '{{ value_for_authority_cert_issuer if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_issuer: '{{ value_for_authority_cert_issuer }}'
authority_cert_serial_number: '{{ 12345 if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_serial_number: 12345
vars: vars:
value_for_authority_cert_issuer: value_for_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
@@ -108,8 +108,8 @@
- "IP:DEAD:BEEF::1" - "IP:DEAD:BEEF::1"
basic_constraints: basic_constraints:
- "CA:FALSE" - "CA:FALSE"
authority_cert_issuer: '{{ value_for_authority_cert_issuer if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_issuer: '{{ value_for_authority_cert_issuer }}'
authority_cert_serial_number: '{{ 12345 if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_serial_number: 12345
vars: vars:
value_for_authority_cert_issuer: value_for_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"

View File

@@ -39,8 +39,8 @@
- result.public_key_data.size == (default_rsa_key_size_certificates | int) - result.public_key_data.size == (default_rsa_key_size_certificates | int)
- "result.subject_alt_name == [ - "result.subject_alt_name == [
'DNS:www.ansible.com', 'DNS:www.ansible.com',
'DNS:' ~ ('öç' if cryptography_version.stdout is version('2.1', '<') else 'xn--7ca3a') ~ '.com', 'DNS:xn--7ca3a.com',
'DNS:' ~ ('www.öç' if cryptography_version.stdout is version('2.1', '<') else 'xn--74h') ~ '.com', 'DNS:xn--74h.com',
'IP:1.2.3.4', 'IP:1.2.3.4',
'IP:::1', 'IP:::1',
'email:test@example.org', 'email:test@example.org',
@@ -49,7 +49,7 @@
- "result_idna.subject_alt_name == [ - "result_idna.subject_alt_name == [
'DNS:www.ansible.com', 'DNS:www.ansible.com',
'DNS:xn--7ca3a.com', 'DNS:xn--7ca3a.com',
'DNS:' ~ ('www.xn--7ca3a' if cryptography_version.stdout is version('2.1', '<') else 'xn--74h') ~ '.com', 'DNS:xn--74h.com',
'IP:1.2.3.4', 'IP:1.2.3.4',
'IP:::1', 'IP:::1',
'email:test@example.org', 'email:test@example.org',
@@ -58,7 +58,7 @@
- "result_unicode.subject_alt_name == [ - "result_unicode.subject_alt_name == [
'DNS:www.ansible.com', 'DNS:www.ansible.com',
'DNS:öç.com', 'DNS:öç.com',
'DNS:' ~ ('www.öç' if cryptography_version.stdout is version('2.1', '<') else '☺') ~ '.com', 'DNS:.com',
'IP:1.2.3.4', 'IP:1.2.3.4',
'IP:::1', 'IP:::1',
'email:test@example.org', 'email:test@example.org',
@@ -74,8 +74,6 @@
- result.extensions_by_oid['2.5.29.17'].critical == false - result.extensions_by_oid['2.5.29.17'].critical == false
- > - >
result.extensions_by_oid['2.5.29.17'].value == ( result.extensions_by_oid['2.5.29.17'].value == (
'MIGCgg93d3cuYW5zaWJsZS5jb22CDXhuLS03Y2EzYS5jb22CEXd3dy54bi0tN2NhM2EuY29thwQBAgMEhxAAAAAAAAAAAAAAAAAAAAABgRB0ZXN0QGV4YW1wbGUub3JnhiNodHRwczovL2V4YW1wbGUub3JnL3Rlc3QvaW5kZXguaHRtbA=='
if cryptography_version.stdout is version('2.1', '<') else
'MHyCD3d3dy5hbnNpYmxlLmNvbYINeG4tLTdjYTNhLmNvbYILeG4tLTc0aC5jb22HBAECAwSHEAAAAAAAAAAAAAAAAAAAAAGBEHRlc3RAZXhhbXBsZS5vcmeGI2h0dHBzOi8vZXhhbXBsZS5vcmcvdGVzdC9pbmRleC5odG1s' 'MHyCD3d3dy5hbnNpYmxlLmNvbYINeG4tLTdjYTNhLmNvbYILeG4tLTc0aC5jb22HBAECAwSHEAAAAAAAAAAAAAAAAAAAAAGBEHRlc3RAZXhhbXBsZS5vcmeGI2h0dHBzOi8vZXhhbXBsZS5vcmcvdGVzdC9pbmRleC5odG1s'
) )
# Basic Constraints # Basic Constraints
@@ -100,7 +98,6 @@
expected_authority_cert_issuer: expected_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
- "IP:1.2.3.4" - "IP:1.2.3.4"
when: cryptography_version.stdout is version('1.3', '>=')
- name: ({{select_crypto_backend}}) Read file - name: ({{select_crypto_backend}}) Read file
slurp: slurp:
@@ -152,7 +149,6 @@
expected_authority_cert_issuer: expected_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
- "IP:1.2.3.4" - "IP:1.2.3.4"
when: cryptography_version.stdout is version('1.3', '>=')
- name: ({{select_crypto_backend}}) Get certificate info - name: ({{select_crypto_backend}}) Get certificate info
x509_certificate_info: x509_certificate_info:
@@ -166,7 +162,6 @@
- result.authority_key_identifier == "44:55:66:77" - result.authority_key_identifier == "44:55:66:77"
- result.authority_cert_issuer is none - result.authority_cert_issuer is none
- result.authority_cert_serial_number is none - result.authority_cert_serial_number is none
when: cryptography_version.stdout is version('1.3', '>=')
- name: Copy packed cert 1 to remote - name: Copy packed cert 1 to remote
copy: copy:

View File

@@ -77,7 +77,7 @@
- "DNS:www.ansible.com" - "DNS:www.ansible.com"
- "DNS:öç.com" - "DNS:öç.com"
# cryptography < 2.1 cannot handle certain Unicode characters # cryptography < 2.1 cannot handle certain Unicode characters
- "DNS:{{ 'www.öç' if cryptography_version.stdout is version('2.1', '<') else '☺' }}.com" - "DNS:.com"
- "IP:1.2.3.4" - "IP:1.2.3.4"
- "IP:::1" - "IP:::1"
- "email:test@example.org" - "email:test@example.org"
@@ -87,10 +87,10 @@
- "pathlen:23" - "pathlen:23"
basic_constraints_critical: true basic_constraints_critical: true
ocsp_must_staple: true ocsp_must_staple: true
subject_key_identifier: '{{ "00:11:22:33" if cryptography_version.stdout is version("1.3", ">=") else omit }}' subject_key_identifier: "00:11:22:33"
authority_key_identifier: '{{ "44:55:66:77" if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_key_identifier: "44:55:66:77"
authority_cert_issuer: '{{ value_for_authority_cert_issuer if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_issuer: '{{ value_for_authority_cert_issuer }}'
authority_cert_serial_number: '{{ 12345 if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_serial_number: 12345
vars: vars:
value_for_authority_cert_issuer: value_for_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
@@ -116,8 +116,8 @@
- "IP:DEAD:BEEF::1" - "IP:DEAD:BEEF::1"
basic_constraints: basic_constraints:
- "CA:FALSE" - "CA:FALSE"
authority_cert_issuer: '{{ value_for_authority_cert_issuer if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_issuer: '{{ value_for_authority_cert_issuer }}'
authority_cert_serial_number: '{{ 12345 if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_cert_serial_number: 12345
vars: vars:
value_for_authority_cert_issuer: value_for_authority_cert_issuer:
- "DNS:ca.example.org" - "DNS:ca.example.org"
@@ -128,7 +128,7 @@
path: '{{ remote_tmp_dir }}/csr_4.csr' path: '{{ remote_tmp_dir }}/csr_4.csr'
privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem' privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem'
useCommonNameForSAN: false useCommonNameForSAN: false
authority_key_identifier: '{{ "44:55:66:77" if cryptography_version.stdout is version("1.3", ">=") else omit }}' authority_key_identifier: "44:55:66:77"
- name: Generate selfsigned certificates - name: Generate selfsigned certificates
x509_certificate: x509_certificate:
@@ -149,4 +149,4 @@
include_tasks: impl.yml include_tasks: impl.yml
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('1.6', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -23,4 +23,4 @@
vars: vars:
select_crypto_backend: cryptography select_crypto_backend: cryptography
when: cryptography_version.stdout is version('1.6', '>=') when: cryptography_version.stdout is version('3.4', '>=')

View File

@@ -553,11 +553,11 @@
- "DNS:ca.example.org" - "DNS:ca.example.org"
- "DNS:ffóò.ḃâŗ.çøṁ" - "DNS:ffóò.ḃâŗ.çøṁ"
- "email:foo@ḃâŗ.çøṁ" - "email:foo@ḃâŗ.çøṁ"
- "URI:https://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'admin:hunter2@' }}ffóò.ḃâŗ.çøṁ/baz?foo=bar" - "URI:https://admin:hunter2@ffóò.ḃâŗ.çøṁ/baz?foo=bar"
- "URI:https://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'goo@' }}www.straße.de" - "URI:https://goo@www.straße.de"
- "URI:https://straße.de:8080" - "URI:https://straße.de:8080"
- "URI:http://gefäß.org" - "URI:http://gefäß.org"
- "URI:http://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'a:b@' }}ä:1" - "URI:http://a:b@ä:1"
issuer_critical: true issuer_critical: true
register: crl_3 register: crl_3
@@ -576,11 +576,11 @@
- "DNS:ca.example.org" - "DNS:ca.example.org"
- "DNS:xn--ff-3jad.xn--2ca8uh37e.xn--7ca8a981n" - "DNS:xn--ff-3jad.xn--2ca8uh37e.xn--7ca8a981n"
- "email:foo@xn--2ca8uh37e.xn--7ca8a981n" - "email:foo@xn--2ca8uh37e.xn--7ca8a981n"
- "URI:https://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'admin:hunter2@' }}xn--ff-3jad.xn--2ca8uh37e.xn--7ca8a981n/baz?foo=bar" - "URI:https://admin:hunter2@xn--ff-3jad.xn--2ca8uh37e.xn--7ca8a981n/baz?foo=bar"
- "URI:https://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'goo@' }}www.xn--strae-oqa.de" - "URI:https://goo@www.xn--strae-oqa.de"
- "URI:https://xn--strae-oqa.de:8080" - "URI:https://xn--strae-oqa.de:8080"
- "URI:http://xn--gef-7kay.org" - "URI:http://xn--gef-7kay.org"
- "URI:http://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'a:b@' }}xn--4ca:1" - "URI:http://a:b@xn--4ca:1"
issuer_critical: true issuer_critical: true
ignore_timestamps: true ignore_timestamps: true
name_encoding: idna name_encoding: idna
@@ -601,11 +601,11 @@
- "DNS:ca.example.org" - "DNS:ca.example.org"
- "DNS:ffóò.ḃâŗ.çøṁ" - "DNS:ffóò.ḃâŗ.çøṁ"
- "email:foo@ḃâŗ.çøṁ" - "email:foo@ḃâŗ.çøṁ"
- "URI:https://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'admin:hunter2@' }}ffóò.ḃâŗ.çøṁ/baz?foo=bar" - "URI:https://admin:hunter2@ffóò.ḃâŗ.çøṁ/baz?foo=bar"
- "URI:https://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'goo@' }}www.straße.de" - "URI:https://goo@www.straße.de"
- "URI:https://straße.de:8080" - "URI:https://straße.de:8080"
- "URI:http://gefäß.org" - "URI:http://gefäß.org"
- "URI:http://{{ '' if cryptography_version.stdout is version('2.1', '<') or ansible_facts.python.version.minor == 5 else 'a:b@' }}ä:1" - "URI:http://a:b@ä:1"
issuer_critical: true issuer_critical: true
ignore_timestamps: true ignore_timestamps: true
name_encoding: unicode name_encoding: unicode
@@ -694,4 +694,4 @@
- Ed448 - Ed448
ignore_errors: true ignore_errors: true
when: cryptography_version.stdout is version('2.6', '>=') when: cryptography_version.stdout is version('3.4', '>=')

Some files were not shown because too many files have changed in this diff Show More