mirror of
https://github.com/ansible-collections/community.crypto.git
synced 2026-05-07 13:53:06 +00:00
Reformat everything with black.
I had to undo the u string prefix removals to not drop Python 2 compatibility. That's why black isn't enabled in antsibull-nox.toml yet.
This commit is contained in:
@@ -51,7 +51,7 @@ from ansible_collections.community.crypto.plugins.module_utils.version import (
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = '1.3'
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = "1.3"
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
@@ -62,13 +62,16 @@ try:
|
||||
import cryptography.hazmat.primitives.serialization
|
||||
import cryptography.x509
|
||||
import cryptography.x509.oid
|
||||
|
||||
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_IMP_ERR = traceback.format_exc()
|
||||
CRYPTOGRAPHY_FOUND = False
|
||||
else:
|
||||
CRYPTOGRAPHY_FOUND = True
|
||||
CRYPTOGRAPHY_MUST_STAPLE_NAME = cryptography.x509.oid.ObjectIdentifier("1.3.6.1.5.5.7.1.24")
|
||||
CRYPTOGRAPHY_MUST_STAPLE_NAME = cryptography.x509.oid.ObjectIdentifier(
|
||||
"1.3.6.1.5.5.7.1.24"
|
||||
)
|
||||
CRYPTOGRAPHY_MUST_STAPLE_VALUE = b"\x30\x03\x02\x01\x05"
|
||||
|
||||
|
||||
@@ -88,80 +91,107 @@ class CertificateSigningRequestBackend(object):
|
||||
def __init__(self, module, backend):
|
||||
self.module = module
|
||||
self.backend = backend
|
||||
self.digest = module.params['digest']
|
||||
self.privatekey_path = module.params['privatekey_path']
|
||||
self.privatekey_content = module.params['privatekey_content']
|
||||
self.digest = module.params["digest"]
|
||||
self.privatekey_path = module.params["privatekey_path"]
|
||||
self.privatekey_content = module.params["privatekey_content"]
|
||||
if self.privatekey_content is not None:
|
||||
self.privatekey_content = self.privatekey_content.encode('utf-8')
|
||||
self.privatekey_passphrase = module.params['privatekey_passphrase']
|
||||
self.version = module.params['version']
|
||||
self.subjectAltName = module.params['subject_alt_name']
|
||||
self.subjectAltName_critical = module.params['subject_alt_name_critical']
|
||||
self.keyUsage = module.params['key_usage']
|
||||
self.keyUsage_critical = module.params['key_usage_critical']
|
||||
self.extendedKeyUsage = module.params['extended_key_usage']
|
||||
self.extendedKeyUsage_critical = module.params['extended_key_usage_critical']
|
||||
self.basicConstraints = module.params['basic_constraints']
|
||||
self.basicConstraints_critical = module.params['basic_constraints_critical']
|
||||
self.ocspMustStaple = module.params['ocsp_must_staple']
|
||||
self.ocspMustStaple_critical = module.params['ocsp_must_staple_critical']
|
||||
self.name_constraints_permitted = module.params['name_constraints_permitted'] or []
|
||||
self.name_constraints_excluded = module.params['name_constraints_excluded'] or []
|
||||
self.name_constraints_critical = module.params['name_constraints_critical']
|
||||
self.create_subject_key_identifier = module.params['create_subject_key_identifier']
|
||||
self.subject_key_identifier = module.params['subject_key_identifier']
|
||||
self.authority_key_identifier = module.params['authority_key_identifier']
|
||||
self.authority_cert_issuer = module.params['authority_cert_issuer']
|
||||
self.authority_cert_serial_number = module.params['authority_cert_serial_number']
|
||||
self.crl_distribution_points = module.params['crl_distribution_points']
|
||||
self.privatekey_content = self.privatekey_content.encode("utf-8")
|
||||
self.privatekey_passphrase = module.params["privatekey_passphrase"]
|
||||
self.version = module.params["version"]
|
||||
self.subjectAltName = module.params["subject_alt_name"]
|
||||
self.subjectAltName_critical = module.params["subject_alt_name_critical"]
|
||||
self.keyUsage = module.params["key_usage"]
|
||||
self.keyUsage_critical = module.params["key_usage_critical"]
|
||||
self.extendedKeyUsage = module.params["extended_key_usage"]
|
||||
self.extendedKeyUsage_critical = module.params["extended_key_usage_critical"]
|
||||
self.basicConstraints = module.params["basic_constraints"]
|
||||
self.basicConstraints_critical = module.params["basic_constraints_critical"]
|
||||
self.ocspMustStaple = module.params["ocsp_must_staple"]
|
||||
self.ocspMustStaple_critical = module.params["ocsp_must_staple_critical"]
|
||||
self.name_constraints_permitted = (
|
||||
module.params["name_constraints_permitted"] or []
|
||||
)
|
||||
self.name_constraints_excluded = (
|
||||
module.params["name_constraints_excluded"] or []
|
||||
)
|
||||
self.name_constraints_critical = module.params["name_constraints_critical"]
|
||||
self.create_subject_key_identifier = module.params[
|
||||
"create_subject_key_identifier"
|
||||
]
|
||||
self.subject_key_identifier = module.params["subject_key_identifier"]
|
||||
self.authority_key_identifier = module.params["authority_key_identifier"]
|
||||
self.authority_cert_issuer = module.params["authority_cert_issuer"]
|
||||
self.authority_cert_serial_number = module.params[
|
||||
"authority_cert_serial_number"
|
||||
]
|
||||
self.crl_distribution_points = module.params["crl_distribution_points"]
|
||||
self.csr = None
|
||||
self.privatekey = None
|
||||
|
||||
if self.create_subject_key_identifier and self.subject_key_identifier is not None:
|
||||
module.fail_json(msg='subject_key_identifier cannot be specified if create_subject_key_identifier is true')
|
||||
if (
|
||||
self.create_subject_key_identifier
|
||||
and self.subject_key_identifier is not None
|
||||
):
|
||||
module.fail_json(
|
||||
msg="subject_key_identifier cannot be specified if create_subject_key_identifier is true"
|
||||
)
|
||||
|
||||
self.ordered_subject = False
|
||||
self.subject = [
|
||||
('C', module.params['country_name']),
|
||||
('ST', module.params['state_or_province_name']),
|
||||
('L', module.params['locality_name']),
|
||||
('O', module.params['organization_name']),
|
||||
('OU', module.params['organizational_unit_name']),
|
||||
('CN', module.params['common_name']),
|
||||
('emailAddress', module.params['email_address']),
|
||||
("C", module.params["country_name"]),
|
||||
("ST", module.params["state_or_province_name"]),
|
||||
("L", module.params["locality_name"]),
|
||||
("O", module.params["organization_name"]),
|
||||
("OU", module.params["organizational_unit_name"]),
|
||||
("CN", module.params["common_name"]),
|
||||
("emailAddress", module.params["email_address"]),
|
||||
]
|
||||
self.subject = [(entry[0], entry[1]) for entry in self.subject if entry[1]]
|
||||
|
||||
try:
|
||||
if module.params['subject']:
|
||||
self.subject = self.subject + parse_name_field(module.params['subject'], 'subject')
|
||||
if module.params['subject_ordered']:
|
||||
if module.params["subject"]:
|
||||
self.subject = self.subject + parse_name_field(
|
||||
module.params["subject"], "subject"
|
||||
)
|
||||
if module.params["subject_ordered"]:
|
||||
if self.subject:
|
||||
raise CertificateSigningRequestError('subject_ordered cannot be combined with any other subject field')
|
||||
self.subject = parse_ordered_name_field(module.params['subject_ordered'], 'subject_ordered')
|
||||
raise CertificateSigningRequestError(
|
||||
"subject_ordered cannot be combined with any other subject field"
|
||||
)
|
||||
self.subject = parse_ordered_name_field(
|
||||
module.params["subject_ordered"], "subject_ordered"
|
||||
)
|
||||
self.ordered_subject = True
|
||||
except ValueError as exc:
|
||||
raise CertificateSigningRequestError(to_native(exc))
|
||||
|
||||
self.using_common_name_for_san = False
|
||||
if not self.subjectAltName and module.params['use_common_name_for_san']:
|
||||
if not self.subjectAltName and module.params["use_common_name_for_san"]:
|
||||
for sub in self.subject:
|
||||
if sub[0] in ('commonName', 'CN'):
|
||||
self.subjectAltName = ['DNS:%s' % sub[1]]
|
||||
if sub[0] in ("commonName", "CN"):
|
||||
self.subjectAltName = ["DNS:%s" % sub[1]]
|
||||
self.using_common_name_for_san = True
|
||||
break
|
||||
|
||||
if self.subject_key_identifier is not None:
|
||||
try:
|
||||
self.subject_key_identifier = binascii.unhexlify(self.subject_key_identifier.replace(':', ''))
|
||||
self.subject_key_identifier = binascii.unhexlify(
|
||||
self.subject_key_identifier.replace(":", "")
|
||||
)
|
||||
except Exception as e:
|
||||
raise CertificateSigningRequestError('Cannot parse subject_key_identifier: {0}'.format(e))
|
||||
raise CertificateSigningRequestError(
|
||||
"Cannot parse subject_key_identifier: {0}".format(e)
|
||||
)
|
||||
|
||||
if self.authority_key_identifier is not None:
|
||||
try:
|
||||
self.authority_key_identifier = binascii.unhexlify(self.authority_key_identifier.replace(':', ''))
|
||||
self.authority_key_identifier = binascii.unhexlify(
|
||||
self.authority_key_identifier.replace(":", "")
|
||||
)
|
||||
except Exception as e:
|
||||
raise CertificateSigningRequestError('Cannot parse authority_key_identifier: {0}'.format(e))
|
||||
raise CertificateSigningRequestError(
|
||||
"Cannot parse authority_key_identifier: {0}".format(e)
|
||||
)
|
||||
|
||||
self.existing_csr = None
|
||||
self.existing_csr_bytes = None
|
||||
@@ -174,8 +204,13 @@ class CertificateSigningRequestBackend(object):
|
||||
return dict()
|
||||
try:
|
||||
result = get_csr_info(
|
||||
self.module, self.backend, data, validate_signature=False, prefer_one_fingerprint=True)
|
||||
result['can_parse_csr'] = True
|
||||
self.module,
|
||||
self.backend,
|
||||
data,
|
||||
validate_signature=False,
|
||||
prefer_one_fingerprint=True,
|
||||
)
|
||||
result["can_parse_csr"] = True
|
||||
return result
|
||||
except Exception:
|
||||
return dict(can_parse_csr=False)
|
||||
@@ -223,7 +258,9 @@ class CertificateSigningRequestBackend(object):
|
||||
if self.existing_csr_bytes is None:
|
||||
return True
|
||||
try:
|
||||
self.existing_csr = load_certificate_request(None, content=self.existing_csr_bytes, backend=self.backend)
|
||||
self.existing_csr = load_certificate_request(
|
||||
None, content=self.existing_csr_bytes, backend=self.backend
|
||||
)
|
||||
except Exception:
|
||||
return True
|
||||
self._ensure_private_key_loaded()
|
||||
@@ -232,15 +269,15 @@ class CertificateSigningRequestBackend(object):
|
||||
def dump(self, include_csr):
|
||||
"""Serialize the object into a dictionary."""
|
||||
result = {
|
||||
'privatekey': self.privatekey_path,
|
||||
'subject': self.subject,
|
||||
'subjectAltName': self.subjectAltName,
|
||||
'keyUsage': self.keyUsage,
|
||||
'extendedKeyUsage': self.extendedKeyUsage,
|
||||
'basicConstraints': self.basicConstraints,
|
||||
'ocspMustStaple': self.ocspMustStaple,
|
||||
'name_constraints_permitted': self.name_constraints_permitted,
|
||||
'name_constraints_excluded': self.name_constraints_excluded,
|
||||
"privatekey": self.privatekey_path,
|
||||
"subject": self.subject,
|
||||
"subjectAltName": self.subjectAltName,
|
||||
"keyUsage": self.keyUsage,
|
||||
"extendedKeyUsage": self.extendedKeyUsage,
|
||||
"basicConstraints": self.basicConstraints,
|
||||
"ocspMustStaple": self.ocspMustStaple,
|
||||
"name_constraints_permitted": self.name_constraints_permitted,
|
||||
"name_constraints_excluded": self.name_constraints_excluded,
|
||||
}
|
||||
# Get hold of CSR bytes
|
||||
csr_bytes = self.existing_csr_bytes
|
||||
@@ -249,9 +286,9 @@ class CertificateSigningRequestBackend(object):
|
||||
self.diff_after = self._get_info(csr_bytes)
|
||||
if include_csr:
|
||||
# Store result
|
||||
result['csr'] = csr_bytes.decode('utf-8') if csr_bytes else None
|
||||
result["csr"] = csr_bytes.decode("utf-8") if csr_bytes else None
|
||||
|
||||
result['diff'] = dict(
|
||||
result["diff"] = dict(
|
||||
before=self.diff_before,
|
||||
after=self.diff_after,
|
||||
)
|
||||
@@ -268,45 +305,67 @@ def parse_crl_distribution_points(module, crl_distribution_points):
|
||||
crl_issuer=None,
|
||||
reasons=None,
|
||||
)
|
||||
if parse_crl_distribution_point['full_name'] is not None:
|
||||
if not parse_crl_distribution_point['full_name']:
|
||||
raise OpenSSLObjectError('full_name must not be empty')
|
||||
params['full_name'] = [cryptography_get_name(name, 'full name') for name in parse_crl_distribution_point['full_name']]
|
||||
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')
|
||||
if parse_crl_distribution_point["full_name"] is not None:
|
||||
if not parse_crl_distribution_point["full_name"]:
|
||||
raise OpenSSLObjectError("full_name must not be empty")
|
||||
params["full_name"] = [
|
||||
cryptography_get_name(name, "full name")
|
||||
for name in parse_crl_distribution_point["full_name"]
|
||||
]
|
||||
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')
|
||||
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')
|
||||
params['crl_issuer'] = [cryptography_get_name(name, 'CRL issuer') for name in parse_crl_distribution_point['crl_issuer']]
|
||||
if parse_crl_distribution_point['reasons'] is not None:
|
||||
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")
|
||||
params["crl_issuer"] = [
|
||||
cryptography_get_name(name, "CRL issuer")
|
||||
for name in parse_crl_distribution_point["crl_issuer"]
|
||||
]
|
||||
if parse_crl_distribution_point["reasons"] is not None:
|
||||
reasons = []
|
||||
for reason in parse_crl_distribution_point['reasons']:
|
||||
for reason in parse_crl_distribution_point["reasons"]:
|
||||
reasons.append(REVOCATION_REASON_MAP[reason])
|
||||
params['reasons'] = frozenset(reasons)
|
||||
params["reasons"] = frozenset(reasons)
|
||||
result.append(cryptography.x509.DistributionPoint(**params))
|
||||
except (OpenSSLObjectError, ValueError) as e:
|
||||
raise OpenSSLObjectError('Error while parsing CRL distribution point #{index}: {error}'.format(index=index, error=e))
|
||||
raise OpenSSLObjectError(
|
||||
"Error while parsing CRL distribution point #{index}: {error}".format(
|
||||
index=index, error=e
|
||||
)
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
# Implementation with using cryptography
|
||||
class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBackend):
|
||||
def __init__(self, module):
|
||||
super(CertificateSigningRequestCryptographyBackend, self).__init__(module, 'cryptography')
|
||||
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.)')
|
||||
module.warn(
|
||||
"The cryptography backend only supports version 1. (The only valid value according to RFC 2986.)"
|
||||
)
|
||||
|
||||
if self.crl_distribution_points:
|
||||
self.crl_distribution_points = parse_crl_distribution_points(module, self.crl_distribution_points)
|
||||
self.crl_distribution_points = parse_crl_distribution_points(
|
||||
module, self.crl_distribution_points
|
||||
)
|
||||
|
||||
def generate_csr(self):
|
||||
"""(Re-)Generate CSR."""
|
||||
@@ -314,82 +373,145 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
|
||||
|
||||
csr = cryptography.x509.CertificateSigningRequestBuilder()
|
||||
try:
|
||||
csr = csr.subject_name(cryptography.x509.Name([
|
||||
cryptography.x509.NameAttribute(cryptography_name_to_oid(entry[0]), to_text(entry[1])) for entry in self.subject
|
||||
]))
|
||||
csr = csr.subject_name(
|
||||
cryptography.x509.Name(
|
||||
[
|
||||
cryptography.x509.NameAttribute(
|
||||
cryptography_name_to_oid(entry[0]), to_text(entry[1])
|
||||
)
|
||||
for entry in self.subject
|
||||
]
|
||||
)
|
||||
)
|
||||
except ValueError as e:
|
||||
raise CertificateSigningRequestError(e)
|
||||
|
||||
if self.subjectAltName:
|
||||
csr = csr.add_extension(cryptography.x509.SubjectAlternativeName([
|
||||
cryptography_get_name(name) for name in self.subjectAltName
|
||||
]), critical=self.subjectAltName_critical)
|
||||
csr = csr.add_extension(
|
||||
cryptography.x509.SubjectAlternativeName(
|
||||
[cryptography_get_name(name) for name in self.subjectAltName]
|
||||
),
|
||||
critical=self.subjectAltName_critical,
|
||||
)
|
||||
|
||||
if self.keyUsage:
|
||||
params = cryptography_parse_key_usage_params(self.keyUsage)
|
||||
csr = csr.add_extension(cryptography.x509.KeyUsage(**params), critical=self.keyUsage_critical)
|
||||
csr = csr.add_extension(
|
||||
cryptography.x509.KeyUsage(**params), critical=self.keyUsage_critical
|
||||
)
|
||||
|
||||
if self.extendedKeyUsage:
|
||||
usages = [cryptography_name_to_oid(usage) for usage in self.extendedKeyUsage]
|
||||
csr = csr.add_extension(cryptography.x509.ExtendedKeyUsage(usages), critical=self.extendedKeyUsage_critical)
|
||||
usages = [
|
||||
cryptography_name_to_oid(usage) for usage in self.extendedKeyUsage
|
||||
]
|
||||
csr = csr.add_extension(
|
||||
cryptography.x509.ExtendedKeyUsage(usages),
|
||||
critical=self.extendedKeyUsage_critical,
|
||||
)
|
||||
|
||||
if self.basicConstraints:
|
||||
params = {}
|
||||
ca, path_length = cryptography_get_basic_constraints(self.basicConstraints)
|
||||
csr = csr.add_extension(cryptography.x509.BasicConstraints(ca, path_length), critical=self.basicConstraints_critical)
|
||||
csr = csr.add_extension(
|
||||
cryptography.x509.BasicConstraints(ca, path_length),
|
||||
critical=self.basicConstraints_critical,
|
||||
)
|
||||
|
||||
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)
|
||||
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
|
||||
cryptography.x509.UnrecognizedExtension(
|
||||
CRYPTOGRAPHY_MUST_STAPLE_NAME, CRYPTOGRAPHY_MUST_STAPLE_VALUE
|
||||
),
|
||||
critical=self.ocspMustStaple_critical,
|
||||
)
|
||||
|
||||
if self.name_constraints_permitted or self.name_constraints_excluded:
|
||||
try:
|
||||
csr = csr.add_extension(cryptography.x509.NameConstraints(
|
||||
[cryptography_get_name(name, 'name constraints permitted') for name in self.name_constraints_permitted] or None,
|
||||
[cryptography_get_name(name, 'name constraints excluded') for name in self.name_constraints_excluded] or None,
|
||||
), critical=self.name_constraints_critical)
|
||||
csr = csr.add_extension(
|
||||
cryptography.x509.NameConstraints(
|
||||
[
|
||||
cryptography_get_name(name, "name constraints permitted")
|
||||
for name in self.name_constraints_permitted
|
||||
]
|
||||
or None,
|
||||
[
|
||||
cryptography_get_name(name, "name constraints excluded")
|
||||
for name in self.name_constraints_excluded
|
||||
]
|
||||
or None,
|
||||
),
|
||||
critical=self.name_constraints_critical,
|
||||
)
|
||||
except TypeError as e:
|
||||
raise OpenSSLObjectError('Error while parsing name constraint: {0}'.format(e))
|
||||
raise OpenSSLObjectError(
|
||||
"Error while parsing name constraint: {0}".format(e)
|
||||
)
|
||||
|
||||
if self.create_subject_key_identifier:
|
||||
csr = csr.add_extension(
|
||||
cryptography.x509.SubjectKeyIdentifier.from_public_key(self.privatekey.public_key()),
|
||||
critical=False
|
||||
cryptography.x509.SubjectKeyIdentifier.from_public_key(
|
||||
self.privatekey.public_key()
|
||||
),
|
||||
critical=False,
|
||||
)
|
||||
elif self.subject_key_identifier is not None:
|
||||
csr = csr.add_extension(cryptography.x509.SubjectKeyIdentifier(self.subject_key_identifier), critical=False)
|
||||
csr = csr.add_extension(
|
||||
cryptography.x509.SubjectKeyIdentifier(self.subject_key_identifier),
|
||||
critical=False,
|
||||
)
|
||||
|
||||
if self.authority_key_identifier is not None or self.authority_cert_issuer is not None or self.authority_cert_serial_number is not None:
|
||||
if (
|
||||
self.authority_key_identifier is not None
|
||||
or self.authority_cert_issuer is not None
|
||||
or self.authority_cert_serial_number is not None
|
||||
):
|
||||
issuers = None
|
||||
if self.authority_cert_issuer is not None:
|
||||
issuers = [cryptography_get_name(n, 'authority cert issuer') for n in self.authority_cert_issuer]
|
||||
issuers = [
|
||||
cryptography_get_name(n, "authority cert issuer")
|
||||
for n in self.authority_cert_issuer
|
||||
]
|
||||
csr = csr.add_extension(
|
||||
cryptography.x509.AuthorityKeyIdentifier(self.authority_key_identifier, issuers, self.authority_cert_serial_number),
|
||||
critical=False
|
||||
cryptography.x509.AuthorityKeyIdentifier(
|
||||
self.authority_key_identifier,
|
||||
issuers,
|
||||
self.authority_cert_serial_number,
|
||||
),
|
||||
critical=False,
|
||||
)
|
||||
|
||||
if self.crl_distribution_points:
|
||||
csr = csr.add_extension(
|
||||
cryptography.x509.CRLDistributionPoints(self.crl_distribution_points),
|
||||
critical=False
|
||||
critical=False,
|
||||
)
|
||||
|
||||
digest = None
|
||||
if cryptography_key_needs_digest_for_signing(self.privatekey):
|
||||
digest = select_message_digest(self.digest)
|
||||
if digest is None:
|
||||
raise CertificateSigningRequestError('Unsupported digest "{0}"'.format(self.digest))
|
||||
raise CertificateSigningRequestError(
|
||||
'Unsupported digest "{0}"'.format(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.')
|
||||
if (
|
||||
str(e) == "Algorithm must be a registered hash algorithm."
|
||||
and digest is None
|
||||
):
|
||||
self.module.fail_json(
|
||||
msg="Signing with Ed25519 and Ed448 keys requires cryptography 2.8 or newer."
|
||||
)
|
||||
raise
|
||||
except UnicodeError as e:
|
||||
# This catches IDNAErrors, which happens when a bad name is passed as a SAN
|
||||
@@ -402,20 +524,32 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
|
||||
# https://github.com/kjd/idna/commit/ebefacd3134d0f5da4745878620a6a1cba86d130
|
||||
# and then
|
||||
# https://github.com/kjd/idna/commit/ea03c7b5db7d2a99af082e0239da2b68aeea702a).
|
||||
msg = 'Error while creating CSR: {0}\n'.format(e)
|
||||
msg = "Error while creating CSR: {0}\n".format(e)
|
||||
if self.using_common_name_for_san:
|
||||
self.module.fail_json(msg=msg + 'This is probably caused because the Common Name is used as a SAN.'
|
||||
' Specifying use_common_name_for_san=false might fix this.')
|
||||
self.module.fail_json(msg=msg + 'This is probably caused by an invalid Subject Alternative DNS Name.')
|
||||
self.module.fail_json(
|
||||
msg=msg
|
||||
+ "This is probably caused because the Common Name is used as a SAN."
|
||||
" Specifying use_common_name_for_san=false might fix this."
|
||||
)
|
||||
self.module.fail_json(
|
||||
msg=msg
|
||||
+ "This is probably caused by an invalid Subject Alternative DNS Name."
|
||||
)
|
||||
|
||||
def get_csr_data(self):
|
||||
"""Return bytes for self.csr."""
|
||||
return self.csr.public_bytes(cryptography.hazmat.primitives.serialization.Encoding.PEM)
|
||||
return self.csr.public_bytes(
|
||||
cryptography.hazmat.primitives.serialization.Encoding.PEM
|
||||
)
|
||||
|
||||
def _check_csr(self):
|
||||
"""Check whether provided parameters, assuming self.existing_csr and self.privatekey have been populated."""
|
||||
|
||||
def _check_subject(csr):
|
||||
subject = [(cryptography_name_to_oid(entry[0]), to_text(entry[1])) for entry in self.subject]
|
||||
subject = [
|
||||
(cryptography_name_to_oid(entry[0]), to_text(entry[1]))
|
||||
for entry in self.subject
|
||||
]
|
||||
current_subject = [(sub.oid, sub.value) for sub in csr.subject]
|
||||
if self.ordered_subject:
|
||||
return subject == current_subject
|
||||
@@ -424,14 +558,26 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
|
||||
|
||||
def _find_extension(extensions, exttype):
|
||||
return next(
|
||||
(ext for ext in extensions if isinstance(ext.value, exttype)),
|
||||
None
|
||||
(ext for ext in extensions if isinstance(ext.value, exttype)), None
|
||||
)
|
||||
|
||||
def _check_subjectAltName(extensions):
|
||||
current_altnames_ext = _find_extension(extensions, cryptography.x509.SubjectAlternativeName)
|
||||
current_altnames = [to_text(altname) for altname in current_altnames_ext.value] if current_altnames_ext else []
|
||||
altnames = [to_text(cryptography_get_name(altname)) for altname in self.subjectAltName] if self.subjectAltName else []
|
||||
current_altnames_ext = _find_extension(
|
||||
extensions, cryptography.x509.SubjectAlternativeName
|
||||
)
|
||||
current_altnames = (
|
||||
[to_text(altname) for altname in current_altnames_ext.value]
|
||||
if current_altnames_ext
|
||||
else []
|
||||
)
|
||||
altnames = (
|
||||
[
|
||||
to_text(cryptography_get_name(altname))
|
||||
for altname in self.subjectAltName
|
||||
]
|
||||
if self.subjectAltName
|
||||
else []
|
||||
)
|
||||
if set(altnames) != set(current_altnames):
|
||||
return False
|
||||
if altnames:
|
||||
@@ -440,23 +586,38 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
|
||||
return True
|
||||
|
||||
def _check_keyUsage(extensions):
|
||||
current_keyusage_ext = _find_extension(extensions, cryptography.x509.KeyUsage)
|
||||
current_keyusage_ext = _find_extension(
|
||||
extensions, cryptography.x509.KeyUsage
|
||||
)
|
||||
if not self.keyUsage:
|
||||
return current_keyusage_ext is None
|
||||
elif current_keyusage_ext is None:
|
||||
return False
|
||||
params = cryptography_parse_key_usage_params(self.keyUsage)
|
||||
for param in params:
|
||||
if getattr(current_keyusage_ext.value, '_' + param) != params[param]:
|
||||
if getattr(current_keyusage_ext.value, "_" + param) != params[param]:
|
||||
return False
|
||||
if current_keyusage_ext.critical != self.keyUsage_critical:
|
||||
return False
|
||||
return True
|
||||
|
||||
def _check_extenededKeyUsage(extensions):
|
||||
current_usages_ext = _find_extension(extensions, cryptography.x509.ExtendedKeyUsage)
|
||||
current_usages = [str(usage) for usage in current_usages_ext.value] if current_usages_ext else []
|
||||
usages = [str(cryptography_name_to_oid(usage)) for usage in self.extendedKeyUsage] if self.extendedKeyUsage else []
|
||||
current_usages_ext = _find_extension(
|
||||
extensions, cryptography.x509.ExtendedKeyUsage
|
||||
)
|
||||
current_usages = (
|
||||
[str(usage) for usage in current_usages_ext.value]
|
||||
if current_usages_ext
|
||||
else []
|
||||
)
|
||||
usages = (
|
||||
[
|
||||
str(cryptography_name_to_oid(usage))
|
||||
for usage in self.extendedKeyUsage
|
||||
]
|
||||
if self.extendedKeyUsage
|
||||
else []
|
||||
)
|
||||
if set(current_usages) != set(usages):
|
||||
return False
|
||||
if usages:
|
||||
@@ -477,38 +638,77 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
|
||||
return False
|
||||
# Check criticality
|
||||
if self.basicConstraints:
|
||||
return bc_ext is not None and bc_ext.critical == self.basicConstraints_critical
|
||||
return (
|
||||
bc_ext is not None
|
||||
and bc_ext.critical == self.basicConstraints_critical
|
||||
)
|
||||
else:
|
||||
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)
|
||||
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
|
||||
(
|
||||
ext
|
||||
for ext in extensions
|
||||
if ext.value.oid == CRYPTOGRAPHY_MUST_STAPLE_NAME
|
||||
),
|
||||
None,
|
||||
)
|
||||
has_tlsfeature = False
|
||||
if self.ocspMustStaple:
|
||||
if not tlsfeature_ext or tlsfeature_ext.critical != self.ocspMustStaple_critical:
|
||||
if (
|
||||
not tlsfeature_ext
|
||||
or tlsfeature_ext.critical != self.ocspMustStaple_critical
|
||||
):
|
||||
return False
|
||||
if has_tlsfeature:
|
||||
return cryptography.x509.TLSFeatureType.status_request in tlsfeature_ext.value
|
||||
return (
|
||||
cryptography.x509.TLSFeatureType.status_request
|
||||
in tlsfeature_ext.value
|
||||
)
|
||||
else:
|
||||
return tlsfeature_ext.value.value == CRYPTOGRAPHY_MUST_STAPLE_VALUE
|
||||
else:
|
||||
return tlsfeature_ext is None
|
||||
|
||||
def _check_nameConstraints(extensions):
|
||||
current_nc_ext = _find_extension(extensions, cryptography.x509.NameConstraints)
|
||||
current_nc_perm = [to_text(altname) for altname in current_nc_ext.value.permitted_subtrees or []] if current_nc_ext else []
|
||||
current_nc_excl = [to_text(altname) for altname in current_nc_ext.value.excluded_subtrees or []] if current_nc_ext else []
|
||||
nc_perm = [to_text(cryptography_get_name(altname, 'name constraints permitted')) for altname in self.name_constraints_permitted]
|
||||
nc_excl = [to_text(cryptography_get_name(altname, 'name constraints excluded')) for altname in self.name_constraints_excluded]
|
||||
if set(nc_perm) != set(current_nc_perm) or set(nc_excl) != set(current_nc_excl):
|
||||
current_nc_ext = _find_extension(
|
||||
extensions, cryptography.x509.NameConstraints
|
||||
)
|
||||
current_nc_perm = (
|
||||
[
|
||||
to_text(altname)
|
||||
for altname in current_nc_ext.value.permitted_subtrees or []
|
||||
]
|
||||
if current_nc_ext
|
||||
else []
|
||||
)
|
||||
current_nc_excl = (
|
||||
[
|
||||
to_text(altname)
|
||||
for altname in current_nc_ext.value.excluded_subtrees or []
|
||||
]
|
||||
if current_nc_ext
|
||||
else []
|
||||
)
|
||||
nc_perm = [
|
||||
to_text(cryptography_get_name(altname, "name constraints permitted"))
|
||||
for altname in self.name_constraints_permitted
|
||||
]
|
||||
nc_excl = [
|
||||
to_text(cryptography_get_name(altname, "name constraints excluded"))
|
||||
for altname in self.name_constraints_excluded
|
||||
]
|
||||
if set(nc_perm) != set(current_nc_perm) or set(nc_excl) != set(
|
||||
current_nc_excl
|
||||
):
|
||||
return False
|
||||
if nc_perm or nc_excl:
|
||||
if current_nc_ext.critical != self.name_constraints_critical:
|
||||
@@ -517,11 +717,16 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
|
||||
|
||||
def _check_subject_key_identifier(extensions):
|
||||
ext = _find_extension(extensions, cryptography.x509.SubjectKeyIdentifier)
|
||||
if self.create_subject_key_identifier or self.subject_key_identifier is not None:
|
||||
if (
|
||||
self.create_subject_key_identifier
|
||||
or self.subject_key_identifier is not None
|
||||
):
|
||||
if not ext or ext.critical:
|
||||
return False
|
||||
if self.create_subject_key_identifier:
|
||||
digest = cryptography.x509.SubjectKeyIdentifier.from_public_key(self.privatekey.public_key()).digest
|
||||
digest = cryptography.x509.SubjectKeyIdentifier.from_public_key(
|
||||
self.privatekey.public_key()
|
||||
).digest
|
||||
return ext.value.digest == digest
|
||||
else:
|
||||
return ext.value.digest == self.subject_key_identifier
|
||||
@@ -530,18 +735,28 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
|
||||
|
||||
def _check_authority_key_identifier(extensions):
|
||||
ext = _find_extension(extensions, cryptography.x509.AuthorityKeyIdentifier)
|
||||
if self.authority_key_identifier is not None or self.authority_cert_issuer is not None or self.authority_cert_serial_number is not None:
|
||||
if (
|
||||
self.authority_key_identifier is not None
|
||||
or self.authority_cert_issuer is not None
|
||||
or self.authority_cert_serial_number is not None
|
||||
):
|
||||
if not ext or ext.critical:
|
||||
return False
|
||||
aci = None
|
||||
csr_aci = None
|
||||
if self.authority_cert_issuer is not None:
|
||||
aci = [to_text(cryptography_get_name(n, 'authority cert issuer')) for n in self.authority_cert_issuer]
|
||||
aci = [
|
||||
to_text(cryptography_get_name(n, "authority cert issuer"))
|
||||
for n in self.authority_cert_issuer
|
||||
]
|
||||
if ext.value.authority_cert_issuer is not None:
|
||||
csr_aci = [to_text(n) for n in ext.value.authority_cert_issuer]
|
||||
return (ext.value.key_identifier == self.authority_key_identifier
|
||||
and csr_aci == aci
|
||||
and ext.value.authority_cert_serial_number == self.authority_cert_serial_number)
|
||||
return (
|
||||
ext.value.key_identifier == self.authority_key_identifier
|
||||
and csr_aci == aci
|
||||
and ext.value.authority_cert_serial_number
|
||||
== self.authority_cert_serial_number
|
||||
)
|
||||
else:
|
||||
return ext is None
|
||||
|
||||
@@ -555,11 +770,17 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
|
||||
|
||||
def _check_extensions(csr):
|
||||
extensions = csr.extensions
|
||||
return (_check_subjectAltName(extensions) and _check_keyUsage(extensions) and
|
||||
_check_extenededKeyUsage(extensions) and _check_basicConstraints(extensions) and
|
||||
_check_ocspMustStaple(extensions) and _check_subject_key_identifier(extensions) and
|
||||
_check_authority_key_identifier(extensions) and _check_nameConstraints(extensions) and
|
||||
_check_crl_distribution_points(extensions))
|
||||
return (
|
||||
_check_subjectAltName(extensions)
|
||||
and _check_keyUsage(extensions)
|
||||
and _check_extenededKeyUsage(extensions)
|
||||
and _check_basicConstraints(extensions)
|
||||
and _check_ocspMustStaple(extensions)
|
||||
and _check_subject_key_identifier(extensions)
|
||||
and _check_authority_key_identifier(extensions)
|
||||
and _check_nameConstraints(extensions)
|
||||
and _check_crl_distribution_points(extensions)
|
||||
)
|
||||
|
||||
def _check_signature(csr):
|
||||
if not csr.is_signature_valid:
|
||||
@@ -568,107 +789,154 @@ class CertificateSigningRequestCryptographyBackend(CertificateSigningRequestBack
|
||||
# encode both public keys and compare PEMs.
|
||||
key_a = csr.public_key().public_bytes(
|
||||
cryptography.hazmat.primitives.serialization.Encoding.PEM,
|
||||
cryptography.hazmat.primitives.serialization.PublicFormat.SubjectPublicKeyInfo
|
||||
cryptography.hazmat.primitives.serialization.PublicFormat.SubjectPublicKeyInfo,
|
||||
)
|
||||
key_b = self.privatekey.public_key().public_bytes(
|
||||
cryptography.hazmat.primitives.serialization.Encoding.PEM,
|
||||
cryptography.hazmat.primitives.serialization.PublicFormat.SubjectPublicKeyInfo
|
||||
cryptography.hazmat.primitives.serialization.PublicFormat.SubjectPublicKeyInfo,
|
||||
)
|
||||
return key_a == key_b
|
||||
|
||||
return _check_subject(self.existing_csr) and _check_extensions(self.existing_csr) and _check_signature(self.existing_csr)
|
||||
return (
|
||||
_check_subject(self.existing_csr)
|
||||
and _check_extensions(self.existing_csr)
|
||||
and _check_signature(self.existing_csr)
|
||||
)
|
||||
|
||||
|
||||
def select_backend(module, backend):
|
||||
if backend == 'auto':
|
||||
if backend == "auto":
|
||||
# Detection what is possible
|
||||
can_use_cryptography = CRYPTOGRAPHY_FOUND and CRYPTOGRAPHY_VERSION >= LooseVersion(MINIMAL_CRYPTOGRAPHY_VERSION)
|
||||
can_use_cryptography = (
|
||||
CRYPTOGRAPHY_FOUND
|
||||
and CRYPTOGRAPHY_VERSION >= LooseVersion(MINIMAL_CRYPTOGRAPHY_VERSION)
|
||||
)
|
||||
|
||||
# Try cryptography
|
||||
if can_use_cryptography:
|
||||
backend = 'cryptography'
|
||||
backend = "cryptography"
|
||||
|
||||
# Success?
|
||||
if backend == 'auto':
|
||||
module.fail_json(msg=("Cannot detect any of the required Python libraries "
|
||||
"cryptography (>= {0})").format(MINIMAL_CRYPTOGRAPHY_VERSION))
|
||||
if backend == "auto":
|
||||
module.fail_json(
|
||||
msg=(
|
||||
"Cannot detect any of the required Python libraries "
|
||||
"cryptography (>= {0})"
|
||||
).format(MINIMAL_CRYPTOGRAPHY_VERSION)
|
||||
)
|
||||
|
||||
if backend == 'cryptography':
|
||||
if backend == "cryptography":
|
||||
if not CRYPTOGRAPHY_FOUND:
|
||||
module.fail_json(msg=missing_required_lib('cryptography >= {0}'.format(MINIMAL_CRYPTOGRAPHY_VERSION)),
|
||||
exception=CRYPTOGRAPHY_IMP_ERR)
|
||||
module.fail_json(
|
||||
msg=missing_required_lib(
|
||||
"cryptography >= {0}".format(MINIMAL_CRYPTOGRAPHY_VERSION)
|
||||
),
|
||||
exception=CRYPTOGRAPHY_IMP_ERR,
|
||||
)
|
||||
return backend, CertificateSigningRequestCryptographyBackend(module)
|
||||
else:
|
||||
raise Exception('Unsupported value for backend: {0}'.format(backend))
|
||||
raise Exception("Unsupported value for backend: {0}".format(backend))
|
||||
|
||||
|
||||
def get_csr_argument_spec():
|
||||
return ArgumentSpec(
|
||||
argument_spec=dict(
|
||||
digest=dict(type='str', default='sha256'),
|
||||
privatekey_path=dict(type='path'),
|
||||
privatekey_content=dict(type='str', no_log=True),
|
||||
privatekey_passphrase=dict(type='str', no_log=True),
|
||||
version=dict(type='int', default=1, choices=[1]),
|
||||
subject=dict(type='dict'),
|
||||
subject_ordered=dict(type='list', elements='dict'),
|
||||
country_name=dict(type='str', aliases=['C', 'countryName']),
|
||||
state_or_province_name=dict(type='str', aliases=['ST', 'stateOrProvinceName']),
|
||||
locality_name=dict(type='str', aliases=['L', 'localityName']),
|
||||
organization_name=dict(type='str', aliases=['O', 'organizationName']),
|
||||
organizational_unit_name=dict(type='str', aliases=['OU', 'organizationalUnitName']),
|
||||
common_name=dict(type='str', aliases=['CN', 'commonName']),
|
||||
email_address=dict(type='str', aliases=['E', 'emailAddress']),
|
||||
subject_alt_name=dict(type='list', elements='str', aliases=['subjectAltName']),
|
||||
subject_alt_name_critical=dict(type='bool', default=False, aliases=['subjectAltName_critical']),
|
||||
use_common_name_for_san=dict(type='bool', default=True, aliases=['useCommonNameForSAN']),
|
||||
key_usage=dict(type='list', elements='str', aliases=['keyUsage']),
|
||||
key_usage_critical=dict(type='bool', default=False, aliases=['keyUsage_critical']),
|
||||
extended_key_usage=dict(type='list', elements='str', aliases=['extKeyUsage', 'extendedKeyUsage']),
|
||||
extended_key_usage_critical=dict(type='bool', default=False, aliases=['extKeyUsage_critical', 'extendedKeyUsage_critical']),
|
||||
basic_constraints=dict(type='list', elements='str', aliases=['basicConstraints']),
|
||||
basic_constraints_critical=dict(type='bool', default=False, aliases=['basicConstraints_critical']),
|
||||
ocsp_must_staple=dict(type='bool', default=False, aliases=['ocspMustStaple']),
|
||||
ocsp_must_staple_critical=dict(type='bool', default=False, aliases=['ocspMustStaple_critical']),
|
||||
name_constraints_permitted=dict(type='list', elements='str'),
|
||||
name_constraints_excluded=dict(type='list', elements='str'),
|
||||
name_constraints_critical=dict(type='bool', default=False),
|
||||
create_subject_key_identifier=dict(type='bool', default=False),
|
||||
subject_key_identifier=dict(type='str'),
|
||||
authority_key_identifier=dict(type='str'),
|
||||
authority_cert_issuer=dict(type='list', elements='str'),
|
||||
authority_cert_serial_number=dict(type='int'),
|
||||
crl_distribution_points=dict(
|
||||
type='list',
|
||||
elements='dict',
|
||||
options=dict(
|
||||
full_name=dict(type='list', elements='str'),
|
||||
relative_name=dict(type='list', elements='str'),
|
||||
crl_issuer=dict(type='list', elements='str'),
|
||||
reasons=dict(type='list', elements='str', choices=[
|
||||
'key_compromise',
|
||||
'ca_compromise',
|
||||
'affiliation_changed',
|
||||
'superseded',
|
||||
'cessation_of_operation',
|
||||
'certificate_hold',
|
||||
'privilege_withdrawn',
|
||||
'aa_compromise',
|
||||
]),
|
||||
),
|
||||
mutually_exclusive=[('full_name', 'relative_name')],
|
||||
required_one_of=[('full_name', 'relative_name', 'crl_issuer')],
|
||||
digest=dict(type="str", default="sha256"),
|
||||
privatekey_path=dict(type="path"),
|
||||
privatekey_content=dict(type="str", no_log=True),
|
||||
privatekey_passphrase=dict(type="str", no_log=True),
|
||||
version=dict(type="int", default=1, choices=[1]),
|
||||
subject=dict(type="dict"),
|
||||
subject_ordered=dict(type="list", elements="dict"),
|
||||
country_name=dict(type="str", aliases=["C", "countryName"]),
|
||||
state_or_province_name=dict(
|
||||
type="str", aliases=["ST", "stateOrProvinceName"]
|
||||
),
|
||||
locality_name=dict(type="str", aliases=["L", "localityName"]),
|
||||
organization_name=dict(type="str", aliases=["O", "organizationName"]),
|
||||
organizational_unit_name=dict(
|
||||
type="str", aliases=["OU", "organizationalUnitName"]
|
||||
),
|
||||
common_name=dict(type="str", aliases=["CN", "commonName"]),
|
||||
email_address=dict(type="str", aliases=["E", "emailAddress"]),
|
||||
subject_alt_name=dict(
|
||||
type="list", elements="str", aliases=["subjectAltName"]
|
||||
),
|
||||
subject_alt_name_critical=dict(
|
||||
type="bool", default=False, aliases=["subjectAltName_critical"]
|
||||
),
|
||||
use_common_name_for_san=dict(
|
||||
type="bool", default=True, aliases=["useCommonNameForSAN"]
|
||||
),
|
||||
key_usage=dict(type="list", elements="str", aliases=["keyUsage"]),
|
||||
key_usage_critical=dict(
|
||||
type="bool", default=False, aliases=["keyUsage_critical"]
|
||||
),
|
||||
extended_key_usage=dict(
|
||||
type="list", elements="str", aliases=["extKeyUsage", "extendedKeyUsage"]
|
||||
),
|
||||
extended_key_usage_critical=dict(
|
||||
type="bool",
|
||||
default=False,
|
||||
aliases=["extKeyUsage_critical", "extendedKeyUsage_critical"],
|
||||
),
|
||||
basic_constraints=dict(
|
||||
type="list", elements="str", aliases=["basicConstraints"]
|
||||
),
|
||||
basic_constraints_critical=dict(
|
||||
type="bool", default=False, aliases=["basicConstraints_critical"]
|
||||
),
|
||||
ocsp_must_staple=dict(
|
||||
type="bool", default=False, aliases=["ocspMustStaple"]
|
||||
),
|
||||
ocsp_must_staple_critical=dict(
|
||||
type="bool", default=False, aliases=["ocspMustStaple_critical"]
|
||||
),
|
||||
name_constraints_permitted=dict(type="list", elements="str"),
|
||||
name_constraints_excluded=dict(type="list", elements="str"),
|
||||
name_constraints_critical=dict(type="bool", default=False),
|
||||
create_subject_key_identifier=dict(type="bool", default=False),
|
||||
subject_key_identifier=dict(type="str"),
|
||||
authority_key_identifier=dict(type="str"),
|
||||
authority_cert_issuer=dict(type="list", elements="str"),
|
||||
authority_cert_serial_number=dict(type="int"),
|
||||
crl_distribution_points=dict(
|
||||
type="list",
|
||||
elements="dict",
|
||||
options=dict(
|
||||
full_name=dict(type="list", elements="str"),
|
||||
relative_name=dict(type="list", elements="str"),
|
||||
crl_issuer=dict(type="list", elements="str"),
|
||||
reasons=dict(
|
||||
type="list",
|
||||
elements="str",
|
||||
choices=[
|
||||
"key_compromise",
|
||||
"ca_compromise",
|
||||
"affiliation_changed",
|
||||
"superseded",
|
||||
"cessation_of_operation",
|
||||
"certificate_hold",
|
||||
"privilege_withdrawn",
|
||||
"aa_compromise",
|
||||
],
|
||||
),
|
||||
),
|
||||
mutually_exclusive=[("full_name", "relative_name")],
|
||||
required_one_of=[("full_name", "relative_name", "crl_issuer")],
|
||||
),
|
||||
select_crypto_backend=dict(
|
||||
type="str", default="auto", choices=["auto", "cryptography"]
|
||||
),
|
||||
select_crypto_backend=dict(type='str', default='auto', choices=['auto', 'cryptography']),
|
||||
),
|
||||
required_together=[
|
||||
['authority_cert_issuer', 'authority_cert_serial_number'],
|
||||
["authority_cert_issuer", "authority_cert_serial_number"],
|
||||
],
|
||||
mutually_exclusive=[
|
||||
['privatekey_path', 'privatekey_content'],
|
||||
['subject', 'subject_ordered'],
|
||||
["privatekey_path", "privatekey_content"],
|
||||
["subject", "subject_ordered"],
|
||||
],
|
||||
required_one_of=[
|
||||
['privatekey_path', 'privatekey_content'],
|
||||
["privatekey_path", "privatekey_content"],
|
||||
],
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user