mirror of
https://github.com/ansible-collections/community.crypto.git
synced 2026-03-26 21:33:25 +00:00
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:
@@ -18,7 +18,7 @@ notes:
|
||||
another ACME server, please L(create an issue,https://github.com/ansible-collections/community.crypto/issues/new/choose)
|
||||
to help us supporting it. Feedback that an ACME server not mentioned does work is also appreciated.
|
||||
requirements:
|
||||
- either openssl or L(cryptography,https://cryptography.io/) >= 1.5
|
||||
- either openssl or L(cryptography,https://cryptography.io/) >= 3.4
|
||||
options:
|
||||
acme_version:
|
||||
description:
|
||||
|
||||
@@ -22,7 +22,7 @@ attributes:
|
||||
- If relative timestamps are used and O(ignore_timestamps=false), the module is not idempotent.
|
||||
- The option O(force=true) generally disables idempotency.
|
||||
requirements:
|
||||
- cryptography >= 1.6 (if using V(selfsigned) or V(ownca) provider)
|
||||
- cryptography >= 3.4 (if using V(selfsigned) or V(ownca) provider)
|
||||
options:
|
||||
force:
|
||||
description:
|
||||
@@ -304,7 +304,6 @@ options:
|
||||
ignored.
|
||||
- A value of V(never_create) never creates a SKI. If the CSR provides one, that one is used.
|
||||
- This is only used by the V(ownca) provider.
|
||||
- Note that this is only supported if the C(cryptography) backend is used!
|
||||
type: str
|
||||
choices: [create_if_not_provided, always_create, never_create]
|
||||
default: create_if_not_provided
|
||||
@@ -316,7 +315,6 @@ options:
|
||||
- The Authority Key Identifier is generated from the CA certificate's Subject Key Identifier,
|
||||
if available. If it is not available, the CA certificate's public key will be used.
|
||||
- This is only used by the V(ownca) provider.
|
||||
- Note that this is only supported if the C(cryptography) backend is used!
|
||||
type: bool
|
||||
default: true
|
||||
"""
|
||||
@@ -403,7 +401,6 @@ options:
|
||||
ignored.
|
||||
- A value of V(never_create) never creates a SKI. If the CSR provides one, that one is used.
|
||||
- This is only used by the V(selfsigned) provider.
|
||||
- Note that this is only supported if the C(cryptography) backend is used!
|
||||
type: str
|
||||
choices: [create_if_not_provided, always_create, never_create]
|
||||
default: create_if_not_provided
|
||||
|
||||
@@ -18,7 +18,7 @@ attributes:
|
||||
idempotent:
|
||||
support: full
|
||||
requirements:
|
||||
- cryptography >= 1.3
|
||||
- cryptography >= 3.4
|
||||
options:
|
||||
digest:
|
||||
description:
|
||||
@@ -237,7 +237,6 @@ options:
|
||||
- Create the Subject Key Identifier from the public key.
|
||||
- Please note that commercial CAs can ignore the value, respectively use a value of their own choice instead. Specifying
|
||||
this option is mostly useful for self-signed certificates or for own CAs.
|
||||
- Note that this is only supported if the C(cryptography) backend is used!
|
||||
type: bool
|
||||
default: false
|
||||
subject_key_identifier:
|
||||
@@ -247,7 +246,6 @@ options:
|
||||
- Please note that commercial CAs ignore this value, respectively use a value of their own choice. Specifying this option
|
||||
is mostly useful for self-signed certificates or for own CAs.
|
||||
- Note that this option can only be used if O(create_subject_key_identifier) is V(false).
|
||||
- Note that this is only supported if the C(cryptography) backend is used!
|
||||
type: str
|
||||
authority_key_identifier:
|
||||
description:
|
||||
@@ -255,7 +253,6 @@ options:
|
||||
- 'Example: V(00:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22:33).'
|
||||
- Please note that commercial CAs ignore this value, respectively use a value of their own choice. Specifying this option
|
||||
is mostly useful for self-signed certificates or for own CAs.
|
||||
- Note that this is only supported if the C(cryptography) backend is used!
|
||||
- The C(AuthorityKeyIdentifier) extension will only be added if at least one of O(authority_key_identifier), O(authority_cert_issuer)
|
||||
and O(authority_cert_serial_number) is specified.
|
||||
type: str
|
||||
@@ -268,7 +265,6 @@ options:
|
||||
- If specified, O(authority_cert_serial_number) must also be specified.
|
||||
- Please note that commercial CAs ignore this value, respectively use a value of their own choice. Specifying this option
|
||||
is mostly useful for self-signed certificates or for own CAs.
|
||||
- Note that this is only supported if the C(cryptography) backend is used!
|
||||
- The C(AuthorityKeyIdentifier) extension will only be added if at least one of O(authority_key_identifier), O(authority_cert_issuer)
|
||||
and O(authority_cert_serial_number) is specified.
|
||||
type: list
|
||||
@@ -277,7 +273,6 @@ options:
|
||||
description:
|
||||
- The authority cert serial number.
|
||||
- If specified, O(authority_cert_issuer) must also be specified.
|
||||
- Note that this is only supported if the C(cryptography) backend is used!
|
||||
- Please note that commercial CAs ignore this value, respectively use a value of their own choice. Specifying this option
|
||||
is mostly useful for self-signed certificates or for own CAs.
|
||||
- The C(AuthorityKeyIdentifier) extension will only be added if at least one of O(authority_key_identifier), O(authority_cert_issuer)
|
||||
@@ -288,7 +283,6 @@ options:
|
||||
crl_distribution_points:
|
||||
description:
|
||||
- Allows to specify one or multiple CRL distribution points.
|
||||
- Only supported by the C(cryptography) backend.
|
||||
type: list
|
||||
elements: dict
|
||||
suboptions:
|
||||
@@ -304,7 +298,6 @@ options:
|
||||
- Describes how the CRL can be retrieved relative to the CRL issuer.
|
||||
- Mutually exclusive with O(crl_distribution_points[].full_name).
|
||||
- 'Example: V(/CN=example.com).'
|
||||
- Can only be used when cryptography >= 1.6 is installed.
|
||||
type: list
|
||||
elements: str
|
||||
crl_issuer:
|
||||
|
||||
@@ -22,7 +22,7 @@ attributes:
|
||||
details:
|
||||
- The option O(regenerate=always) generally disables idempotency.
|
||||
requirements:
|
||||
- cryptography >= 1.2.3 (older versions might work as well)
|
||||
- cryptography >= 3.4
|
||||
options:
|
||||
size:
|
||||
description:
|
||||
@@ -32,9 +32,6 @@ options:
|
||||
type:
|
||||
description:
|
||||
- The algorithm used to generate the TLS/SSL private key.
|
||||
- Note that V(ECC), V(X25519), V(X448), V(Ed25519), and V(Ed448) require the C(cryptography) backend. V(X25519) needs
|
||||
cryptography 2.5 or newer, while V(X448), V(Ed25519), and V(Ed448) require cryptography 2.6 or newer. For V(ECC),
|
||||
the minimal cryptography version required depends on the O(curve) option.
|
||||
type: str
|
||||
default: RSA
|
||||
choices: [DSA, ECC, Ed25519, Ed448, RSA, X25519, X448]
|
||||
@@ -101,7 +98,6 @@ options:
|
||||
parameters are as expected.
|
||||
- If set to V(regenerate) (default), generates a new private key.
|
||||
- If set to V(convert), the key will be converted to the new format instead.
|
||||
- Only supported by the C(cryptography) backend.
|
||||
type: str
|
||||
default: regenerate
|
||||
choices: [regenerate, convert]
|
||||
|
||||
@@ -10,7 +10,7 @@ class ModuleDocFragment:
|
||||
# Standard files documentation fragment
|
||||
DOCUMENTATION = r"""
|
||||
requirements:
|
||||
- cryptography >= 1.2.3 (older versions might work as well)
|
||||
- cryptography >= 3.4
|
||||
attributes:
|
||||
diff_mode:
|
||||
support: none
|
||||
|
||||
@@ -29,7 +29,6 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.utils import
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
CRYPTOGRAPHY_TIMEZONE,
|
||||
cryptography_name_to_oid,
|
||||
cryptography_serial_number_of_cert,
|
||||
get_not_valid_after,
|
||||
get_not_valid_before,
|
||||
)
|
||||
@@ -75,11 +74,6 @@ else:
|
||||
HAS_CURRENT_CRYPTOGRAPHY = LooseVersion(CRYPTOGRAPHY_VERSION) >= LooseVersion(
|
||||
CRYPTOGRAPHY_MINIMAL_VERSION
|
||||
)
|
||||
try:
|
||||
if HAS_CURRENT_CRYPTOGRAPHY:
|
||||
_cryptography_backend = cryptography.hazmat.backends.default_backend()
|
||||
except Exception:
|
||||
CRYPTOGRAPHY_ERROR = traceback.format_exc()
|
||||
|
||||
|
||||
class CryptographyChainMatcher(ChainMatcher):
|
||||
@@ -150,9 +144,7 @@ class CryptographyChainMatcher(ChainMatcher):
|
||||
chain = chain[:1]
|
||||
for cert in chain:
|
||||
try:
|
||||
x509 = cryptography.x509.load_pem_x509_certificate(
|
||||
to_bytes(cert), cryptography.hazmat.backends.default_backend()
|
||||
)
|
||||
x509 = cryptography.x509.load_pem_x509_certificate(to_bytes(cert))
|
||||
matches = True
|
||||
if not self._match_subject(x509.subject, self.subject):
|
||||
matches = False
|
||||
@@ -204,7 +196,6 @@ class CryptographyBackend(CryptoBackend):
|
||||
key = cryptography.hazmat.primitives.serialization.load_pem_private_key(
|
||||
key_content,
|
||||
password=to_bytes(passphrase) if passphrase is not None else None,
|
||||
backend=_cryptography_backend,
|
||||
)
|
||||
except Exception as e:
|
||||
raise KeyParsingError(f"error while loading key: {e}")
|
||||
@@ -323,7 +314,7 @@ class CryptographyBackend(CryptoBackend):
|
||||
)
|
||||
return {
|
||||
"mac_obj": lambda: cryptography.hazmat.primitives.hmac.HMAC(
|
||||
key_bytes, hashalg(), _cryptography_backend
|
||||
key_bytes, hashalg()
|
||||
),
|
||||
"type": "hmac",
|
||||
"alg": alg,
|
||||
@@ -346,7 +337,7 @@ class CryptographyBackend(CryptoBackend):
|
||||
csr_content = read_file(csr_filename)
|
||||
else:
|
||||
csr_content = to_bytes(csr_content)
|
||||
csr = cryptography.x509.load_pem_x509_csr(csr_content, _cryptography_backend)
|
||||
csr = cryptography.x509.load_pem_x509_csr(csr_content)
|
||||
|
||||
identifiers = set()
|
||||
result = []
|
||||
@@ -410,9 +401,7 @@ class CryptographyBackend(CryptoBackend):
|
||||
cert_content = to_bytes(extract_first_pem(to_text(cert_content)) or "")
|
||||
|
||||
try:
|
||||
cert = cryptography.x509.load_pem_x509_certificate(
|
||||
cert_content, _cryptography_backend
|
||||
)
|
||||
cert = cryptography.x509.load_pem_x509_certificate(cert_content)
|
||||
except Exception as e:
|
||||
if cert_filename is None:
|
||||
raise BackendException(f"Cannot parse certificate: {e}")
|
||||
@@ -443,9 +432,7 @@ class CryptographyBackend(CryptoBackend):
|
||||
cert_content = to_bytes(extract_first_pem(to_text(cert_content)) or "")
|
||||
|
||||
try:
|
||||
cert = cryptography.x509.load_pem_x509_certificate(
|
||||
cert_content, _cryptography_backend
|
||||
)
|
||||
cert = cryptography.x509.load_pem_x509_certificate(cert_content)
|
||||
except Exception as e:
|
||||
if cert_filename is None:
|
||||
raise BackendException(f"Cannot parse certificate: {e}")
|
||||
@@ -472,7 +459,7 @@ class CryptographyBackend(CryptoBackend):
|
||||
return CertificateInformation(
|
||||
not_valid_after=get_not_valid_after(cert),
|
||||
not_valid_before=get_not_valid_before(cert),
|
||||
serial_number=cryptography_serial_number_of_cert(cert),
|
||||
serial_number=cert.serial_number,
|
||||
subject_key_identifier=ski,
|
||||
authority_key_identifier=aki,
|
||||
)
|
||||
|
||||
@@ -5,155 +5,13 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
LooseVersion,
|
||||
)
|
||||
|
||||
|
||||
try:
|
||||
import cryptography
|
||||
from cryptography import x509
|
||||
|
||||
# Older versions of cryptography (< 2.1) do not have __hash__ functions for
|
||||
# general name objects (DNSName, IPAddress, ...), while providing overloaded
|
||||
# equality and string representation operations. This makes it impossible to
|
||||
# use them in hash-based data structures such as set or dict. Since we are
|
||||
# actually doing that in x509_certificate, and potentially in other code,
|
||||
# we need to monkey-patch __hash__ for these classes to make sure our code
|
||||
# works fine.
|
||||
if LooseVersion(cryptography.__version__) < LooseVersion("2.1"):
|
||||
# A very simply hash function which relies on the representation
|
||||
# of an object to be implemented. This is the case since at least
|
||||
# cryptography 1.0, see
|
||||
# https://github.com/pyca/cryptography/commit/7a9abce4bff36c05d26d8d2680303a6f64a0e84f
|
||||
def simple_hash(self):
|
||||
return hash(repr(self))
|
||||
|
||||
# The hash functions for the following types were added for cryptography 2.1:
|
||||
# https://github.com/pyca/cryptography/commit/fbfc36da2a4769045f2373b004ddf0aff906cf38
|
||||
x509.DNSName.__hash__ = simple_hash
|
||||
x509.DirectoryName.__hash__ = simple_hash
|
||||
x509.GeneralName.__hash__ = simple_hash
|
||||
x509.IPAddress.__hash__ = simple_hash
|
||||
x509.OtherName.__hash__ = simple_hash
|
||||
x509.RegisteredID.__hash__ = simple_hash
|
||||
|
||||
if LooseVersion(cryptography.__version__) < LooseVersion("1.2"):
|
||||
# The hash functions for the following types were added for cryptography 1.2:
|
||||
# https://github.com/pyca/cryptography/commit/b642deed88a8696e5f01ce6855ccf89985fc35d0
|
||||
# https://github.com/pyca/cryptography/commit/d1b5681f6db2bde7a14625538bd7907b08dfb486
|
||||
x509.RFC822Name.__hash__ = simple_hash
|
||||
x509.UniformResourceIdentifier.__hash__ = simple_hash
|
||||
|
||||
# Test whether we have support for DSA, EC, Ed25519, Ed448, RSA, X25519 and/or X448
|
||||
try:
|
||||
# added in 0.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/dsa/
|
||||
import cryptography.hazmat.primitives.asymmetric.dsa
|
||||
|
||||
CRYPTOGRAPHY_HAS_DSA = True
|
||||
try:
|
||||
# added later in 1.5
|
||||
cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey.sign
|
||||
CRYPTOGRAPHY_HAS_DSA_SIGN = True
|
||||
except AttributeError:
|
||||
CRYPTOGRAPHY_HAS_DSA_SIGN = False
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_HAS_DSA = False
|
||||
CRYPTOGRAPHY_HAS_DSA_SIGN = False
|
||||
try:
|
||||
# added in 2.6 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ed25519/
|
||||
import cryptography.hazmat.primitives.asymmetric.ed25519
|
||||
|
||||
CRYPTOGRAPHY_HAS_ED25519 = True
|
||||
try:
|
||||
# added with the primitive in 2.6
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.sign
|
||||
CRYPTOGRAPHY_HAS_ED25519_SIGN = True
|
||||
except AttributeError:
|
||||
CRYPTOGRAPHY_HAS_ED25519_SIGN = False
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_HAS_ED25519 = False
|
||||
CRYPTOGRAPHY_HAS_ED25519_SIGN = False
|
||||
try:
|
||||
# added in 2.6 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ed448/
|
||||
import cryptography.hazmat.primitives.asymmetric.ed448
|
||||
|
||||
CRYPTOGRAPHY_HAS_ED448 = True
|
||||
try:
|
||||
# added with the primitive in 2.6
|
||||
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey.sign
|
||||
CRYPTOGRAPHY_HAS_ED448_SIGN = True
|
||||
except AttributeError:
|
||||
CRYPTOGRAPHY_HAS_ED448_SIGN = False
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_HAS_ED448 = False
|
||||
CRYPTOGRAPHY_HAS_ED448_SIGN = False
|
||||
try:
|
||||
# added in 0.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/
|
||||
import cryptography.hazmat.primitives.asymmetric.ec
|
||||
|
||||
CRYPTOGRAPHY_HAS_EC = True
|
||||
try:
|
||||
# added later in 1.5
|
||||
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey.sign
|
||||
CRYPTOGRAPHY_HAS_EC_SIGN = True
|
||||
except AttributeError:
|
||||
CRYPTOGRAPHY_HAS_EC_SIGN = False
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_HAS_EC = False
|
||||
CRYPTOGRAPHY_HAS_EC_SIGN = False
|
||||
try:
|
||||
# added in 0.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/
|
||||
import cryptography.hazmat.primitives.asymmetric.rsa
|
||||
|
||||
CRYPTOGRAPHY_HAS_RSA = True
|
||||
try:
|
||||
# added later in 1.4
|
||||
cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey.sign
|
||||
CRYPTOGRAPHY_HAS_RSA_SIGN = True
|
||||
except AttributeError:
|
||||
CRYPTOGRAPHY_HAS_RSA_SIGN = False
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_HAS_RSA = False
|
||||
CRYPTOGRAPHY_HAS_RSA_SIGN = False
|
||||
try:
|
||||
# added in 2.0 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/x25519/
|
||||
import cryptography.hazmat.primitives.asymmetric.x25519
|
||||
|
||||
CRYPTOGRAPHY_HAS_X25519 = True
|
||||
try:
|
||||
# added later in 2.5
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.private_bytes
|
||||
CRYPTOGRAPHY_HAS_X25519_FULL = True
|
||||
except AttributeError:
|
||||
CRYPTOGRAPHY_HAS_X25519_FULL = False
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_HAS_X25519 = False
|
||||
CRYPTOGRAPHY_HAS_X25519_FULL = False
|
||||
try:
|
||||
# added in 2.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/x448/
|
||||
import cryptography.hazmat.primitives.asymmetric.x448
|
||||
|
||||
CRYPTOGRAPHY_HAS_X448 = True
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_HAS_X448 = False
|
||||
import cryptography # noqa: F401, pylint: disable=unused-import
|
||||
|
||||
HAS_CRYPTOGRAPHY = True
|
||||
except ImportError:
|
||||
# Error handled in the calling module.
|
||||
CRYPTOGRAPHY_HAS_EC = False
|
||||
CRYPTOGRAPHY_HAS_EC_SIGN = False
|
||||
CRYPTOGRAPHY_HAS_ED25519 = False
|
||||
CRYPTOGRAPHY_HAS_ED25519_SIGN = False
|
||||
CRYPTOGRAPHY_HAS_ED448 = False
|
||||
CRYPTOGRAPHY_HAS_ED448_SIGN = False
|
||||
CRYPTOGRAPHY_HAS_DSA = False
|
||||
CRYPTOGRAPHY_HAS_DSA_SIGN = False
|
||||
CRYPTOGRAPHY_HAS_RSA = False
|
||||
CRYPTOGRAPHY_HAS_RSA_SIGN = False
|
||||
CRYPTOGRAPHY_HAS_X25519 = False
|
||||
CRYPTOGRAPHY_HAS_X25519_FULL = False
|
||||
CRYPTOGRAPHY_HAS_X448 = False
|
||||
HAS_CRYPTOGRAPHY = False
|
||||
|
||||
|
||||
|
||||
@@ -27,9 +27,11 @@ try:
|
||||
import cryptography
|
||||
from cryptography import x509
|
||||
from cryptography.exceptions import InvalidSignature
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import padding
|
||||
from cryptography.hazmat.primitives.serialization.pkcs12 import (
|
||||
load_key_and_certificates as _load_key_and_certificates,
|
||||
)
|
||||
|
||||
_HAS_CRYPTOGRAPHY = True
|
||||
except ImportError:
|
||||
@@ -37,36 +39,15 @@ except ImportError:
|
||||
# Error handled in the calling module.
|
||||
pass
|
||||
|
||||
try:
|
||||
import cryptography.hazmat.primitives.asymmetric.rsa
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import cryptography.hazmat.primitives.asymmetric.ec
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import cryptography.hazmat.primitives.asymmetric.dsa
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import cryptography.hazmat.primitives.asymmetric.ed25519
|
||||
except ImportError:
|
||||
pass
|
||||
try:
|
||||
import cryptography.hazmat.primitives.asymmetric.ed448
|
||||
import cryptography.hazmat.primitives.asymmetric.ed25519
|
||||
import cryptography.hazmat.primitives.asymmetric.rsa
|
||||
import cryptography.hazmat.primitives.asymmetric.x448
|
||||
import cryptography.hazmat.primitives.asymmetric.x25519
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
# This is a separate try/except since this is only present in cryptography 2.5 or newer
|
||||
from cryptography.hazmat.primitives.serialization.pkcs12 import (
|
||||
load_key_and_certificates as _load_key_and_certificates,
|
||||
)
|
||||
except ImportError:
|
||||
# Error handled in the calling module.
|
||||
_load_key_and_certificates = None
|
||||
|
||||
try:
|
||||
# This is a separate try/except since this is only present in cryptography 36.0.0 or newer
|
||||
from cryptography.hazmat.primitives.serialization.pkcs12 import (
|
||||
@@ -89,43 +70,40 @@ from ansible.module_utils.basic import missing_required_lib
|
||||
from ._obj2txt import obj2txt
|
||||
from ._objects import NORMALIZE_NAMES, NORMALIZE_NAMES_SHORT, OID_LOOKUP, OID_MAP
|
||||
from .basic import (
|
||||
CRYPTOGRAPHY_HAS_DSA_SIGN,
|
||||
CRYPTOGRAPHY_HAS_EC_SIGN,
|
||||
CRYPTOGRAPHY_HAS_ED448,
|
||||
CRYPTOGRAPHY_HAS_ED448_SIGN,
|
||||
CRYPTOGRAPHY_HAS_ED25519,
|
||||
CRYPTOGRAPHY_HAS_ED25519_SIGN,
|
||||
CRYPTOGRAPHY_HAS_RSA_SIGN,
|
||||
CRYPTOGRAPHY_HAS_X448,
|
||||
CRYPTOGRAPHY_HAS_X25519,
|
||||
CRYPTOGRAPHY_HAS_X25519_FULL,
|
||||
OpenSSLObjectError,
|
||||
)
|
||||
|
||||
|
||||
CRYPTOGRAPHY_TIMEZONE = False
|
||||
_CRYPTOGRAPHY_36_0_OR_NEWER = False
|
||||
if _HAS_CRYPTOGRAPHY:
|
||||
CRYPTOGRAPHY_TIMEZONE = LooseVersion(cryptography.__version__) >= LooseVersion(
|
||||
"42.0.0"
|
||||
)
|
||||
|
||||
_CRYPTOGRAPHY_36_0_OR_NEWER = LooseVersion(
|
||||
cryptography.__version__
|
||||
) >= LooseVersion("36.0")
|
||||
|
||||
DOTTED_OID = re.compile(r"^\d+(?:\.\d+)+$")
|
||||
|
||||
|
||||
def cryptography_get_extensions_from_cert(cert):
|
||||
result = dict()
|
||||
try:
|
||||
|
||||
if _CRYPTOGRAPHY_36_0_OR_NEWER:
|
||||
for ext in cert.extensions:
|
||||
result[ext.oid.dotted_string] = dict(
|
||||
critical=ext.critical,
|
||||
value=to_native(base64.b64encode(ext.value.public_bytes())),
|
||||
)
|
||||
else:
|
||||
# Since cryptography will not give us the DER value for an extension
|
||||
# (that is only stored for unrecognized extensions), we have to re-do
|
||||
# the extension parsing ourselves.
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
|
||||
backend = default_backend()
|
||||
try:
|
||||
# For certain old versions of cryptography, backend is a MultiBackend object,
|
||||
# which has no _lib attribute. In that case, revert to the old approach.
|
||||
backend._lib
|
||||
except AttributeError:
|
||||
backend = cert._backend
|
||||
|
||||
x509_obj = cert._x509
|
||||
# With cryptography 35.0.0, we can no longer use obj2txt. Unfortunately it still does
|
||||
@@ -154,34 +132,26 @@ def cryptography_get_extensions_from_cert(cert):
|
||||
oid = exts[i].oid.dotted_string
|
||||
result[oid] = entry
|
||||
|
||||
except Exception:
|
||||
# In case the above method breaks, we likely have cryptography 36.0.0 or newer.
|
||||
# Use its public_bytes() feature in that case. We will later switch this around
|
||||
# so that this code will be the default, but for now this will act as a fallback
|
||||
# since it will re-serialize de-serialized data, which can be different (if the
|
||||
# original data was not canonicalized) from what was contained in the certificate.
|
||||
for ext in cert.extensions:
|
||||
result[ext.oid.dotted_string] = dict(
|
||||
critical=ext.critical,
|
||||
value=to_native(base64.b64encode(ext.value.public_bytes())),
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def cryptography_get_extensions_from_csr(csr):
|
||||
result = dict()
|
||||
try:
|
||||
|
||||
if _CRYPTOGRAPHY_36_0_OR_NEWER:
|
||||
for ext in csr.extensions:
|
||||
result[ext.oid.dotted_string] = dict(
|
||||
critical=ext.critical,
|
||||
value=to_native(base64.b64encode(ext.value.public_bytes())),
|
||||
)
|
||||
|
||||
else:
|
||||
# Since cryptography will not give us the DER value for an extension
|
||||
# (that is only stored for unrecognized extensions), we have to re-do
|
||||
# the extension parsing ourselves.
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
|
||||
backend = default_backend()
|
||||
try:
|
||||
# For certain old versions of cryptography, backend is a MultiBackend object,
|
||||
# which has no _lib attribute. In that case, revert to the old approach.
|
||||
backend._lib
|
||||
except AttributeError:
|
||||
backend = csr._backend
|
||||
|
||||
extensions = backend._lib.X509_REQ_get_extensions(csr._x509_req)
|
||||
extensions = backend._ffi.gc(
|
||||
@@ -220,18 +190,6 @@ def cryptography_get_extensions_from_csr(csr):
|
||||
oid = exts[i].oid.dotted_string
|
||||
result[oid] = entry
|
||||
|
||||
except Exception:
|
||||
# In case the above method breaks, we likely have cryptography 36.0.0 or newer.
|
||||
# Use its public_bytes() feature in that case. We will later switch this around
|
||||
# so that this code will be the default, but for now this will act as a fallback
|
||||
# since it will re-serialize de-serialized data, which can be different (if the
|
||||
# original data was not canonicalized) from what was contained in the CSR.
|
||||
for ext in csr.extensions:
|
||||
result[ext.oid.dotted_string] = dict(
|
||||
critical=ext.critical,
|
||||
value=to_native(base64.b64encode(ext.value.public_bytes())),
|
||||
)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
@@ -665,13 +623,11 @@ def cryptography_key_needs_digest_for_signing(key):
|
||||
|
||||
Ed25519 and Ed448 keys do not; they need None to be passed as the digest algorithm.
|
||||
"""
|
||||
if CRYPTOGRAPHY_HAS_ED25519 and isinstance(
|
||||
if isinstance(
|
||||
key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey
|
||||
):
|
||||
return False
|
||||
if CRYPTOGRAPHY_HAS_ED448 and isinstance(
|
||||
key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey
|
||||
):
|
||||
if isinstance(key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey):
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -693,33 +649,28 @@ def cryptography_compare_public_keys(key1, key2):
|
||||
|
||||
Needs special logic for Ed25519 and Ed448 keys, since they do not have public_numbers().
|
||||
"""
|
||||
if CRYPTOGRAPHY_HAS_ED25519:
|
||||
res = _compare_public_keys(
|
||||
key1,
|
||||
key2,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
|
||||
)
|
||||
if res is not None:
|
||||
return res
|
||||
if CRYPTOGRAPHY_HAS_ED448:
|
||||
res = _compare_public_keys(
|
||||
key1, key2, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey
|
||||
)
|
||||
if res is not None:
|
||||
return res
|
||||
res = _compare_public_keys(
|
||||
key1,
|
||||
key2,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
|
||||
)
|
||||
if res is not None:
|
||||
return res
|
||||
res = _compare_public_keys(
|
||||
key1, key2, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey
|
||||
)
|
||||
if res is not None:
|
||||
return res
|
||||
return key1.public_numbers() == key2.public_numbers()
|
||||
|
||||
|
||||
def _compare_private_keys(key1, key2, clazz, has_no_private_bytes=False):
|
||||
def _compare_private_keys(key1, key2, clazz):
|
||||
a = isinstance(key1, clazz)
|
||||
b = isinstance(key2, clazz)
|
||||
if not (a or b):
|
||||
return None
|
||||
if not a or not b:
|
||||
return False
|
||||
if has_no_private_bytes:
|
||||
# We do not have the private_bytes() function - compare associated public keys
|
||||
return cryptography_compare_public_keys(a.public_key(), b.public_key())
|
||||
encryption_algorithm = cryptography.hazmat.primitives.serialization.NoEncryption()
|
||||
a = key1.private_bytes(
|
||||
serialization.Encoding.Raw,
|
||||
@@ -739,57 +690,35 @@ def cryptography_compare_private_keys(key1, key2):
|
||||
|
||||
Needs special logic for Ed25519, X25519, and Ed448 keys, since they do not have private_numbers().
|
||||
"""
|
||||
if CRYPTOGRAPHY_HAS_ED25519:
|
||||
res = _compare_private_keys(
|
||||
key1,
|
||||
key2,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey,
|
||||
)
|
||||
if res is not None:
|
||||
return res
|
||||
if CRYPTOGRAPHY_HAS_X25519:
|
||||
res = _compare_private_keys(
|
||||
key1,
|
||||
key2,
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey,
|
||||
has_no_private_bytes=not CRYPTOGRAPHY_HAS_X25519_FULL,
|
||||
)
|
||||
if res is not None:
|
||||
return res
|
||||
if CRYPTOGRAPHY_HAS_ED448:
|
||||
res = _compare_private_keys(
|
||||
key1, key2, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey
|
||||
)
|
||||
if res is not None:
|
||||
return res
|
||||
if CRYPTOGRAPHY_HAS_X448:
|
||||
res = _compare_private_keys(
|
||||
key1, key2, cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey
|
||||
)
|
||||
if res is not None:
|
||||
return res
|
||||
res = _compare_private_keys(
|
||||
key1,
|
||||
key2,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey,
|
||||
)
|
||||
if res is not None:
|
||||
return res
|
||||
res = _compare_private_keys(
|
||||
key1,
|
||||
key2,
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey,
|
||||
)
|
||||
if res is not None:
|
||||
return res
|
||||
res = _compare_private_keys(
|
||||
key1, key2, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey
|
||||
)
|
||||
if res is not None:
|
||||
return res
|
||||
res = _compare_private_keys(
|
||||
key1, key2, cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey
|
||||
)
|
||||
if res is not None:
|
||||
return res
|
||||
return key1.private_numbers() == key2.private_numbers()
|
||||
|
||||
|
||||
def cryptography_serial_number_of_cert(cert):
|
||||
"""Returns cert.serial_number.
|
||||
|
||||
Also works for old versions of cryptography.
|
||||
"""
|
||||
try:
|
||||
return cert.serial_number
|
||||
except AttributeError:
|
||||
# The property was called "serial" before cryptography 1.4
|
||||
return cert.serial
|
||||
|
||||
|
||||
def parse_pkcs12(pkcs12_bytes, passphrase=None):
|
||||
"""Returns a tuple (private_key, certificate, additional_certificates, friendly_name)."""
|
||||
if _load_pkcs12 is None and _load_key_and_certificates is None:
|
||||
raise ValueError(
|
||||
"neither load_pkcs12() nor load_key_and_certificates() present in the current cryptography version"
|
||||
)
|
||||
|
||||
if passphrase is not None:
|
||||
passphrase = to_bytes(passphrase)
|
||||
|
||||
@@ -825,6 +754,8 @@ def _parse_pkcs12_35_0_0(pkcs12_bytes, passphrase=None):
|
||||
friendly_name = None
|
||||
if certificate:
|
||||
# See https://github.com/pyca/cryptography/issues/5760#issuecomment-842687238
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
|
||||
backend = default_backend()
|
||||
|
||||
# This code basically does what load_key_and_certificates() does, but without error-checking.
|
||||
@@ -877,7 +808,7 @@ def cryptography_verify_signature(signature, data, hash_algorithm, signer_public
|
||||
Check whether the given signature of the given data was signed by the given public key object.
|
||||
"""
|
||||
try:
|
||||
if CRYPTOGRAPHY_HAS_RSA_SIGN and isinstance(
|
||||
if isinstance(
|
||||
signer_public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey,
|
||||
):
|
||||
@@ -885,7 +816,7 @@ def cryptography_verify_signature(signature, data, hash_algorithm, signer_public
|
||||
signature, data, padding.PKCS1v15(), hash_algorithm
|
||||
)
|
||||
return True
|
||||
if CRYPTOGRAPHY_HAS_EC_SIGN and isinstance(
|
||||
if isinstance(
|
||||
signer_public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey,
|
||||
):
|
||||
@@ -895,19 +826,19 @@ def cryptography_verify_signature(signature, data, hash_algorithm, signer_public
|
||||
cryptography.hazmat.primitives.asymmetric.ec.ECDSA(hash_algorithm),
|
||||
)
|
||||
return True
|
||||
if CRYPTOGRAPHY_HAS_DSA_SIGN and isinstance(
|
||||
if isinstance(
|
||||
signer_public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey,
|
||||
):
|
||||
signer_public_key.verify(signature, data, hash_algorithm)
|
||||
return True
|
||||
if CRYPTOGRAPHY_HAS_ED25519_SIGN and isinstance(
|
||||
if isinstance(
|
||||
signer_public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
|
||||
):
|
||||
signer_public_key.verify(signature, data)
|
||||
return True
|
||||
if CRYPTOGRAPHY_HAS_ED448_SIGN and isinstance(
|
||||
if isinstance(
|
||||
signer_public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey,
|
||||
):
|
||||
|
||||
@@ -35,7 +35,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.6"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
CRYPTOGRAPHY_VERSION = None
|
||||
|
||||
@@ -11,7 +11,6 @@ import os
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
CRYPTOGRAPHY_TIMEZONE,
|
||||
cryptography_serial_number_of_cert,
|
||||
get_not_valid_after,
|
||||
)
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.certificate import (
|
||||
@@ -179,9 +178,7 @@ class EntrustCertificateBackend(CertificateBackend):
|
||||
serial_number = None
|
||||
expiry = None
|
||||
if self.backend == "cryptography":
|
||||
serial_number = (
|
||||
f"{cryptography_serial_number_of_cert(self.existing_certificate):X}"
|
||||
)
|
||||
serial_number = f"{self.existing_certificate.serial_number:X}"
|
||||
expiry = get_not_valid_after(self.existing_certificate)
|
||||
|
||||
# get some information about the expiry of this certificate
|
||||
|
||||
@@ -18,7 +18,6 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptograp
|
||||
cryptography_decode_name,
|
||||
cryptography_get_extensions_from_cert,
|
||||
cryptography_oid_to_name,
|
||||
cryptography_serial_number_of_cert,
|
||||
get_not_valid_after,
|
||||
get_not_valid_before,
|
||||
)
|
||||
@@ -37,7 +36,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.6"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
@@ -341,20 +340,12 @@ class CertificateInfoRetrievalCryptography(CertificateInfoRetrieval):
|
||||
|
||||
def _get_ocsp_must_staple(self):
|
||||
try:
|
||||
try:
|
||||
# This only works with cryptography >= 2.1
|
||||
tlsfeature_ext = self.cert.extensions.get_extension_for_class(
|
||||
x509.TLSFeature
|
||||
)
|
||||
value = (
|
||||
cryptography.x509.TLSFeatureType.status_request
|
||||
in tlsfeature_ext.value
|
||||
)
|
||||
except AttributeError:
|
||||
# Fallback for cryptography < 2.1
|
||||
oid = x509.oid.ObjectIdentifier("1.3.6.1.5.5.7.1.24")
|
||||
tlsfeature_ext = self.cert.extensions.get_extension_for_oid(oid)
|
||||
value = tlsfeature_ext.value.value == b"\x30\x03\x02\x01\x05"
|
||||
tlsfeature_ext = self.cert.extensions.get_extension_for_class(
|
||||
x509.TLSFeature
|
||||
)
|
||||
value = (
|
||||
cryptography.x509.TLSFeatureType.status_request in tlsfeature_ext.value
|
||||
)
|
||||
return value, tlsfeature_ext.critical
|
||||
except cryptography.x509.ExtensionNotFound:
|
||||
return None, False
|
||||
@@ -416,7 +407,7 @@ class CertificateInfoRetrievalCryptography(CertificateInfoRetrieval):
|
||||
return None, None, None
|
||||
|
||||
def _get_serial_number(self):
|
||||
return cryptography_serial_number_of_cert(self.cert)
|
||||
return self.cert.serial_number
|
||||
|
||||
def _get_all_extensions(self):
|
||||
return cryptography_get_extensions_from_cert(self.cert)
|
||||
|
||||
@@ -15,7 +15,6 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptograp
|
||||
CRYPTOGRAPHY_TIMEZONE,
|
||||
cryptography_compare_public_keys,
|
||||
cryptography_key_needs_digest_for_signing,
|
||||
cryptography_serial_number_of_cert,
|
||||
cryptography_verify_certificate_signature,
|
||||
get_not_valid_after,
|
||||
get_not_valid_before,
|
||||
@@ -44,7 +43,6 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
try:
|
||||
import cryptography
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.serialization import Encoding
|
||||
except ImportError:
|
||||
pass
|
||||
@@ -187,21 +185,10 @@ class OwnCACertificateBackendCryptography(CertificateBackend):
|
||||
critical=False,
|
||||
)
|
||||
|
||||
try:
|
||||
certificate = cert_builder.sign(
|
||||
private_key=self.ca_private_key,
|
||||
algorithm=self.digest,
|
||||
backend=default_backend(),
|
||||
)
|
||||
except TypeError as e:
|
||||
if (
|
||||
str(e) == "Algorithm must be a registered hash algorithm."
|
||||
and self.digest is None
|
||||
):
|
||||
self.module.fail_json(
|
||||
msg="Signing with Ed25519 and Ed448 keys requires cryptography 2.8 or newer."
|
||||
)
|
||||
raise
|
||||
certificate = cert_builder.sign(
|
||||
private_key=self.ca_private_key,
|
||||
algorithm=self.digest,
|
||||
)
|
||||
|
||||
self.cert = certificate
|
||||
|
||||
@@ -288,7 +275,7 @@ class OwnCACertificateBackendCryptography(CertificateBackend):
|
||||
"notAfter": get_not_valid_after(self.cert).strftime(
|
||||
"%Y%m%d%H%M%SZ"
|
||||
),
|
||||
"serial_number": cryptography_serial_number_of_cert(self.cert),
|
||||
"serial_number": self.cert.serial_number,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ from random import randrange
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
CRYPTOGRAPHY_TIMEZONE,
|
||||
cryptography_key_needs_digest_for_signing,
|
||||
cryptography_serial_number_of_cert,
|
||||
cryptography_verify_certificate_signature,
|
||||
get_not_valid_after,
|
||||
get_not_valid_before,
|
||||
@@ -34,7 +33,6 @@ from ansible_collections.community.crypto.plugins.module_utils.time import (
|
||||
try:
|
||||
import cryptography
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.serialization import Encoding
|
||||
except ImportError:
|
||||
pass
|
||||
@@ -90,17 +88,7 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
|
||||
self.module.fail_json(
|
||||
msg=f'Unsupported digest "{module.params["selfsigned_digest"]}"'
|
||||
)
|
||||
try:
|
||||
self.csr = csr.sign(self.privatekey, digest, default_backend())
|
||||
except TypeError as e:
|
||||
if (
|
||||
str(e) == "Algorithm must be a registered hash algorithm."
|
||||
and digest is None
|
||||
):
|
||||
self.module.fail_json(
|
||||
msg="Signing with Ed25519 and Ed448 keys requires cryptography 2.8 or newer."
|
||||
)
|
||||
raise
|
||||
self.csr = csr.sign(self.privatekey, digest)
|
||||
|
||||
if cryptography_key_needs_digest_for_signing(self.privatekey):
|
||||
if self.digest is None:
|
||||
@@ -139,21 +127,10 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
|
||||
except ValueError as e:
|
||||
raise CertificateError(str(e))
|
||||
|
||||
try:
|
||||
certificate = cert_builder.sign(
|
||||
private_key=self.privatekey,
|
||||
algorithm=self.digest,
|
||||
backend=default_backend(),
|
||||
)
|
||||
except TypeError as e:
|
||||
if (
|
||||
str(e) == "Algorithm must be a registered hash algorithm."
|
||||
and self.digest is None
|
||||
):
|
||||
self.module.fail_json(
|
||||
msg="Signing with Ed25519 and Ed448 keys requires cryptography 2.8 or newer."
|
||||
)
|
||||
raise
|
||||
certificate = cert_builder.sign(
|
||||
private_key=self.privatekey,
|
||||
algorithm=self.digest,
|
||||
)
|
||||
|
||||
self.cert = certificate
|
||||
|
||||
@@ -201,7 +178,7 @@ class SelfSignedCertificateBackendCryptography(CertificateBackend):
|
||||
"notAfter": get_not_valid_after(self.cert).strftime(
|
||||
"%Y%m%d%H%M%SZ"
|
||||
),
|
||||
"serial_number": cryptography_serial_number_of_cert(self.cert),
|
||||
"serial_number": self.cert.serial_number,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -26,13 +26,12 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
|
||||
# crypto_utils
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.2"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
import cryptography
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
|
||||
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
|
||||
except ImportError:
|
||||
@@ -54,9 +53,9 @@ class CRLInfoRetrieval:
|
||||
self.crl_pem = identify_pem_format(self.content)
|
||||
try:
|
||||
if self.crl_pem:
|
||||
self.crl = x509.load_pem_x509_crl(self.content, default_backend())
|
||||
self.crl = x509.load_pem_x509_crl(self.content)
|
||||
else:
|
||||
self.crl = x509.load_der_x509_crl(self.content, default_backend())
|
||||
self.crl = x509.load_der_x509_crl(self.content)
|
||||
except ValueError as e:
|
||||
self.module.fail_json(msg=f"Error while decoding CRL: {e}")
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.3"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
@@ -309,19 +309,11 @@ def parse_crl_distribution_points(module, crl_distribution_points):
|
||||
if parse_crl_distribution_point["relative_name"] is not None:
|
||||
if not parse_crl_distribution_point["relative_name"]:
|
||||
raise OpenSSLObjectError("relative_name must not be empty")
|
||||
try:
|
||||
params["relative_name"] = (
|
||||
cryptography_parse_relative_distinguished_name(
|
||||
parse_crl_distribution_point["relative_name"]
|
||||
)
|
||||
params["relative_name"] = (
|
||||
cryptography_parse_relative_distinguished_name(
|
||||
parse_crl_distribution_point["relative_name"]
|
||||
)
|
||||
except Exception:
|
||||
# If cryptography's version is < 1.6, the error is probably caused by that
|
||||
if CRYPTOGRAPHY_VERSION < LooseVersion("1.6"):
|
||||
raise OpenSSLObjectError(
|
||||
"Cannot specify relative_name for cryptography < 1.6"
|
||||
)
|
||||
raise
|
||||
)
|
||||
if parse_crl_distribution_point["crl_issuer"] is not None:
|
||||
if not parse_crl_distribution_point["crl_issuer"]:
|
||||
raise OpenSSLObjectError("crl_issuer must not be empty")
|
||||
@@ -348,7 +340,6 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
|
||||
super(CertificateSigningRequestCryptographyBackend, self).__init__(
|
||||
module, "cryptography"
|
||||
)
|
||||
self.cryptography_backend = cryptography.hazmat.backends.default_backend()
|
||||
if self.version != 1:
|
||||
module.warn(
|
||||
"The cryptography backend only supports version 1. (The only valid value according to RFC 2986.)"
|
||||
@@ -410,21 +401,12 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
|
||||
)
|
||||
|
||||
if self.ocspMustStaple:
|
||||
try:
|
||||
# This only works with cryptography >= 2.1
|
||||
csr = csr.add_extension(
|
||||
cryptography.x509.TLSFeature(
|
||||
[cryptography.x509.TLSFeatureType.status_request]
|
||||
),
|
||||
critical=self.ocspMustStaple_critical,
|
||||
)
|
||||
except AttributeError:
|
||||
csr = csr.add_extension(
|
||||
cryptography.x509.UnrecognizedExtension(
|
||||
CRYPTOGRAPHY_MUST_STAPLE_NAME, CRYPTOGRAPHY_MUST_STAPLE_VALUE
|
||||
),
|
||||
critical=self.ocspMustStaple_critical,
|
||||
)
|
||||
csr = csr.add_extension(
|
||||
cryptography.x509.TLSFeature(
|
||||
[cryptography.x509.TLSFeatureType.status_request]
|
||||
),
|
||||
critical=self.ocspMustStaple_critical,
|
||||
)
|
||||
|
||||
if self.name_constraints_permitted or self.name_constraints_excluded:
|
||||
try:
|
||||
@@ -493,16 +475,7 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
|
||||
f'Unsupported digest "{self.digest}"'
|
||||
)
|
||||
try:
|
||||
self.csr = csr.sign(self.privatekey, digest, self.cryptography_backend)
|
||||
except TypeError as e:
|
||||
if (
|
||||
str(e) == "Algorithm must be a registered hash algorithm."
|
||||
and digest is None
|
||||
):
|
||||
self.module.fail_json(
|
||||
msg="Signing with Ed25519 and Ed448 keys requires cryptography 2.8 or newer."
|
||||
)
|
||||
raise
|
||||
self.csr = csr.sign(self.privatekey, digest)
|
||||
except UnicodeError as e:
|
||||
# This catches IDNAErrors, which happens when a bad name is passed as a SAN
|
||||
# (https://github.com/ansible-collections/community.crypto/issues/105).
|
||||
@@ -636,22 +609,8 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
|
||||
return bc_ext is None
|
||||
|
||||
def _check_ocspMustStaple(extensions):
|
||||
try:
|
||||
# This only works with cryptography >= 2.1
|
||||
tlsfeature_ext = _find_extension(
|
||||
extensions, cryptography.x509.TLSFeature
|
||||
)
|
||||
has_tlsfeature = True
|
||||
except AttributeError:
|
||||
tlsfeature_ext = next(
|
||||
(
|
||||
ext
|
||||
for ext in extensions
|
||||
if ext.value.oid == CRYPTOGRAPHY_MUST_STAPLE_NAME
|
||||
),
|
||||
None,
|
||||
)
|
||||
has_tlsfeature = False
|
||||
tlsfeature_ext = _find_extension(extensions, cryptography.x509.TLSFeature)
|
||||
has_tlsfeature = True
|
||||
if self.ocspMustStaple:
|
||||
if (
|
||||
not tlsfeature_ext
|
||||
|
||||
@@ -29,7 +29,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.3"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
@@ -267,20 +267,13 @@ class CSRInfoRetrievalCryptography(CSRInfoRetrieval):
|
||||
|
||||
def _get_ocsp_must_staple(self):
|
||||
try:
|
||||
try:
|
||||
# This only works with cryptography >= 2.1
|
||||
tlsfeature_ext = self.csr.extensions.get_extension_for_class(
|
||||
x509.TLSFeature
|
||||
)
|
||||
value = (
|
||||
cryptography.x509.TLSFeatureType.status_request
|
||||
in tlsfeature_ext.value
|
||||
)
|
||||
except AttributeError:
|
||||
# Fallback for cryptography < 2.1
|
||||
oid = x509.oid.ObjectIdentifier("1.3.6.1.5.5.7.1.24")
|
||||
tlsfeature_ext = self.csr.extensions.get_extension_for_oid(oid)
|
||||
value = tlsfeature_ext.value.value == b"\x30\x03\x02\x01\x05"
|
||||
# This only works with cryptography >= 2.1
|
||||
tlsfeature_ext = self.csr.extensions.get_extension_for_class(
|
||||
x509.TLSFeature
|
||||
)
|
||||
value = (
|
||||
cryptography.x509.TLSFeatureType.status_request in tlsfeature_ext.value
|
||||
)
|
||||
return value, tlsfeature_ext.critical
|
||||
except cryptography.x509.ExtensionNotFound:
|
||||
return None, False
|
||||
|
||||
@@ -16,11 +16,6 @@ from ansible_collections.community.crypto.plugins.module_utils.argspec import (
|
||||
ArgumentSpec,
|
||||
)
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
CRYPTOGRAPHY_HAS_ED448,
|
||||
CRYPTOGRAPHY_HAS_ED25519,
|
||||
CRYPTOGRAPHY_HAS_X448,
|
||||
CRYPTOGRAPHY_HAS_X25519,
|
||||
CRYPTOGRAPHY_HAS_X25519_FULL,
|
||||
OpenSSLObjectError,
|
||||
)
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.privatekey_info import (
|
||||
@@ -39,7 +34,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.2.3"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
@@ -48,8 +43,12 @@ try:
|
||||
import cryptography.hazmat.backends
|
||||
import cryptography.hazmat.primitives.asymmetric.dsa
|
||||
import cryptography.hazmat.primitives.asymmetric.ec
|
||||
import cryptography.hazmat.primitives.asymmetric.ed448
|
||||
import cryptography.hazmat.primitives.asymmetric.ed25519
|
||||
import cryptography.hazmat.primitives.asymmetric.rsa
|
||||
import cryptography.hazmat.primitives.asymmetric.utils
|
||||
import cryptography.hazmat.primitives.asymmetric.x448
|
||||
import cryptography.hazmat.primitives.asymmetric.x25519
|
||||
import cryptography.hazmat.primitives.serialization
|
||||
|
||||
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
|
||||
@@ -320,27 +319,6 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
|
||||
self._add_curve("brainpoolP384r1", "BrainpoolP384R1", deprecated=True)
|
||||
self._add_curve("brainpoolP512r1", "BrainpoolP512R1", deprecated=True)
|
||||
|
||||
self.cryptography_backend = cryptography.hazmat.backends.default_backend()
|
||||
|
||||
if not CRYPTOGRAPHY_HAS_X25519 and self.type == "X25519":
|
||||
self.module.fail_json(
|
||||
msg="Your cryptography version does not support X25519"
|
||||
)
|
||||
if not CRYPTOGRAPHY_HAS_X25519_FULL and self.type == "X25519":
|
||||
self.module.fail_json(
|
||||
msg="Your cryptography version does not support X25519 serialization"
|
||||
)
|
||||
if not CRYPTOGRAPHY_HAS_X448 and self.type == "X448":
|
||||
self.module.fail_json(msg="Your cryptography version does not support X448")
|
||||
if not CRYPTOGRAPHY_HAS_ED25519 and self.type == "Ed25519":
|
||||
self.module.fail_json(
|
||||
msg="Your cryptography version does not support Ed25519"
|
||||
)
|
||||
if not CRYPTOGRAPHY_HAS_ED448 and self.type == "Ed448":
|
||||
self.module.fail_json(
|
||||
msg="Your cryptography version does not support Ed448"
|
||||
)
|
||||
|
||||
def _get_wanted_format(self):
|
||||
if self.format not in ("auto", "auto_ignore"):
|
||||
return self.format
|
||||
@@ -357,28 +335,27 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
|
||||
cryptography.hazmat.primitives.asymmetric.rsa.generate_private_key(
|
||||
public_exponent=65537, # OpenSSL always uses this
|
||||
key_size=self.size,
|
||||
backend=self.cryptography_backend,
|
||||
)
|
||||
)
|
||||
if self.type == "DSA":
|
||||
self.private_key = (
|
||||
cryptography.hazmat.primitives.asymmetric.dsa.generate_private_key(
|
||||
key_size=self.size, backend=self.cryptography_backend
|
||||
key_size=self.size
|
||||
)
|
||||
)
|
||||
if CRYPTOGRAPHY_HAS_X25519_FULL and self.type == "X25519":
|
||||
if self.type == "X25519":
|
||||
self.private_key = (
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.generate()
|
||||
)
|
||||
if CRYPTOGRAPHY_HAS_X448 and self.type == "X448":
|
||||
if self.type == "X448":
|
||||
self.private_key = (
|
||||
cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey.generate()
|
||||
)
|
||||
if CRYPTOGRAPHY_HAS_ED25519 and self.type == "Ed25519":
|
||||
if self.type == "Ed25519":
|
||||
self.private_key = (
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.generate()
|
||||
)
|
||||
if CRYPTOGRAPHY_HAS_ED448 and self.type == "Ed448":
|
||||
if self.type == "Ed448":
|
||||
self.private_key = (
|
||||
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey.generate()
|
||||
)
|
||||
@@ -390,7 +367,6 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
|
||||
self.private_key = (
|
||||
cryptography.hazmat.primitives.asymmetric.ec.generate_private_key(
|
||||
curve=self.curves[self.curve]["create"](self.size),
|
||||
backend=self.cryptography_backend,
|
||||
)
|
||||
)
|
||||
except cryptography.exceptions.UnsupportedAlgorithm:
|
||||
@@ -462,43 +438,37 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
|
||||
# Interpret bytes depending on format.
|
||||
format = identify_private_key_format(data)
|
||||
if format == "raw":
|
||||
if len(data) == 56 and CRYPTOGRAPHY_HAS_X448:
|
||||
if len(data) == 56:
|
||||
return cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey.from_private_bytes(
|
||||
data
|
||||
)
|
||||
if len(data) == 57 and CRYPTOGRAPHY_HAS_ED448:
|
||||
if len(data) == 57:
|
||||
return cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey.from_private_bytes(
|
||||
data
|
||||
)
|
||||
if len(data) == 32:
|
||||
if CRYPTOGRAPHY_HAS_X25519 and (
|
||||
self.type == "X25519" or not CRYPTOGRAPHY_HAS_ED25519
|
||||
):
|
||||
if self.type == "X25519":
|
||||
return cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
)
|
||||
if CRYPTOGRAPHY_HAS_ED25519 and (
|
||||
self.type == "Ed25519" or not CRYPTOGRAPHY_HAS_X25519
|
||||
):
|
||||
if self.type == "Ed25519":
|
||||
return cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
)
|
||||
try:
|
||||
return cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
)
|
||||
except Exception:
|
||||
return cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
)
|
||||
if CRYPTOGRAPHY_HAS_X25519 and CRYPTOGRAPHY_HAS_ED25519:
|
||||
try:
|
||||
return cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
)
|
||||
except Exception:
|
||||
return cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
)
|
||||
raise PrivateKeyError("Cannot load raw key")
|
||||
else:
|
||||
return (
|
||||
cryptography.hazmat.primitives.serialization.load_pem_private_key(
|
||||
data,
|
||||
None if self.passphrase is None else to_bytes(self.passphrase),
|
||||
backend=self.cryptography_backend,
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
@@ -523,7 +493,6 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
|
||||
cryptography.hazmat.primitives.serialization.load_pem_private_key(
|
||||
self.existing_private_key_bytes,
|
||||
None if self.passphrase is None else to_bytes(self.passphrase),
|
||||
backend=self.cryptography_backend,
|
||||
)
|
||||
)
|
||||
except Exception:
|
||||
@@ -544,22 +513,22 @@ class PrivateKeyCryptographyBackend(PrivateKeyBackend):
|
||||
return (
|
||||
self.type == "DSA" and self.size == self.existing_private_key.key_size
|
||||
)
|
||||
if CRYPTOGRAPHY_HAS_X25519 and isinstance(
|
||||
if isinstance(
|
||||
self.existing_private_key,
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey,
|
||||
):
|
||||
return self.type == "X25519"
|
||||
if CRYPTOGRAPHY_HAS_X448 and isinstance(
|
||||
if isinstance(
|
||||
self.existing_private_key,
|
||||
cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey,
|
||||
):
|
||||
return self.type == "X448"
|
||||
if CRYPTOGRAPHY_HAS_ED25519 and isinstance(
|
||||
if isinstance(
|
||||
self.existing_private_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey,
|
||||
):
|
||||
return self.type == "Ed25519"
|
||||
if CRYPTOGRAPHY_HAS_ED448 and isinstance(
|
||||
if isinstance(
|
||||
self.existing_private_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey,
|
||||
):
|
||||
|
||||
@@ -14,10 +14,6 @@ from ansible_collections.community.crypto.plugins.module_utils.argspec import (
|
||||
ArgumentSpec,
|
||||
)
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
CRYPTOGRAPHY_HAS_ED448,
|
||||
CRYPTOGRAPHY_HAS_ED25519,
|
||||
CRYPTOGRAPHY_HAS_X448,
|
||||
CRYPTOGRAPHY_HAS_X25519,
|
||||
OpenSSLObjectError,
|
||||
)
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
@@ -32,7 +28,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.2.3"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
@@ -41,8 +37,12 @@ try:
|
||||
import cryptography.hazmat.backends
|
||||
import cryptography.hazmat.primitives.asymmetric.dsa
|
||||
import cryptography.hazmat.primitives.asymmetric.ec
|
||||
import cryptography.hazmat.primitives.asymmetric.ed448
|
||||
import cryptography.hazmat.primitives.asymmetric.ed25519
|
||||
import cryptography.hazmat.primitives.asymmetric.rsa
|
||||
import cryptography.hazmat.primitives.asymmetric.utils
|
||||
import cryptography.hazmat.primitives.asymmetric.x448
|
||||
import cryptography.hazmat.primitives.asymmetric.x25519
|
||||
import cryptography.hazmat.primitives.serialization
|
||||
|
||||
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
|
||||
@@ -136,8 +136,6 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
|
||||
module=module, backend="cryptography"
|
||||
)
|
||||
|
||||
self.cryptography_backend = cryptography.hazmat.backends.default_backend()
|
||||
|
||||
def get_private_key_data(self):
|
||||
"""Return bytes for self.src_private_key in output format"""
|
||||
# Select export format and encoding
|
||||
@@ -199,14 +197,14 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
|
||||
if format == "raw":
|
||||
if passphrase is not None:
|
||||
raise PrivateKeyError("Cannot load raw key with passphrase")
|
||||
if len(data) == 56 and CRYPTOGRAPHY_HAS_X448:
|
||||
if len(data) == 56:
|
||||
return (
|
||||
format,
|
||||
cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey.from_private_bytes(
|
||||
data
|
||||
),
|
||||
)
|
||||
if len(data) == 57 and CRYPTOGRAPHY_HAS_ED448:
|
||||
if len(data) == 57:
|
||||
return (
|
||||
format,
|
||||
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey.from_private_bytes(
|
||||
@@ -214,54 +212,39 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
|
||||
),
|
||||
)
|
||||
if len(data) == 32:
|
||||
if CRYPTOGRAPHY_HAS_X25519 and not CRYPTOGRAPHY_HAS_ED25519:
|
||||
return (
|
||||
format,
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
),
|
||||
)
|
||||
if CRYPTOGRAPHY_HAS_ED25519 and not CRYPTOGRAPHY_HAS_X25519:
|
||||
return (
|
||||
format,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
),
|
||||
)
|
||||
if CRYPTOGRAPHY_HAS_X25519 and CRYPTOGRAPHY_HAS_ED25519:
|
||||
if isinstance(
|
||||
current_hint,
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey,
|
||||
):
|
||||
try:
|
||||
return (
|
||||
format,
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
),
|
||||
)
|
||||
except Exception:
|
||||
return (
|
||||
format,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
),
|
||||
)
|
||||
else:
|
||||
try:
|
||||
return (
|
||||
format,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
),
|
||||
)
|
||||
except Exception:
|
||||
return (
|
||||
format,
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
),
|
||||
)
|
||||
if isinstance(
|
||||
current_hint,
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey,
|
||||
):
|
||||
try:
|
||||
return (
|
||||
format,
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
),
|
||||
)
|
||||
except Exception:
|
||||
return (
|
||||
format,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
),
|
||||
)
|
||||
else:
|
||||
try:
|
||||
return (
|
||||
format,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
),
|
||||
)
|
||||
except Exception:
|
||||
return (
|
||||
format,
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
|
||||
data
|
||||
),
|
||||
)
|
||||
raise PrivateKeyError("Cannot load raw key")
|
||||
else:
|
||||
return (
|
||||
@@ -269,7 +252,6 @@ class PrivateKeyConvertCryptographyBackend(PrivateKeyConvertBackend):
|
||||
cryptography.hazmat.primitives.serialization.load_pem_private_key(
|
||||
data,
|
||||
None if passphrase is None else to_bytes(passphrase),
|
||||
backend=self.cryptography_backend,
|
||||
),
|
||||
)
|
||||
except Exception as e:
|
||||
|
||||
@@ -13,8 +13,6 @@ from ansible.module_utils import six
|
||||
from ansible.module_utils.basic import missing_required_lib
|
||||
from ansible.module_utils.common.text.converters import to_bytes, to_native
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
CRYPTOGRAPHY_HAS_ED448,
|
||||
CRYPTOGRAPHY_HAS_ED25519,
|
||||
OpenSSLObjectError,
|
||||
)
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.math import (
|
||||
@@ -33,7 +31,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.2.3"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
@@ -115,13 +113,9 @@ def _is_cryptography_key_consistent(
|
||||
result = _check_dsa_consistency(key_public_data, key_private_data)
|
||||
if result is not None:
|
||||
return result
|
||||
try:
|
||||
signature = key.sign(
|
||||
SIGNATURE_TEST_DATA, cryptography.hazmat.primitives.hashes.SHA256()
|
||||
)
|
||||
except AttributeError:
|
||||
# sign() was added in cryptography 1.5, but we support older versions
|
||||
return None
|
||||
signature = key.sign(
|
||||
SIGNATURE_TEST_DATA, cryptography.hazmat.primitives.hashes.SHA256()
|
||||
)
|
||||
try:
|
||||
key.public_key().verify(
|
||||
signature,
|
||||
@@ -134,16 +128,12 @@ def _is_cryptography_key_consistent(
|
||||
if isinstance(
|
||||
key, cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey
|
||||
):
|
||||
try:
|
||||
signature = key.sign(
|
||||
SIGNATURE_TEST_DATA,
|
||||
cryptography.hazmat.primitives.asymmetric.ec.ECDSA(
|
||||
cryptography.hazmat.primitives.hashes.SHA256()
|
||||
),
|
||||
)
|
||||
except AttributeError:
|
||||
# sign() was added in cryptography 1.5, but we support older versions
|
||||
return None
|
||||
signature = key.sign(
|
||||
SIGNATURE_TEST_DATA,
|
||||
cryptography.hazmat.primitives.asymmetric.ec.ECDSA(
|
||||
cryptography.hazmat.primitives.hashes.SHA256()
|
||||
),
|
||||
)
|
||||
try:
|
||||
key.public_key().verify(
|
||||
signature,
|
||||
@@ -156,13 +146,11 @@ def _is_cryptography_key_consistent(
|
||||
except cryptography.exceptions.InvalidSignature:
|
||||
return False
|
||||
has_simple_sign_function = False
|
||||
if CRYPTOGRAPHY_HAS_ED25519 and isinstance(
|
||||
if isinstance(
|
||||
key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey
|
||||
):
|
||||
has_simple_sign_function = True
|
||||
if CRYPTOGRAPHY_HAS_ED448 and isinstance(
|
||||
key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey
|
||||
):
|
||||
if isinstance(key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey):
|
||||
has_simple_sign_function = True
|
||||
if has_simple_sign_function:
|
||||
signature = key.sign(SIGNATURE_TEST_DATA)
|
||||
|
||||
@@ -11,10 +11,6 @@ from ansible.module_utils import six
|
||||
from ansible.module_utils.basic import missing_required_lib
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
CRYPTOGRAPHY_HAS_ED448,
|
||||
CRYPTOGRAPHY_HAS_ED25519,
|
||||
CRYPTOGRAPHY_HAS_X448,
|
||||
CRYPTOGRAPHY_HAS_X25519,
|
||||
OpenSSLObjectError,
|
||||
)
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
@@ -26,11 +22,15 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.2.3"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
import cryptography
|
||||
import cryptography.hazmat.primitives.asymmetric.ed448
|
||||
import cryptography.hazmat.primitives.asymmetric.ed25519
|
||||
import cryptography.hazmat.primitives.asymmetric.x448
|
||||
import cryptography.hazmat.primitives.asymmetric.x25519
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
|
||||
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
|
||||
@@ -58,19 +58,17 @@ def _get_cryptography_public_key_info(key):
|
||||
key_public_data["q"] = parameter_numbers.q
|
||||
key_public_data["g"] = parameter_numbers.g
|
||||
key_public_data["y"] = public_numbers.y
|
||||
elif CRYPTOGRAPHY_HAS_X25519 and isinstance(
|
||||
elif isinstance(
|
||||
key, cryptography.hazmat.primitives.asymmetric.x25519.X25519PublicKey
|
||||
):
|
||||
key_type = "X25519"
|
||||
elif CRYPTOGRAPHY_HAS_X448 and isinstance(
|
||||
key, cryptography.hazmat.primitives.asymmetric.x448.X448PublicKey
|
||||
):
|
||||
elif isinstance(key, cryptography.hazmat.primitives.asymmetric.x448.X448PublicKey):
|
||||
key_type = "X448"
|
||||
elif CRYPTOGRAPHY_HAS_ED25519 and isinstance(
|
||||
elif isinstance(
|
||||
key, cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey
|
||||
):
|
||||
key_type = "Ed25519"
|
||||
elif CRYPTOGRAPHY_HAS_ED448 and isinstance(
|
||||
elif isinstance(
|
||||
key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey
|
||||
):
|
||||
key_type = "Ed448"
|
||||
|
||||
@@ -26,7 +26,6 @@ from ansible_collections.community.crypto.plugins.module_utils.time import ( #
|
||||
|
||||
try:
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend as cryptography_backend
|
||||
from cryptography.hazmat.primitives import hashes, serialization
|
||||
from cryptography.hazmat.primitives.serialization import load_pem_private_key
|
||||
except ImportError:
|
||||
@@ -151,7 +150,6 @@ def load_privatekey(
|
||||
result = load_pem_private_key(
|
||||
priv_key_detail,
|
||||
None if passphrase is None else to_bytes(passphrase),
|
||||
cryptography_backend(),
|
||||
)
|
||||
except TypeError:
|
||||
raise OpenSSLBadPassphraseError(
|
||||
@@ -175,9 +173,7 @@ def load_publickey(path=None, content=None, backend=None):
|
||||
|
||||
if backend == "cryptography":
|
||||
try:
|
||||
return serialization.load_pem_public_key(
|
||||
content, backend=cryptography_backend()
|
||||
)
|
||||
return serialization.load_pem_public_key(content)
|
||||
except Exception as e:
|
||||
raise OpenSSLObjectError(f"Error while deserializing key: {e}")
|
||||
|
||||
@@ -198,16 +194,12 @@ def load_certificate(
|
||||
if backend == "cryptography":
|
||||
if der_support_enabled is False or identify_pem_format(cert_content):
|
||||
try:
|
||||
return x509.load_pem_x509_certificate(
|
||||
cert_content, cryptography_backend()
|
||||
)
|
||||
return x509.load_pem_x509_certificate(cert_content)
|
||||
except ValueError as exc:
|
||||
raise OpenSSLObjectError(exc)
|
||||
elif der_support_enabled:
|
||||
try:
|
||||
return x509.load_der_x509_certificate(
|
||||
cert_content, cryptography_backend()
|
||||
)
|
||||
return x509.load_der_x509_certificate(cert_content)
|
||||
except ValueError as exc:
|
||||
raise OpenSSLObjectError(f"Cannot parse DER certificate: {exc}")
|
||||
|
||||
@@ -224,7 +216,7 @@ def load_certificate_request(path, content=None, backend="cryptography"):
|
||||
raise OpenSSLObjectError(exc)
|
||||
if backend == "cryptography":
|
||||
try:
|
||||
return x509.load_pem_x509_csr(csr_content, cryptography_backend())
|
||||
return x509.load_pem_x509_csr(csr_content)
|
||||
except ValueError as exc:
|
||||
raise OpenSSLObjectError(exc)
|
||||
|
||||
|
||||
@@ -438,7 +438,7 @@ class KeypairBackendCryptography(KeypairBackend):
|
||||
if result == "SSH" and not HAS_OPENSSH_PRIVATE_FORMAT:
|
||||
self.module.fail_json(
|
||||
msg=missing_required_lib(
|
||||
"cryptography >= 3.0",
|
||||
"cryptography >= 3.4",
|
||||
reason="to load/dump private keys in the default OpenSSH format for OpenSSH >= 7.8 "
|
||||
+ "or for ed25519 keys",
|
||||
)
|
||||
@@ -549,7 +549,7 @@ def select_backend(module, backend):
|
||||
else:
|
||||
module.fail_json(
|
||||
msg="Cannot find either the OpenSSH binary in the PATH "
|
||||
+ "or cryptography >= 2.6 installed on this system"
|
||||
+ "or cryptography >= 3.4 installed on this system"
|
||||
)
|
||||
|
||||
if backend == "opensshbin":
|
||||
@@ -558,7 +558,7 @@ def select_backend(module, backend):
|
||||
return backend, KeypairBackendOpensshBin(module)
|
||||
elif backend == "cryptography":
|
||||
if not can_use_cryptography:
|
||||
module.fail_json(msg=missing_required_lib("cryptography >= 2.6"))
|
||||
module.fail_json(msg=missing_required_lib("cryptography >= 3.4"))
|
||||
return backend, KeypairBackendCryptography(module)
|
||||
else:
|
||||
raise ValueError(f"Unsupported value for backend: {backend}")
|
||||
|
||||
@@ -25,7 +25,7 @@ try:
|
||||
Ed25519PublicKey,
|
||||
)
|
||||
|
||||
if LooseVersion(CRYPTOGRAPHY_VERSION) >= LooseVersion("3.0"):
|
||||
if LooseVersion(CRYPTOGRAPHY_VERSION) >= LooseVersion("3.4"):
|
||||
HAS_OPENSSH_PRIVATE_FORMAT = True
|
||||
else:
|
||||
HAS_OPENSSH_PRIVATE_FORMAT = False
|
||||
|
||||
@@ -22,7 +22,7 @@ seealso:
|
||||
description: The specification of the C(tls-alpn-01) challenge (RFC 8737).
|
||||
link: https://www.rfc-editor.org/rfc/rfc8737.html
|
||||
requirements:
|
||||
- "cryptography >= 1.3"
|
||||
- "cryptography >= 3.4"
|
||||
extends_documentation_fragment:
|
||||
- community.crypto.attributes
|
||||
attributes:
|
||||
@@ -184,8 +184,7 @@ try:
|
||||
import cryptography.x509
|
||||
import cryptography.x509.oid
|
||||
|
||||
HAS_CRYPTOGRAPHY = LooseVersion(cryptography.__version__) >= LooseVersion("1.3")
|
||||
_cryptography_backend = cryptography.hazmat.backends.default_backend()
|
||||
HAS_CRYPTOGRAPHY = LooseVersion(cryptography.__version__) >= LooseVersion("3.4")
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_IMP_ERR = traceback.format_exc()
|
||||
HAS_CRYPTOGRAPHY = False
|
||||
@@ -216,10 +215,10 @@ def main():
|
||||
# Some callbacks die when exception is provided with value None
|
||||
if CRYPTOGRAPHY_IMP_ERR:
|
||||
module.fail_json(
|
||||
msg=missing_required_lib("cryptography >= 1.3"),
|
||||
msg=missing_required_lib("cryptography >= 3.4"),
|
||||
exception=CRYPTOGRAPHY_IMP_ERR,
|
||||
)
|
||||
module.fail_json(msg=missing_required_lib("cryptography >= 1.3"))
|
||||
module.fail_json(msg=missing_required_lib("cryptography >= 3.4"))
|
||||
|
||||
try:
|
||||
# Get parameters
|
||||
@@ -242,7 +241,6 @@ def main():
|
||||
if private_key_passphrase is not None
|
||||
else None
|
||||
),
|
||||
backend=_cryptography_backend,
|
||||
)
|
||||
)
|
||||
except Exception as e:
|
||||
@@ -283,7 +281,6 @@ def main():
|
||||
regular_certificate = cert_builder.sign(
|
||||
private_key,
|
||||
cryptography.hazmat.primitives.hashes.SHA256(),
|
||||
_cryptography_backend,
|
||||
)
|
||||
|
||||
# Process challenge
|
||||
@@ -312,7 +309,6 @@ def main():
|
||||
challenge_certificate = cert_builder.sign(
|
||||
private_key,
|
||||
cryptography.hazmat.primitives.hashes.SHA256(),
|
||||
_cryptography_backend,
|
||||
)
|
||||
|
||||
module.exit_json(
|
||||
|
||||
@@ -18,7 +18,7 @@ description:
|
||||
that the signature is correct. It ignores validity dates and key usage completely. If you need to verify that a generated
|
||||
chain is valid, please use C(openssl verify ...).
|
||||
requirements:
|
||||
- "cryptography >= 1.5"
|
||||
- "cryptography >= 3.4"
|
||||
extends_documentation_fragment:
|
||||
- community.crypto.attributes
|
||||
- community.crypto.attributes.idempotent_not_modify_state
|
||||
@@ -126,10 +126,6 @@ import traceback
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils.common.text.converters import to_bytes
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
CRYPTOGRAPHY_HAS_ED448_SIGN,
|
||||
CRYPTOGRAPHY_HAS_ED25519_SIGN,
|
||||
)
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.pem import (
|
||||
split_pem_list,
|
||||
)
|
||||
@@ -152,8 +148,7 @@ try:
|
||||
import cryptography.x509
|
||||
import cryptography.x509.oid
|
||||
|
||||
HAS_CRYPTOGRAPHY = LooseVersion(cryptography.__version__) >= LooseVersion("1.5")
|
||||
_cryptography_backend = cryptography.hazmat.backends.default_backend()
|
||||
HAS_CRYPTOGRAPHY = LooseVersion(cryptography.__version__) >= LooseVersion("3.4")
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_IMP_ERR = traceback.format_exc()
|
||||
HAS_CRYPTOGRAPHY = False
|
||||
@@ -201,12 +196,12 @@ def is_parent(module, cert, potential_parent):
|
||||
cert.cert.signature_hash_algorithm
|
||||
),
|
||||
)
|
||||
elif CRYPTOGRAPHY_HAS_ED25519_SIGN and isinstance(
|
||||
elif isinstance(
|
||||
public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
|
||||
):
|
||||
public_key.verify(cert.cert.signature, cert.cert.tbs_certificate_bytes)
|
||||
elif CRYPTOGRAPHY_HAS_ED448_SIGN and isinstance(
|
||||
elif isinstance(
|
||||
public_key, cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey
|
||||
):
|
||||
public_key.verify(cert.cert.signature, cert.cert.tbs_certificate_bytes)
|
||||
@@ -232,9 +227,7 @@ def parse_PEM_list(module, text, source, fail_on_error=True):
|
||||
for cert_pem in split_pem_list(text):
|
||||
# Try to load PEM certificate
|
||||
try:
|
||||
cert = cryptography.x509.load_pem_x509_certificate(
|
||||
to_bytes(cert_pem), _cryptography_backend
|
||||
)
|
||||
cert = cryptography.x509.load_pem_x509_certificate(to_bytes(cert_pem))
|
||||
result.append(Certificate(cert_pem, cert))
|
||||
except Exception as e:
|
||||
msg = f"Cannot parse certificate #{len(result) + 1} from {source}: {e}"
|
||||
@@ -338,7 +331,7 @@ def main():
|
||||
|
||||
if not HAS_CRYPTOGRAPHY:
|
||||
module.fail_json(
|
||||
msg=missing_required_lib("cryptography >= 1.5"),
|
||||
msg=missing_required_lib("cryptography >= 3.4"),
|
||||
exception=CRYPTOGRAPHY_IMP_ERR,
|
||||
)
|
||||
|
||||
|
||||
@@ -154,22 +154,6 @@ openssl:
|
||||
import traceback
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
CRYPTOGRAPHY_HAS_DSA,
|
||||
CRYPTOGRAPHY_HAS_DSA_SIGN,
|
||||
CRYPTOGRAPHY_HAS_EC,
|
||||
CRYPTOGRAPHY_HAS_EC_SIGN,
|
||||
CRYPTOGRAPHY_HAS_ED448,
|
||||
CRYPTOGRAPHY_HAS_ED448_SIGN,
|
||||
CRYPTOGRAPHY_HAS_ED25519,
|
||||
CRYPTOGRAPHY_HAS_ED25519_SIGN,
|
||||
CRYPTOGRAPHY_HAS_RSA,
|
||||
CRYPTOGRAPHY_HAS_RSA_SIGN,
|
||||
CRYPTOGRAPHY_HAS_X448,
|
||||
CRYPTOGRAPHY_HAS_X25519,
|
||||
CRYPTOGRAPHY_HAS_X25519_FULL,
|
||||
HAS_CRYPTOGRAPHY,
|
||||
)
|
||||
|
||||
|
||||
try:
|
||||
@@ -185,9 +169,11 @@ try:
|
||||
except ImportError:
|
||||
UnsupportedAlgorithm = Exception
|
||||
CryptographyInternalError = Exception
|
||||
HAS_CRYPTOGRAPHY = False
|
||||
CRYPTOGRAPHY_VERSION = None
|
||||
CRYPTOGRAPHY_IMP_ERR = traceback.format_exc()
|
||||
else:
|
||||
HAS_CRYPTOGRAPHY = True
|
||||
CRYPTOGRAPHY_VERSION = cryptography.__version__
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
|
||||
@@ -222,64 +208,153 @@ def add_crypto_information(module):
|
||||
result["python_cryptography_import_error"] = CRYPTOGRAPHY_IMP_ERR
|
||||
return result
|
||||
|
||||
has_ed25519 = CRYPTOGRAPHY_HAS_ED25519
|
||||
if has_ed25519:
|
||||
try:
|
||||
from cryptography.hazmat.primitives.asymmetric.ed25519 import (
|
||||
Ed25519PrivateKey,
|
||||
)
|
||||
# Test for DSA
|
||||
has_dsa = False
|
||||
has_dsa_sign = False
|
||||
try:
|
||||
# added in 0.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/dsa/
|
||||
import cryptography.hazmat.primitives.asymmetric.dsa
|
||||
|
||||
has_dsa = True
|
||||
try:
|
||||
# added later in 1.5
|
||||
cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey.sign
|
||||
has_dsa_sign = True
|
||||
except AttributeError:
|
||||
pass
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Test for RSA
|
||||
has_rsa = False
|
||||
has_rsa_sign = False
|
||||
try:
|
||||
# added in 0.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/
|
||||
import cryptography.hazmat.primitives.asymmetric.rsa
|
||||
|
||||
has_rsa = True
|
||||
try:
|
||||
# added later in 1.4
|
||||
cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey.sign
|
||||
has_rsa_sign = True
|
||||
except AttributeError:
|
||||
pass
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Test for Ed25519
|
||||
has_ed25519 = False
|
||||
has_ed25519_sign = False
|
||||
try:
|
||||
# added in 2.6 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ed25519/
|
||||
import cryptography.hazmat.primitives.asymmetric.ed25519
|
||||
from cryptography.hazmat.primitives.asymmetric.ed25519 import (
|
||||
Ed25519PrivateKey,
|
||||
)
|
||||
|
||||
try:
|
||||
Ed25519PrivateKey.from_private_bytes(b"")
|
||||
except ValueError:
|
||||
pass
|
||||
except UnsupportedAlgorithm:
|
||||
has_ed25519 = False
|
||||
|
||||
has_ed448 = CRYPTOGRAPHY_HAS_ED448
|
||||
if has_ed448:
|
||||
has_ed25519 = True
|
||||
try:
|
||||
from cryptography.hazmat.primitives.asymmetric.ed448 import Ed448PrivateKey
|
||||
# added with the primitive in 2.6
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey.sign
|
||||
has_ed25519_sign = True
|
||||
except AttributeError:
|
||||
pass
|
||||
except (ImportError, UnsupportedAlgorithm):
|
||||
pass
|
||||
|
||||
# Test for Ed448
|
||||
has_ed448 = False
|
||||
has_ed448_sign = False
|
||||
try:
|
||||
# added in 2.6 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ed448/
|
||||
import cryptography.hazmat.primitives.asymmetric.ed448
|
||||
from cryptography.hazmat.primitives.asymmetric.ed448 import Ed448PrivateKey
|
||||
|
||||
try:
|
||||
Ed448PrivateKey.from_private_bytes(b"")
|
||||
except ValueError:
|
||||
pass
|
||||
except UnsupportedAlgorithm:
|
||||
has_ed448 = False
|
||||
|
||||
has_x25519 = CRYPTOGRAPHY_HAS_X25519
|
||||
if has_x25519:
|
||||
has_ed448 = True
|
||||
try:
|
||||
from cryptography.hazmat.primitives.asymmetric.x25519 import (
|
||||
X25519PrivateKey,
|
||||
)
|
||||
# added with the primitive in 2.6
|
||||
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey.sign
|
||||
has_ed448_sign = True
|
||||
except AttributeError:
|
||||
pass
|
||||
except (ImportError, UnsupportedAlgorithm):
|
||||
pass
|
||||
|
||||
if CRYPTOGRAPHY_HAS_X25519_FULL:
|
||||
X25519PrivateKey.from_private_bytes(b"")
|
||||
# Test for X25519
|
||||
has_x25519 = False
|
||||
has_x25519_full = False
|
||||
try:
|
||||
# added in 2.0 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/x25519/
|
||||
import cryptography.hazmat.primitives.asymmetric.x25519
|
||||
|
||||
try:
|
||||
# added later in 2.5
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.private_bytes
|
||||
full = True
|
||||
except AttributeError:
|
||||
full = False
|
||||
|
||||
try:
|
||||
if full:
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.from_private_bytes(
|
||||
b""
|
||||
)
|
||||
else:
|
||||
# Some versions do not support serialization and deserialization - use generate() instead
|
||||
X25519PrivateKey.generate()
|
||||
cryptography.hazmat.primitives.asymmetric.x25519.X25519PrivateKey.generate()
|
||||
except ValueError:
|
||||
pass
|
||||
except UnsupportedAlgorithm:
|
||||
has_x25519 = False
|
||||
|
||||
has_x448 = CRYPTOGRAPHY_HAS_X448
|
||||
if has_x448:
|
||||
has_x25519 = True
|
||||
has_x25519_full = full
|
||||
except (ImportError, UnsupportedAlgorithm):
|
||||
pass
|
||||
|
||||
# Test for X448
|
||||
has_x448 = False
|
||||
try:
|
||||
# added in 2.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/x448/
|
||||
import cryptography.hazmat.primitives.asymmetric.x448
|
||||
|
||||
try:
|
||||
from cryptography.hazmat.primitives.asymmetric.x448 import X448PrivateKey
|
||||
|
||||
X448PrivateKey.from_private_bytes(b"")
|
||||
except ValueError:
|
||||
pass
|
||||
except UnsupportedAlgorithm:
|
||||
has_x448 = False
|
||||
|
||||
has_x448 = True
|
||||
except (ImportError, UnsupportedAlgorithm):
|
||||
pass
|
||||
|
||||
# Test for ECC
|
||||
has_ec = False
|
||||
has_ec_sign = False
|
||||
curves = []
|
||||
if CRYPTOGRAPHY_HAS_EC:
|
||||
import cryptography.hazmat.backends
|
||||
try:
|
||||
# added in 0.5 - https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/
|
||||
import cryptography.hazmat.primitives.asymmetric.ec
|
||||
|
||||
backend = cryptography.hazmat.backends.default_backend()
|
||||
has_ec = True
|
||||
try:
|
||||
# added later in 1.5
|
||||
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey.sign
|
||||
has_ec_sign = True
|
||||
except AttributeError:
|
||||
pass
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
for curve_name, constructor_name in CURVES:
|
||||
ecclass = cryptography.hazmat.primitives.asymmetric.ec.__dict__.get(
|
||||
constructor_name
|
||||
@@ -287,7 +362,7 @@ def add_crypto_information(module):
|
||||
if ecclass:
|
||||
try:
|
||||
cryptography.hazmat.primitives.asymmetric.ec.generate_private_key(
|
||||
curve=ecclass(), backend=backend
|
||||
curve=ecclass()
|
||||
)
|
||||
curves.append(curve_name)
|
||||
except UnsupportedAlgorithm:
|
||||
@@ -300,21 +375,22 @@ def add_crypto_information(module):
|
||||
# curves removed.
|
||||
pass
|
||||
|
||||
# Compose result
|
||||
info = {
|
||||
"version": CRYPTOGRAPHY_VERSION,
|
||||
"curves": curves,
|
||||
"has_ec": CRYPTOGRAPHY_HAS_EC,
|
||||
"has_ec_sign": CRYPTOGRAPHY_HAS_EC_SIGN,
|
||||
"has_ec": has_ec,
|
||||
"has_ec_sign": has_ec_sign,
|
||||
"has_ed25519": has_ed25519,
|
||||
"has_ed25519_sign": has_ed25519 and CRYPTOGRAPHY_HAS_ED25519_SIGN,
|
||||
"has_ed25519_sign": has_ed25519_sign,
|
||||
"has_ed448": has_ed448,
|
||||
"has_ed448_sign": has_ed448 and CRYPTOGRAPHY_HAS_ED448_SIGN,
|
||||
"has_dsa": CRYPTOGRAPHY_HAS_DSA,
|
||||
"has_dsa_sign": CRYPTOGRAPHY_HAS_DSA_SIGN,
|
||||
"has_rsa": CRYPTOGRAPHY_HAS_RSA,
|
||||
"has_rsa_sign": CRYPTOGRAPHY_HAS_RSA_SIGN,
|
||||
"has_ed448_sign": has_ed448_sign,
|
||||
"has_dsa": has_dsa,
|
||||
"has_dsa_sign": has_dsa_sign,
|
||||
"has_rsa": has_rsa,
|
||||
"has_rsa_sign": has_rsa_sign,
|
||||
"has_x25519": has_x25519,
|
||||
"has_x25519_serialization": has_x25519 and CRYPTOGRAPHY_HAS_X25519_FULL,
|
||||
"has_x25519_serialization": has_x25519 and has_x25519_full,
|
||||
"has_x448": has_x448,
|
||||
}
|
||||
result["python_cryptography_capabilities"] = info
|
||||
|
||||
@@ -20,7 +20,7 @@ description:
|
||||
notes:
|
||||
- O(path) must be specified as the output location of the certificate.
|
||||
requirements:
|
||||
- cryptography >= 1.6
|
||||
- cryptography >= 3.4
|
||||
extends_documentation_fragment:
|
||||
- community.crypto.attributes
|
||||
- community.crypto.attributes.files
|
||||
@@ -581,7 +581,7 @@ except ImportError:
|
||||
else:
|
||||
CRYPTOGRAPHY_FOUND = True
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.6"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
|
||||
def validate_cert_expiry(cert_expiry):
|
||||
|
||||
@@ -121,7 +121,7 @@ notes:
|
||||
- When using ca_cert on OS X it has been reported that in some conditions the validate will always succeed.
|
||||
requirements:
|
||||
- "Python >= 3.10 when O(get_certificate_chain=true)"
|
||||
- "cryptography >= 1.6"
|
||||
- "cryptography >= 3.4"
|
||||
|
||||
seealso:
|
||||
- plugin: community.crypto.to_serial
|
||||
@@ -292,14 +292,13 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.6"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
import cryptography
|
||||
import cryptography.exceptions
|
||||
import cryptography.x509
|
||||
from cryptography.hazmat.backends import default_backend as cryptography_backend
|
||||
|
||||
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
|
||||
except ImportError:
|
||||
@@ -528,9 +527,7 @@ def main():
|
||||
result["cert"] = cert
|
||||
|
||||
if backend == "cryptography":
|
||||
x509 = cryptography.x509.load_pem_x509_certificate(
|
||||
to_bytes(cert), cryptography_backend()
|
||||
)
|
||||
x509 = cryptography.x509.load_pem_x509_certificate(to_bytes(cert))
|
||||
result["subject"] = {}
|
||||
for attribute in x509.subject:
|
||||
result["subject"][cryptography_oid_to_name(attribute.oid, short=True)] = (
|
||||
|
||||
@@ -15,8 +15,7 @@ description:
|
||||
V(rsa), V(dsa), V(rsa1), V(ed25519) or V(ecdsa) private keys.
|
||||
requirements:
|
||||
- ssh-keygen (if O(backend=openssh))
|
||||
- cryptography >= 2.6 (if O(backend=cryptography) and OpenSSH < 7.8 is installed)
|
||||
- cryptography >= 3.0 (if O(backend=cryptography) and OpenSSH >= 7.8 is installed)
|
||||
- cryptography >= 3.4 (if O(backend=cryptography))
|
||||
extends_documentation_fragment:
|
||||
- ansible.builtin.files
|
||||
- community.crypto.attributes
|
||||
|
||||
@@ -15,7 +15,7 @@ description:
|
||||
- In case the CSR signature cannot be validated, the module will fail. In this case, all return variables are still returned.
|
||||
- It uses the cryptography python library to interact with OpenSSL.
|
||||
requirements:
|
||||
- cryptography >= 1.3
|
||||
- cryptography >= 3.4
|
||||
author:
|
||||
- Felix Fontein (@felixfontein)
|
||||
- Yanis Guenane (@Spredzy)
|
||||
|
||||
@@ -17,7 +17,7 @@ description:
|
||||
- The module can use the cryptography Python library, or the C(openssl) executable. By default, it tries to detect which
|
||||
one is available. This can be overridden with the O(select_crypto_backend) option.
|
||||
requirements:
|
||||
- Either cryptography >= 2.0
|
||||
- Either cryptography >= 3.4
|
||||
- Or OpenSSL binary C(openssl)
|
||||
author:
|
||||
- Thom Wiggers (@thomwiggers)
|
||||
@@ -148,7 +148,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "2.0"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
@@ -322,7 +322,6 @@ class DHParameterCryptography(DHParameterBase):
|
||||
|
||||
def __init__(self, module):
|
||||
super(DHParameterCryptography, self).__init__(module)
|
||||
self.crypto_backend = cryptography.hazmat.backends.default_backend()
|
||||
|
||||
def _do_generate(self, module):
|
||||
"""Actually generate the DH params."""
|
||||
@@ -330,7 +329,6 @@ class DHParameterCryptography(DHParameterBase):
|
||||
params = cryptography.hazmat.primitives.asymmetric.dh.generate_parameters(
|
||||
generator=2,
|
||||
key_size=self.size,
|
||||
backend=self.crypto_backend,
|
||||
)
|
||||
# Serialize parameters
|
||||
result = params.parameter_bytes(
|
||||
@@ -349,7 +347,7 @@ class DHParameterCryptography(DHParameterBase):
|
||||
with open(self.path, "rb") as f:
|
||||
data = f.read()
|
||||
params = cryptography.hazmat.primitives.serialization.load_pem_parameters(
|
||||
data, backend=self.crypto_backend
|
||||
data
|
||||
)
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
@@ -15,7 +15,7 @@ description:
|
||||
- This module allows one to (re-)generate PKCS#12.
|
||||
- The module uses the cryptography Python library.
|
||||
requirements:
|
||||
- cryptography >= 3.0
|
||||
- cryptography >= 3.4
|
||||
extends_documentation_fragment:
|
||||
- ansible.builtin.files
|
||||
- community.crypto.attributes
|
||||
@@ -305,7 +305,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.0"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
|
||||
@@ -17,7 +17,7 @@ description:
|
||||
V(none) is returned for RV(key_is_consistent).
|
||||
- It uses the cryptography python library to interact with OpenSSL.
|
||||
requirements:
|
||||
- cryptography >= 1.2.3
|
||||
- cryptography >= 3.4
|
||||
author:
|
||||
- Felix Fontein (@felixfontein)
|
||||
- Yanis Guenane (@Spredzy)
|
||||
|
||||
@@ -15,8 +15,7 @@ description:
|
||||
not supported), use the M(community.crypto.openssh_keypair) module to manage these.
|
||||
- The module uses the cryptography Python library.
|
||||
requirements:
|
||||
- cryptography >= 1.2.3 (older versions might work as well)
|
||||
- Needs cryptography >= 1.4 if O(format) is C(OpenSSH)
|
||||
- cryptography >= 3.4
|
||||
author:
|
||||
- Yanis Guenane (@Spredzy)
|
||||
- Felix Fontein (@felixfontein)
|
||||
@@ -211,13 +210,11 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.2.3"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION_OPENSSH = "1.4"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
import cryptography
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives import serialization as crypto_serialization
|
||||
|
||||
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
|
||||
@@ -354,7 +351,7 @@ class PublicKey(OpenSSLObject):
|
||||
if self.format == "OpenSSH":
|
||||
# Read and dump public key. Makes sure that the comment is stripped off.
|
||||
current_publickey = crypto_serialization.load_ssh_public_key(
|
||||
publickey_content, backend=default_backend()
|
||||
publickey_content
|
||||
)
|
||||
publickey_content = current_publickey.public_bytes(
|
||||
crypto_serialization.Encoding.OpenSSH,
|
||||
@@ -362,7 +359,7 @@ class PublicKey(OpenSSLObject):
|
||||
)
|
||||
else:
|
||||
current_publickey = crypto_serialization.load_pem_public_key(
|
||||
publickey_content, backend=default_backend()
|
||||
publickey_content
|
||||
)
|
||||
publickey_content = current_publickey.public_bytes(
|
||||
crypto_serialization.Encoding.PEM,
|
||||
@@ -442,16 +439,12 @@ def main():
|
||||
mutually_exclusive=(["privatekey_path", "privatekey_content"],),
|
||||
)
|
||||
|
||||
minimal_cryptography_version = MINIMAL_CRYPTOGRAPHY_VERSION
|
||||
if module.params["format"] == "OpenSSH":
|
||||
minimal_cryptography_version = MINIMAL_CRYPTOGRAPHY_VERSION_OPENSSH
|
||||
|
||||
backend = module.params["select_crypto_backend"]
|
||||
if backend == "auto":
|
||||
# Detection what is possible
|
||||
can_use_cryptography = (
|
||||
CRYPTOGRAPHY_FOUND
|
||||
and CRYPTOGRAPHY_VERSION >= LooseVersion(minimal_cryptography_version)
|
||||
and CRYPTOGRAPHY_VERSION >= LooseVersion(MINIMAL_CRYPTOGRAPHY_VERSION)
|
||||
)
|
||||
|
||||
# Decision
|
||||
@@ -461,7 +454,7 @@ def main():
|
||||
# Success?
|
||||
if backend == "auto":
|
||||
module.fail_json(
|
||||
msg=f"Cannot detect the required Python library cryptography (>= {minimal_cryptography_version})",
|
||||
msg=f"Cannot detect the required Python library cryptography (>= {MINIMAL_CRYPTOGRAPHY_VERSION})",
|
||||
)
|
||||
|
||||
if module.params["format"] == "OpenSSH" and backend != "cryptography":
|
||||
@@ -471,7 +464,7 @@ def main():
|
||||
if not CRYPTOGRAPHY_FOUND:
|
||||
module.fail_json(
|
||||
msg=missing_required_lib(
|
||||
f"cryptography >= {minimal_cryptography_version}"
|
||||
f"cryptography >= {MINIMAL_CRYPTOGRAPHY_VERSION}"
|
||||
),
|
||||
exception=CRYPTOGRAPHY_IMP_ERR,
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@ description:
|
||||
- It uses the cryptography python library to interact with OpenSSL.
|
||||
version_added: 1.7.0
|
||||
requirements:
|
||||
- cryptography >= 1.2.3
|
||||
- cryptography >= 3.4
|
||||
author:
|
||||
- Felix Fontein (@felixfontein)
|
||||
extends_documentation_fragment:
|
||||
|
||||
@@ -14,7 +14,7 @@ description:
|
||||
- This module allows one to sign data using a private key.
|
||||
- The module uses the cryptography Python library.
|
||||
requirements:
|
||||
- cryptography >= 1.4 (some key types require newer versions)
|
||||
- cryptography >= 3.4
|
||||
author:
|
||||
- Patrick Pichler (@aveexy)
|
||||
- Markus Teufelberger (@MarkusTeufelberger)
|
||||
@@ -62,10 +62,6 @@ options:
|
||||
type: str
|
||||
default: auto
|
||||
choices: [auto, cryptography]
|
||||
notes:
|
||||
- "When using the C(cryptography) backend, the following key types require at least the following C(cryptography) version:\n
|
||||
RSA keys: C(cryptography) >= 1.4\nDSA and ECDSA keys: C(cryptography) >= 1.5\ned448 and ed25519 keys: C(cryptography)
|
||||
>= 2.6."
|
||||
seealso:
|
||||
- module: community.crypto.openssl_signature_info
|
||||
- module: community.crypto.openssl_privatekey
|
||||
@@ -108,7 +104,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.4"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
@@ -126,11 +122,6 @@ else:
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
CRYPTOGRAPHY_HAS_DSA_SIGN,
|
||||
CRYPTOGRAPHY_HAS_EC_SIGN,
|
||||
CRYPTOGRAPHY_HAS_ED448_SIGN,
|
||||
CRYPTOGRAPHY_HAS_ED25519_SIGN,
|
||||
CRYPTOGRAPHY_HAS_RSA_SIGN,
|
||||
OpenSSLObjectError,
|
||||
)
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
@@ -191,42 +182,37 @@ class SignatureCryptography(SignatureBase):
|
||||
|
||||
signature = None
|
||||
|
||||
if CRYPTOGRAPHY_HAS_DSA_SIGN:
|
||||
if isinstance(
|
||||
private_key,
|
||||
cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey,
|
||||
):
|
||||
signature = private_key.sign(_in, _hash)
|
||||
if isinstance(
|
||||
private_key,
|
||||
cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKey,
|
||||
):
|
||||
signature = private_key.sign(_in, _hash)
|
||||
|
||||
if CRYPTOGRAPHY_HAS_EC_SIGN:
|
||||
if isinstance(
|
||||
private_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey,
|
||||
):
|
||||
signature = private_key.sign(
|
||||
_in, cryptography.hazmat.primitives.asymmetric.ec.ECDSA(_hash)
|
||||
)
|
||||
elif isinstance(
|
||||
private_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKey,
|
||||
):
|
||||
signature = private_key.sign(
|
||||
_in, cryptography.hazmat.primitives.asymmetric.ec.ECDSA(_hash)
|
||||
)
|
||||
|
||||
if CRYPTOGRAPHY_HAS_ED25519_SIGN:
|
||||
if isinstance(
|
||||
private_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey,
|
||||
):
|
||||
signature = private_key.sign(_in)
|
||||
elif isinstance(
|
||||
private_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PrivateKey,
|
||||
):
|
||||
signature = private_key.sign(_in)
|
||||
|
||||
if CRYPTOGRAPHY_HAS_ED448_SIGN:
|
||||
if isinstance(
|
||||
private_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey,
|
||||
):
|
||||
signature = private_key.sign(_in)
|
||||
elif isinstance(
|
||||
private_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PrivateKey,
|
||||
):
|
||||
signature = private_key.sign(_in)
|
||||
|
||||
if CRYPTOGRAPHY_HAS_RSA_SIGN:
|
||||
if isinstance(
|
||||
private_key,
|
||||
cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey,
|
||||
):
|
||||
signature = private_key.sign(_in, _padding, _hash)
|
||||
elif isinstance(
|
||||
private_key,
|
||||
cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey,
|
||||
):
|
||||
signature = private_key.sign(_in, _padding, _hash)
|
||||
|
||||
if signature is None:
|
||||
self.module.fail_json(
|
||||
|
||||
@@ -14,7 +14,7 @@ description:
|
||||
- This module allows one to verify a signature for a file by a certificate.
|
||||
- The module uses the cryptography Python library.
|
||||
requirements:
|
||||
- cryptography >= 1.4 (some key types require newer versions)
|
||||
- cryptography >= 3.4
|
||||
author:
|
||||
- Patrick Pichler (@aveexy)
|
||||
- Markus Teufelberger (@MarkusTeufelberger)
|
||||
@@ -51,10 +51,6 @@ options:
|
||||
type: str
|
||||
default: auto
|
||||
choices: [auto, cryptography]
|
||||
notes:
|
||||
- "When using the C(cryptography) backend, the following key types require at least the following C(cryptography) version:\n
|
||||
RSA keys: C(cryptography) >= 1.4\nDSA and ECDSA keys: C(cryptography) >= 1.5\ned448 and ed25519 keys: C(cryptography)
|
||||
>= 2.6."
|
||||
seealso:
|
||||
- module: community.crypto.openssl_signature
|
||||
- module: community.crypto.x509_certificate
|
||||
@@ -97,7 +93,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.4"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
@@ -115,11 +111,6 @@ else:
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
CRYPTOGRAPHY_HAS_DSA_SIGN,
|
||||
CRYPTOGRAPHY_HAS_EC_SIGN,
|
||||
CRYPTOGRAPHY_HAS_ED448_SIGN,
|
||||
CRYPTOGRAPHY_HAS_ED25519_SIGN,
|
||||
CRYPTOGRAPHY_HAS_RSA_SIGN,
|
||||
OpenSSLObjectError,
|
||||
)
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
@@ -181,74 +172,53 @@ class SignatureInfoCryptography(SignatureInfoBase):
|
||||
verified = False
|
||||
valid = False
|
||||
|
||||
if CRYPTOGRAPHY_HAS_DSA_SIGN:
|
||||
try:
|
||||
if isinstance(
|
||||
public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey,
|
||||
):
|
||||
public_key.verify(_signature, _in, _hash)
|
||||
verified = True
|
||||
valid = True
|
||||
except cryptography.exceptions.InvalidSignature:
|
||||
try:
|
||||
if isinstance(
|
||||
public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey,
|
||||
):
|
||||
public_key.verify(_signature, _in, _hash)
|
||||
verified = True
|
||||
valid = False
|
||||
valid = True
|
||||
|
||||
if CRYPTOGRAPHY_HAS_EC_SIGN:
|
||||
try:
|
||||
if isinstance(
|
||||
public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey,
|
||||
):
|
||||
public_key.verify(
|
||||
_signature,
|
||||
_in,
|
||||
cryptography.hazmat.primitives.asymmetric.ec.ECDSA(_hash),
|
||||
)
|
||||
verified = True
|
||||
valid = True
|
||||
except cryptography.exceptions.InvalidSignature:
|
||||
elif isinstance(
|
||||
public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey,
|
||||
):
|
||||
public_key.verify(
|
||||
_signature,
|
||||
_in,
|
||||
cryptography.hazmat.primitives.asymmetric.ec.ECDSA(_hash),
|
||||
)
|
||||
verified = True
|
||||
valid = False
|
||||
valid = True
|
||||
|
||||
if CRYPTOGRAPHY_HAS_ED25519_SIGN:
|
||||
try:
|
||||
if isinstance(
|
||||
public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
|
||||
):
|
||||
public_key.verify(_signature, _in)
|
||||
verified = True
|
||||
valid = True
|
||||
except cryptography.exceptions.InvalidSignature:
|
||||
elif isinstance(
|
||||
public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ed25519.Ed25519PublicKey,
|
||||
):
|
||||
public_key.verify(_signature, _in)
|
||||
verified = True
|
||||
valid = False
|
||||
valid = True
|
||||
|
||||
if CRYPTOGRAPHY_HAS_ED448_SIGN:
|
||||
try:
|
||||
if isinstance(
|
||||
public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey,
|
||||
):
|
||||
public_key.verify(_signature, _in)
|
||||
verified = True
|
||||
valid = True
|
||||
except cryptography.exceptions.InvalidSignature:
|
||||
elif isinstance(
|
||||
public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.ed448.Ed448PublicKey,
|
||||
):
|
||||
public_key.verify(_signature, _in)
|
||||
verified = True
|
||||
valid = False
|
||||
valid = True
|
||||
|
||||
if CRYPTOGRAPHY_HAS_RSA_SIGN:
|
||||
try:
|
||||
if isinstance(
|
||||
public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey,
|
||||
):
|
||||
public_key.verify(_signature, _in, _padding, _hash)
|
||||
verified = True
|
||||
valid = True
|
||||
except cryptography.exceptions.InvalidSignature:
|
||||
elif isinstance(
|
||||
public_key,
|
||||
cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey,
|
||||
):
|
||||
public_key.verify(_signature, _in, _padding, _hash)
|
||||
verified = True
|
||||
valid = False
|
||||
valid = True
|
||||
except cryptography.exceptions.InvalidSignature:
|
||||
verified = True
|
||||
valid = False
|
||||
|
||||
if not verified:
|
||||
self.module.fail_json(
|
||||
|
||||
@@ -85,8 +85,6 @@ seealso:
|
||||
- module: community.crypto.x509_certificate
|
||||
- module: community.crypto.x509_certificate_pipe
|
||||
- module: community.crypto.x509_certificate_info
|
||||
requirements:
|
||||
- cryptography >= 1.6 if O(verify_cert_parsable=true)
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
@@ -132,12 +130,11 @@ from ansible_collections.community.crypto.plugins.module_utils.io import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.6"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
import cryptography # noqa: F401, pylint: disable=unused-import
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.x509 import load_der_x509_certificate
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_IMP_ERR = traceback.format_exc()
|
||||
@@ -234,7 +231,7 @@ class X509CertificateConvertModule(OpenSSLObject):
|
||||
exception=CRYPTOGRAPHY_IMP_ERR,
|
||||
)
|
||||
try:
|
||||
load_der_x509_certificate(self.input, default_backend())
|
||||
load_der_x509_certificate(self.input)
|
||||
except Exception as exc:
|
||||
module.fail_json(msg=f"Error while parsing certificate: {exc}")
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ description:
|
||||
L(collections,https://docs.ansible.com/ansible/latest/user_guide/collections_using.html#using-collections-in-a-playbook)
|
||||
keyword, the new name M(community.crypto.x509_certificate_info) should be used to avoid a deprecation warning.
|
||||
requirements:
|
||||
- cryptography >= 1.6
|
||||
- cryptography >= 3.4
|
||||
author:
|
||||
- Felix Fontein (@felixfontein)
|
||||
- Yanis Guenane (@Spredzy)
|
||||
|
||||
@@ -15,7 +15,7 @@ description:
|
||||
- Certificates on the revocation list can be either specified by serial number and (optionally) their issuer, or as a path
|
||||
to a certificate file in PEM format.
|
||||
requirements:
|
||||
- cryptography >= 1.2
|
||||
- cryptography >= 3.4
|
||||
author:
|
||||
- Felix Fontein (@felixfontein)
|
||||
extends_documentation_fragment:
|
||||
@@ -455,7 +455,6 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptograp
|
||||
cryptography_key_needs_digest_for_signing,
|
||||
cryptography_name_to_oid,
|
||||
cryptography_oid_to_name,
|
||||
cryptography_serial_number_of_cert,
|
||||
)
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.crl_info import (
|
||||
get_crl_info,
|
||||
@@ -483,13 +482,12 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.2"
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "3.4"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
import cryptography
|
||||
from cryptography import x509
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.hazmat.primitives.serialization import Encoding
|
||||
from cryptography.x509 import (
|
||||
CertificateRevocationListBuilder,
|
||||
@@ -585,7 +583,7 @@ class CRL(OpenSSLObject):
|
||||
cert = load_certificate(
|
||||
rc["path"], content=rc["content"], backend="cryptography"
|
||||
)
|
||||
result["serial_number"] = cryptography_serial_number_of_cert(cert)
|
||||
result["serial_number"] = cert.serial_number
|
||||
except OpenSSLObjectError as e:
|
||||
if rc["content"] is not None:
|
||||
module.fail_json(
|
||||
@@ -642,11 +640,11 @@ class CRL(OpenSSLObject):
|
||||
data = f.read()
|
||||
self.actual_format = "pem" if identify_pem_format(data) else "der"
|
||||
if self.actual_format == "pem":
|
||||
self.crl = x509.load_pem_x509_crl(data, default_backend())
|
||||
self.crl = x509.load_pem_x509_crl(data)
|
||||
if self.return_content:
|
||||
self.crl_content = data
|
||||
else:
|
||||
self.crl = x509.load_der_x509_crl(data, default_backend())
|
||||
self.crl = x509.load_der_x509_crl(data)
|
||||
if self.return_content:
|
||||
self.crl_content = base64.b64encode(data)
|
||||
except Exception:
|
||||
@@ -783,7 +781,6 @@ class CRL(OpenSSLObject):
|
||||
return True
|
||||
|
||||
def _generate_crl(self):
|
||||
backend = default_backend()
|
||||
crl = CertificateRevocationListBuilder()
|
||||
|
||||
try:
|
||||
@@ -830,12 +827,12 @@ class CRL(OpenSSLObject):
|
||||
x509.InvalidityDate(entry["invalidity_date"]),
|
||||
entry["invalidity_date_critical"],
|
||||
)
|
||||
crl = crl.add_revoked_certificate(revoked_cert.build(backend))
|
||||
crl = crl.add_revoked_certificate(revoked_cert.build())
|
||||
|
||||
digest = None
|
||||
if cryptography_key_needs_digest_for_signing(self.privatekey):
|
||||
digest = self.digest
|
||||
self.crl = crl.sign(self.privatekey, digest, backend=backend)
|
||||
self.crl = crl.sign(self.privatekey, digest)
|
||||
if self.format == "pem":
|
||||
return self.crl.public_bytes(Encoding.PEM)
|
||||
else:
|
||||
|
||||
@@ -13,7 +13,7 @@ short_description: Retrieve information on Certificate Revocation Lists (CRLs)
|
||||
description:
|
||||
- This module allows one to retrieve information on Certificate Revocation Lists (CRLs).
|
||||
requirements:
|
||||
- cryptography >= 1.2
|
||||
- cryptography >= 3.4
|
||||
author:
|
||||
- Felix Fontein (@felixfontein)
|
||||
extends_documentation_fragment:
|
||||
|
||||
Reference in New Issue
Block a user