mirror of
https://github.com/ansible-collections/community.crypto.git
synced 2026-05-06 21:33:00 +00:00
Refactor module_utils/crypto.py (#27)
* Refactor module_utils/crypto.py: split up into multiple smaller modules * Remove superfluous files. * Fix sanity errors. * Move CRL entry dumping code to module_utils. * Move obj2txt usage from CRL modules to module_utils/crpyto/cryptography_crl. * Move generic I/O functions to plugins/module_utils/io.py. * Add helper method for retrieving serial number of certificate. * Add compatibility code into __init__.py. * Fix syntax error, and add ignore.txt entries for non-empty __init__.
This commit is contained in:
@@ -505,7 +505,14 @@ from datetime import datetime
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils._text import to_bytes, to_native
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils import crypto as crypto_utils
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
parse_name_field,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
cryptography_name_to_oid,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.acme import (
|
||||
ModuleFailException,
|
||||
write_file,
|
||||
@@ -1004,8 +1011,8 @@ class ACMEClient(object):
|
||||
x509 = cryptography.x509.load_pem_x509_certificate(to_bytes(cert), cryptography.hazmat.backends.default_backend())
|
||||
matches = True
|
||||
if criterium['subject']:
|
||||
for k, v in crypto_utils.parse_name_field(criterium['subject']):
|
||||
oid = crypto_utils.cryptography_name_to_oid(k)
|
||||
for k, v in parse_name_field(criterium['subject']):
|
||||
oid = cryptography_name_to_oid(k)
|
||||
value = to_native(v)
|
||||
found = False
|
||||
for attribute in x509.subject:
|
||||
@@ -1016,8 +1023,8 @@ class ACMEClient(object):
|
||||
matches = False
|
||||
break
|
||||
if criterium['issuer']:
|
||||
for k, v in crypto_utils.parse_name_field(criterium['issuer']):
|
||||
oid = crypto_utils.cryptography_name_to_oid(k)
|
||||
for k, v in parse_name_field(criterium['issuer']):
|
||||
oid = cryptography_name_to_oid(k)
|
||||
value = to_native(v)
|
||||
found = False
|
||||
for attribute in x509.issuer:
|
||||
|
||||
@@ -518,7 +518,6 @@ from ansible_collections.community.crypto.plugins.module_utils.ecs.api import (
|
||||
)
|
||||
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import time
|
||||
@@ -529,7 +528,13 @@ from distutils.version import LooseVersion
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils._text import to_native, to_bytes
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils import crypto as crypto_utils
|
||||
from ansible_collections.community.crypto.plugins.module_utils.io import (
|
||||
write_file,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
load_certificate,
|
||||
)
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
@@ -602,7 +607,7 @@ class EcsCertificate(object):
|
||||
self.ecs_client = None
|
||||
if self.path and os.path.exists(self.path):
|
||||
try:
|
||||
self.cert = crypto_utils.load_certificate(self.path, backend='cryptography')
|
||||
self.cert = load_certificate(self.path, backend='cryptography')
|
||||
except Exception as dummy:
|
||||
self.cert = None
|
||||
# Instantiate the ECS client and then try a no-op connection to verify credentials are valid
|
||||
@@ -774,20 +779,20 @@ class EcsCertificate(object):
|
||||
if self.request_type != 'validate_only':
|
||||
if self.backup:
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
crypto_utils.write_file(module, to_bytes(self.cert_details.get('endEntityCert')))
|
||||
write_file(module, to_bytes(self.cert_details.get('endEntityCert')))
|
||||
if self.full_chain_path and self.cert_details.get('chainCerts'):
|
||||
if self.backup:
|
||||
self.backup_full_chain_file = module.backup_local(self.full_chain_path)
|
||||
chain_string = '\n'.join(self.cert_details.get('chainCerts')) + '\n'
|
||||
crypto_utils.write_file(module, to_bytes(chain_string), path=self.full_chain_path)
|
||||
write_file(module, to_bytes(chain_string), path=self.full_chain_path)
|
||||
self.changed = True
|
||||
# If there is no certificate present in path but a tracking ID was specified, save it to disk
|
||||
elif not os.path.exists(self.path) and self.tracking_id:
|
||||
if not module.check_mode:
|
||||
crypto_utils.write_file(module, to_bytes(self.cert_details.get('endEntityCert')))
|
||||
write_file(module, to_bytes(self.cert_details.get('endEntityCert')))
|
||||
if self.full_chain_path and self.cert_details.get('chainCerts'):
|
||||
chain_string = '\n'.join(self.cert_details.get('chainCerts')) + '\n'
|
||||
crypto_utils.write_file(module, to_bytes(chain_string), path=self.full_chain_path)
|
||||
write_file(module, to_bytes(chain_string), path=self.full_chain_path)
|
||||
self.changed = True
|
||||
|
||||
def dump(self):
|
||||
|
||||
@@ -163,7 +163,10 @@ from ssl import get_server_certificate, DER_cert_to_PEM_cert, CERT_NONE, CERT_OP
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils._text import to_bytes
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils import crypto as crypto_utils
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
cryptography_oid_to_name,
|
||||
cryptography_get_extensions_from_cert,
|
||||
)
|
||||
|
||||
MINIMAL_PYOPENSSL_VERSION = '0.15'
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = '1.6'
|
||||
@@ -330,28 +333,28 @@ def main():
|
||||
x509 = cryptography.x509.load_pem_x509_certificate(to_bytes(cert), cryptography_backend())
|
||||
result['subject'] = {}
|
||||
for attribute in x509.subject:
|
||||
result['subject'][crypto_utils.cryptography_oid_to_name(attribute.oid, short=True)] = attribute.value
|
||||
result['subject'][cryptography_oid_to_name(attribute.oid, short=True)] = attribute.value
|
||||
|
||||
result['expired'] = x509.not_valid_after < datetime.datetime.utcnow()
|
||||
|
||||
result['extensions'] = []
|
||||
for dotted_number, entry in crypto_utils.cryptography_get_extensions_from_cert(x509).items():
|
||||
for dotted_number, entry in cryptography_get_extensions_from_cert(x509).items():
|
||||
oid = cryptography.x509.oid.ObjectIdentifier(dotted_number)
|
||||
result['extensions'].append({
|
||||
'critical': entry['critical'],
|
||||
'asn1_data': base64.b64decode(entry['value']),
|
||||
'name': crypto_utils.cryptography_oid_to_name(oid, short=True),
|
||||
'name': cryptography_oid_to_name(oid, short=True),
|
||||
})
|
||||
|
||||
result['issuer'] = {}
|
||||
for attribute in x509.issuer:
|
||||
result['issuer'][crypto_utils.cryptography_oid_to_name(attribute.oid, short=True)] = attribute.value
|
||||
result['issuer'][cryptography_oid_to_name(attribute.oid, short=True)] = attribute.value
|
||||
|
||||
result['not_after'] = x509.not_valid_after.strftime('%Y%m%d%H%M%SZ')
|
||||
result['not_before'] = x509.not_valid_before.strftime('%Y%m%d%H%M%SZ')
|
||||
|
||||
result['serial_number'] = x509.serial_number
|
||||
result['signature_algorithm'] = crypto_utils.cryptography_oid_to_name(x509.signature_algorithm_oid)
|
||||
result['signature_algorithm'] = cryptography_oid_to_name(x509.signature_algorithm_oid)
|
||||
|
||||
# We need the -1 offset to get the same values as pyOpenSSL
|
||||
if x509.version == cryptography.x509.Version.v1:
|
||||
|
||||
@@ -208,7 +208,7 @@ from shutil import copy2, rmtree
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils._text import to_native
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto import convert_relative_to_datetime
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import convert_relative_to_datetime
|
||||
|
||||
|
||||
class CertificateError(Exception):
|
||||
|
||||
@@ -425,9 +425,33 @@ from distutils.version import LooseVersion
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils._text import to_native, to_bytes, to_text
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils import crypto as crypto_utils
|
||||
from ansible_collections.community.crypto.plugins.module_utils.compat import ipaddress as compat_ipaddress
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.io import (
|
||||
load_file_if_exists,
|
||||
write_file,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
OpenSSLObjectError,
|
||||
OpenSSLBadPassphraseError,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
OpenSSLObject,
|
||||
load_privatekey,
|
||||
load_certificate_request,
|
||||
parse_name_field,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
cryptography_get_basic_constraints,
|
||||
cryptography_get_name,
|
||||
cryptography_name_to_oid,
|
||||
cryptography_key_needs_digest_for_signing,
|
||||
cryptography_parse_key_usage_params,
|
||||
)
|
||||
|
||||
MINIMAL_PYOPENSSL_VERSION = '0.15'
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = '1.3'
|
||||
|
||||
@@ -469,11 +493,11 @@ else:
|
||||
CRYPTOGRAPHY_MUST_STAPLE_VALUE = b"\x30\x03\x02\x01\x05"
|
||||
|
||||
|
||||
class CertificateSigningRequestError(crypto_utils.OpenSSLObjectError):
|
||||
class CertificateSigningRequestError(OpenSSLObjectError):
|
||||
pass
|
||||
|
||||
|
||||
class CertificateSigningRequestBase(crypto_utils.OpenSSLObject):
|
||||
class CertificateSigningRequestBase(OpenSSLObject):
|
||||
|
||||
def __init__(self, module):
|
||||
super(CertificateSigningRequestBase, self).__init__(
|
||||
@@ -526,7 +550,7 @@ class CertificateSigningRequestBase(crypto_utils.OpenSSLObject):
|
||||
]
|
||||
|
||||
if module.params['subject']:
|
||||
self.subject = self.subject + crypto_utils.parse_name_field(module.params['subject'])
|
||||
self.subject = self.subject + parse_name_field(module.params['subject'])
|
||||
self.subject = [(entry[0], entry[1]) for entry in self.subject if entry[1]]
|
||||
|
||||
if not self.subjectAltName and module.params['use_common_name_for_san']:
|
||||
@@ -559,7 +583,7 @@ class CertificateSigningRequestBase(crypto_utils.OpenSSLObject):
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
if self.return_content:
|
||||
self.csr_bytes = result
|
||||
crypto_utils.write_file(module, result)
|
||||
write_file(module, result)
|
||||
self.changed = True
|
||||
|
||||
file_args = module.load_file_common_arguments(module.params)
|
||||
@@ -608,7 +632,7 @@ class CertificateSigningRequestBase(crypto_utils.OpenSSLObject):
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
if self.csr_bytes is None:
|
||||
self.csr_bytes = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
self.csr_bytes = load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['csr'] = self.csr_bytes.decode('utf-8') if self.csr_bytes else None
|
||||
|
||||
return result
|
||||
@@ -676,12 +700,12 @@ class CertificateSigningRequestPyOpenSSL(CertificateSigningRequestBase):
|
||||
|
||||
def _load_private_key(self):
|
||||
try:
|
||||
self.privatekey = crypto_utils.load_privatekey(
|
||||
self.privatekey = load_privatekey(
|
||||
path=self.privatekey_path,
|
||||
content=self.privatekey_content,
|
||||
passphrase=self.privatekey_passphrase
|
||||
)
|
||||
except crypto_utils.OpenSSLBadPassphraseError as exc:
|
||||
except OpenSSLBadPassphraseError as exc:
|
||||
raise CertificateSigningRequestError(exc)
|
||||
|
||||
def _normalize_san(self, san):
|
||||
@@ -771,7 +795,7 @@ class CertificateSigningRequestPyOpenSSL(CertificateSigningRequestBase):
|
||||
return False
|
||||
|
||||
try:
|
||||
csr = crypto_utils.load_certificate_request(self.path, backend='pyopenssl')
|
||||
csr = load_certificate_request(self.path, backend='pyopenssl')
|
||||
except Exception as dummy:
|
||||
return False
|
||||
|
||||
@@ -791,27 +815,27 @@ class CertificateSigningRequestCryptography(CertificateSigningRequestBase):
|
||||
csr = cryptography.x509.CertificateSigningRequestBuilder()
|
||||
try:
|
||||
csr = csr.subject_name(cryptography.x509.Name([
|
||||
cryptography.x509.NameAttribute(crypto_utils.cryptography_name_to_oid(entry[0]), to_text(entry[1])) for entry in self.subject
|
||||
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([
|
||||
crypto_utils.cryptography_get_name(name) for name in self.subjectAltName
|
||||
cryptography_get_name(name) for name in self.subjectAltName
|
||||
]), critical=self.subjectAltName_critical)
|
||||
|
||||
if self.keyUsage:
|
||||
params = crypto_utils.cryptography_parse_key_usage_params(self.keyUsage)
|
||||
params = cryptography_parse_key_usage_params(self.keyUsage)
|
||||
csr = csr.add_extension(cryptography.x509.KeyUsage(**params), critical=self.keyUsage_critical)
|
||||
|
||||
if self.extendedKeyUsage:
|
||||
usages = [crypto_utils.cryptography_name_to_oid(usage) for usage in 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)
|
||||
|
||||
if self.basicConstraints:
|
||||
params = {}
|
||||
ca, path_length = crypto_utils.cryptography_get_basic_constraints(self.basicConstraints)
|
||||
ca, path_length = cryptography_get_basic_constraints(self.basicConstraints)
|
||||
csr = csr.add_extension(cryptography.x509.BasicConstraints(ca, path_length), critical=self.basicConstraints_critical)
|
||||
|
||||
if self.ocspMustStaple:
|
||||
@@ -835,14 +859,14 @@ class CertificateSigningRequestCryptography(CertificateSigningRequestBase):
|
||||
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 = [crypto_utils.cryptography_get_name(n) for n in self.authority_cert_issuer]
|
||||
issuers = [cryptography_get_name(n) 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
|
||||
)
|
||||
|
||||
digest = None
|
||||
if crypto_utils.cryptography_key_needs_digest_for_signing(self.privatekey):
|
||||
if cryptography_key_needs_digest_for_signing(self.privatekey):
|
||||
if self.digest == 'sha256':
|
||||
digest = cryptography.hazmat.primitives.hashes.SHA256()
|
||||
elif self.digest == 'sha384':
|
||||
@@ -882,7 +906,7 @@ class CertificateSigningRequestCryptography(CertificateSigningRequestBase):
|
||||
|
||||
def _check_csr(self):
|
||||
def _check_subject(csr):
|
||||
subject = [(crypto_utils.cryptography_name_to_oid(entry[0]), entry[1]) for entry in self.subject]
|
||||
subject = [(cryptography_name_to_oid(entry[0]), entry[1]) for entry in self.subject]
|
||||
current_subject = [(sub.oid, sub.value) for sub in csr.subject]
|
||||
return set(subject) == set(current_subject)
|
||||
|
||||
@@ -895,7 +919,7 @@ class CertificateSigningRequestCryptography(CertificateSigningRequestBase):
|
||||
def _check_subjectAltName(extensions):
|
||||
current_altnames_ext = _find_extension(extensions, cryptography.x509.SubjectAlternativeName)
|
||||
current_altnames = [str(altname) for altname in current_altnames_ext.value] if current_altnames_ext else []
|
||||
altnames = [str(crypto_utils.cryptography_get_name(altname)) for altname in self.subjectAltName] if self.subjectAltName else []
|
||||
altnames = [str(cryptography_get_name(altname)) for altname in self.subjectAltName] if self.subjectAltName else []
|
||||
if set(altnames) != set(current_altnames):
|
||||
return False
|
||||
if altnames:
|
||||
@@ -909,7 +933,7 @@ class CertificateSigningRequestCryptography(CertificateSigningRequestBase):
|
||||
return current_keyusage_ext is None
|
||||
elif current_keyusage_ext is None:
|
||||
return False
|
||||
params = crypto_utils.cryptography_parse_key_usage_params(self.keyUsage)
|
||||
params = cryptography_parse_key_usage_params(self.keyUsage)
|
||||
for param in params:
|
||||
if getattr(current_keyusage_ext.value, '_' + param) != params[param]:
|
||||
return False
|
||||
@@ -920,7 +944,7 @@ class CertificateSigningRequestCryptography(CertificateSigningRequestBase):
|
||||
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(crypto_utils.cryptography_name_to_oid(usage)) for usage in self.extendedKeyUsage] if self.extendedKeyUsage 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:
|
||||
@@ -932,7 +956,7 @@ class CertificateSigningRequestCryptography(CertificateSigningRequestBase):
|
||||
bc_ext = _find_extension(extensions, cryptography.x509.BasicConstraints)
|
||||
current_ca = bc_ext.value.ca if bc_ext else False
|
||||
current_path_length = bc_ext.value.path_length if bc_ext else None
|
||||
ca, path_length = crypto_utils.cryptography_get_basic_constraints(self.basicConstraints)
|
||||
ca, path_length = cryptography_get_basic_constraints(self.basicConstraints)
|
||||
# Check CA flag
|
||||
if ca != current_ca:
|
||||
return False
|
||||
@@ -987,7 +1011,7 @@ class CertificateSigningRequestCryptography(CertificateSigningRequestBase):
|
||||
aci = None
|
||||
csr_aci = None
|
||||
if self.authority_cert_issuer is not None:
|
||||
aci = [str(crypto_utils.cryptography_get_name(n)) for n in self.authority_cert_issuer]
|
||||
aci = [str(cryptography_get_name(n)) for n in self.authority_cert_issuer]
|
||||
if ext.value.authority_cert_issuer is not None:
|
||||
csr_aci = [str(n) for n in ext.value.authority_cert_issuer]
|
||||
return (ext.value.key_identifier == self.authority_key_identifier
|
||||
@@ -1019,7 +1043,7 @@ class CertificateSigningRequestCryptography(CertificateSigningRequestBase):
|
||||
return key_a == key_b
|
||||
|
||||
try:
|
||||
csr = crypto_utils.load_certificate_request(self.path, backend='cryptography')
|
||||
csr = load_certificate_request(self.path, backend='cryptography')
|
||||
except Exception as dummy:
|
||||
return False
|
||||
|
||||
@@ -1136,7 +1160,7 @@ def main():
|
||||
|
||||
result = csr.dump()
|
||||
module.exit_json(**result)
|
||||
except crypto_utils.OpenSSLObjectError as exc:
|
||||
except OpenSSLObjectError as exc:
|
||||
module.fail_json(msg=to_native(exc))
|
||||
|
||||
|
||||
|
||||
@@ -213,9 +213,29 @@ from distutils.version import LooseVersion
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils._text import to_native, to_text, to_bytes
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils import crypto as crypto_utils
|
||||
from ansible_collections.community.crypto.plugins.module_utils.compat import ipaddress as compat_ipaddress
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
OpenSSLObjectError,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
OpenSSLObject,
|
||||
load_certificate_request,
|
||||
get_fingerprint_of_bytes,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
cryptography_decode_name,
|
||||
cryptography_get_extensions_from_csr,
|
||||
cryptography_oid_to_name,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.pyopenssl_support import (
|
||||
pyopenssl_normalize_name,
|
||||
pyopenssl_get_extensions_from_csr,
|
||||
)
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = '1.3'
|
||||
MINIMAL_PYOPENSSL_VERSION = '0.15'
|
||||
|
||||
@@ -254,7 +274,7 @@ else:
|
||||
TIMESTAMP_FORMAT = "%Y%m%d%H%M%SZ"
|
||||
|
||||
|
||||
class CertificateSigningRequestInfo(crypto_utils.OpenSSLObject):
|
||||
class CertificateSigningRequestInfo(OpenSSLObject):
|
||||
def __init__(self, module, backend):
|
||||
super(CertificateSigningRequestInfo, self).__init__(
|
||||
module.params['path'] or '',
|
||||
@@ -269,11 +289,11 @@ class CertificateSigningRequestInfo(crypto_utils.OpenSSLObject):
|
||||
self.content = self.content.encode('utf-8')
|
||||
|
||||
def generate(self):
|
||||
# Empty method because crypto_utils.OpenSSLObject wants this
|
||||
# Empty method because OpenSSLObject wants this
|
||||
pass
|
||||
|
||||
def dump(self):
|
||||
# Empty method because crypto_utils.OpenSSLObject wants this
|
||||
# Empty method because OpenSSLObject wants this
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
@@ -322,7 +342,7 @@ class CertificateSigningRequestInfo(crypto_utils.OpenSSLObject):
|
||||
|
||||
def get_info(self):
|
||||
result = dict()
|
||||
self.csr = crypto_utils.load_certificate_request(self.path, content=self.content, backend=self.backend)
|
||||
self.csr = load_certificate_request(self.path, content=self.content, backend=self.backend)
|
||||
|
||||
subject = self._get_subject_ordered()
|
||||
result['subject'] = dict()
|
||||
@@ -337,7 +357,7 @@ class CertificateSigningRequestInfo(crypto_utils.OpenSSLObject):
|
||||
|
||||
result['public_key'] = self._get_public_key(binary=False)
|
||||
pk = self._get_public_key(binary=True)
|
||||
result['public_key_fingerprints'] = crypto_utils.get_fingerprint_of_bytes(pk) if pk is not None else dict()
|
||||
result['public_key_fingerprints'] = get_fingerprint_of_bytes(pk) if pk is not None else dict()
|
||||
|
||||
if self.backend != 'pyopenssl':
|
||||
ski = self._get_subject_key_identifier()
|
||||
@@ -373,7 +393,7 @@ class CertificateSigningRequestInfoCryptography(CertificateSigningRequestInfo):
|
||||
def _get_subject_ordered(self):
|
||||
result = []
|
||||
for attribute in self.csr.subject:
|
||||
result.append([crypto_utils.cryptography_oid_to_name(attribute.oid), attribute.value])
|
||||
result.append([cryptography_oid_to_name(attribute.oid), attribute.value])
|
||||
return result
|
||||
|
||||
def _get_key_usage(self):
|
||||
@@ -418,7 +438,7 @@ class CertificateSigningRequestInfoCryptography(CertificateSigningRequestInfo):
|
||||
try:
|
||||
ext_keyusage_ext = self.csr.extensions.get_extension_for_class(x509.ExtendedKeyUsage)
|
||||
return sorted([
|
||||
crypto_utils.cryptography_oid_to_name(eku) for eku in ext_keyusage_ext.value
|
||||
cryptography_oid_to_name(eku) for eku in ext_keyusage_ext.value
|
||||
]), ext_keyusage_ext.critical
|
||||
except cryptography.x509.ExtensionNotFound:
|
||||
return None, False
|
||||
@@ -452,7 +472,7 @@ class CertificateSigningRequestInfoCryptography(CertificateSigningRequestInfo):
|
||||
def _get_subject_alt_name(self):
|
||||
try:
|
||||
san_ext = self.csr.extensions.get_extension_for_class(x509.SubjectAlternativeName)
|
||||
result = [crypto_utils.cryptography_decode_name(san) for san in san_ext.value]
|
||||
result = [cryptography_decode_name(san) for san in san_ext.value]
|
||||
return result, san_ext.critical
|
||||
except cryptography.x509.ExtensionNotFound:
|
||||
return None, False
|
||||
@@ -475,13 +495,13 @@ class CertificateSigningRequestInfoCryptography(CertificateSigningRequestInfo):
|
||||
ext = self.csr.extensions.get_extension_for_class(x509.AuthorityKeyIdentifier)
|
||||
issuer = None
|
||||
if ext.value.authority_cert_issuer is not None:
|
||||
issuer = [crypto_utils.cryptography_decode_name(san) for san in ext.value.authority_cert_issuer]
|
||||
issuer = [cryptography_decode_name(san) for san in ext.value.authority_cert_issuer]
|
||||
return ext.value.key_identifier, issuer, ext.value.authority_cert_serial_number
|
||||
except cryptography.x509.ExtensionNotFound:
|
||||
return None, None, None
|
||||
|
||||
def _get_all_extensions(self):
|
||||
return crypto_utils.cryptography_get_extensions_from_csr(self.csr)
|
||||
return cryptography_get_extensions_from_csr(self.csr)
|
||||
|
||||
def _is_signature_valid(self):
|
||||
return self.csr.is_signature_valid
|
||||
@@ -496,7 +516,7 @@ class CertificateSigningRequestInfoPyOpenSSL(CertificateSigningRequestInfo):
|
||||
def __get_name(self, name):
|
||||
result = []
|
||||
for sub in name.get_components():
|
||||
result.append([crypto_utils.pyopenssl_normalize_name(sub[0]), to_text(sub[1])])
|
||||
result.append([pyopenssl_normalize_name(sub[0]), to_text(sub[1])])
|
||||
return result
|
||||
|
||||
def _get_subject_ordered(self):
|
||||
@@ -506,7 +526,7 @@ class CertificateSigningRequestInfoPyOpenSSL(CertificateSigningRequestInfo):
|
||||
for extension in self.csr.get_extensions():
|
||||
if extension.get_short_name() == short_name:
|
||||
result = [
|
||||
crypto_utils.pyopenssl_normalize_name(usage.strip()) for usage in to_text(extension, errors='surrogate_or_strict').split(',')
|
||||
pyopenssl_normalize_name(usage.strip()) for usage in to_text(extension, errors='surrogate_or_strict').split(',')
|
||||
]
|
||||
return sorted(result), bool(extension.get_critical())
|
||||
return None, False
|
||||
@@ -581,7 +601,7 @@ class CertificateSigningRequestInfoPyOpenSSL(CertificateSigningRequestInfo):
|
||||
return None, None, None
|
||||
|
||||
def _get_all_extensions(self):
|
||||
return crypto_utils.pyopenssl_get_extensions_from_csr(self.csr)
|
||||
return pyopenssl_get_extensions_from_csr(self.csr)
|
||||
|
||||
def _is_signature_valid(self):
|
||||
try:
|
||||
@@ -654,7 +674,7 @@ def main():
|
||||
|
||||
result = certificate.get_info()
|
||||
module.exit_json(**result)
|
||||
except crypto_utils.OpenSSLObjectError as exc:
|
||||
except OpenSSLObjectError as exc:
|
||||
module.fail_json(msg=to_native(exc))
|
||||
|
||||
|
||||
|
||||
@@ -131,8 +131,14 @@ from distutils.version import LooseVersion
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils._text import to_native
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils import crypto as crypto_utils
|
||||
from ansible_collections.community.crypto.plugins.module_utils.io import (
|
||||
load_file_if_exists,
|
||||
write_file,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.math import (
|
||||
count_bits,
|
||||
)
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = '2.0'
|
||||
|
||||
@@ -228,7 +234,7 @@ class DHParameterBase(object):
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
content = load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['dhparams'] = content.decode('utf-8') if content else None
|
||||
|
||||
return result
|
||||
@@ -317,7 +323,7 @@ class DHParameterCryptography(DHParameterBase):
|
||||
# Write result
|
||||
if self.backup:
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
crypto_utils.write_file(module, result)
|
||||
write_file(module, result)
|
||||
|
||||
def _check_params_valid(self, module):
|
||||
"""Check if the params are in the correct state"""
|
||||
@@ -329,7 +335,7 @@ class DHParameterCryptography(DHParameterBase):
|
||||
except Exception as dummy:
|
||||
return False
|
||||
# Check parameters
|
||||
bits = crypto_utils.count_bits(params.parameter_numbers().p)
|
||||
bits = count_bits(params.parameter_numbers().p)
|
||||
return bits == self.size
|
||||
|
||||
|
||||
|
||||
@@ -186,7 +186,21 @@ import traceback
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils._text import to_bytes, to_native
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils import crypto as crypto_utils
|
||||
from ansible_collections.community.crypto.plugins.module_utils.io import (
|
||||
load_file_if_exists,
|
||||
write_file,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
OpenSSLObjectError,
|
||||
OpenSSLBadPassphraseError,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
OpenSSLObject,
|
||||
load_privatekey,
|
||||
load_certificate,
|
||||
)
|
||||
|
||||
PYOPENSSL_IMP_ERR = None
|
||||
try:
|
||||
@@ -198,11 +212,11 @@ else:
|
||||
pyopenssl_found = True
|
||||
|
||||
|
||||
class PkcsError(crypto_utils.OpenSSLObjectError):
|
||||
class PkcsError(OpenSSLObjectError):
|
||||
pass
|
||||
|
||||
|
||||
class Pkcs(crypto_utils.OpenSSLObject):
|
||||
class Pkcs(OpenSSLObject):
|
||||
|
||||
def __init__(self, module):
|
||||
super(Pkcs, self).__init__(
|
||||
@@ -239,11 +253,10 @@ class Pkcs(crypto_utils.OpenSSLObject):
|
||||
def _check_pkey_passphrase():
|
||||
if self.privatekey_passphrase:
|
||||
try:
|
||||
crypto_utils.load_privatekey(self.privatekey_path,
|
||||
self.privatekey_passphrase)
|
||||
load_privatekey(self.privatekey_path, self.privatekey_passphrase)
|
||||
except crypto.Error:
|
||||
return False
|
||||
except crypto_utils.OpenSSLBadPassphraseError:
|
||||
except OpenSSLBadPassphraseError:
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -307,7 +320,7 @@ class Pkcs(crypto_utils.OpenSSLObject):
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
if self.pkcs12_bytes is None:
|
||||
self.pkcs12_bytes = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
self.pkcs12_bytes = load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['pkcs12'] = base64.b64encode(self.pkcs12_bytes) if self.pkcs12_bytes else None
|
||||
|
||||
return result
|
||||
@@ -317,24 +330,20 @@ class Pkcs(crypto_utils.OpenSSLObject):
|
||||
self.pkcs12 = crypto.PKCS12()
|
||||
|
||||
if self.other_certificates:
|
||||
other_certs = [crypto_utils.load_certificate(other_cert) for other_cert
|
||||
other_certs = [load_certificate(other_cert) for other_cert
|
||||
in self.other_certificates]
|
||||
self.pkcs12.set_ca_certificates(other_certs)
|
||||
|
||||
if self.certificate_path:
|
||||
self.pkcs12.set_certificate(crypto_utils.load_certificate(
|
||||
self.certificate_path))
|
||||
self.pkcs12.set_certificate(load_certificate(self.certificate_path))
|
||||
|
||||
if self.friendly_name:
|
||||
self.pkcs12.set_friendlyname(to_bytes(self.friendly_name))
|
||||
|
||||
if self.privatekey_path:
|
||||
try:
|
||||
self.pkcs12.set_privatekey(crypto_utils.load_privatekey(
|
||||
self.privatekey_path,
|
||||
self.privatekey_passphrase)
|
||||
)
|
||||
except crypto_utils.OpenSSLBadPassphraseError as exc:
|
||||
self.pkcs12.set_privatekey(load_privatekey(self.privatekey_path, self.privatekey_passphrase))
|
||||
except OpenSSLBadPassphraseError as exc:
|
||||
raise PkcsError(exc)
|
||||
|
||||
return self.pkcs12.export(self.passphrase, self.iter_size, self.maciter_size)
|
||||
@@ -372,7 +381,7 @@ class Pkcs(crypto_utils.OpenSSLObject):
|
||||
"""Write the PKCS#12 file."""
|
||||
if self.backup:
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
crypto_utils.write_file(module, content, mode)
|
||||
write_file(module, content, mode)
|
||||
if self.return_content:
|
||||
self.pkcs12_bytes = content
|
||||
|
||||
@@ -459,7 +468,7 @@ def main():
|
||||
result['mode'] = file_mode
|
||||
|
||||
module.exit_json(**result)
|
||||
except crypto_utils.OpenSSLObjectError as exc:
|
||||
except OpenSSLObjectError as exc:
|
||||
module.fail_json(msg=to_native(exc))
|
||||
|
||||
|
||||
|
||||
@@ -281,7 +281,31 @@ from distutils.version import LooseVersion
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils._text import to_native, to_bytes
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils import crypto as crypto_utils
|
||||
from ansible_collections.community.crypto.plugins.module_utils.io import (
|
||||
load_file_if_exists,
|
||||
write_file,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
CRYPTOGRAPHY_HAS_X25519,
|
||||
CRYPTOGRAPHY_HAS_X25519_FULL,
|
||||
CRYPTOGRAPHY_HAS_X448,
|
||||
CRYPTOGRAPHY_HAS_ED25519,
|
||||
CRYPTOGRAPHY_HAS_ED448,
|
||||
OpenSSLObjectError,
|
||||
OpenSSLBadPassphraseError,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
OpenSSLObject,
|
||||
load_privatekey,
|
||||
get_fingerprint,
|
||||
get_fingerprint_of_bytes,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.identify import (
|
||||
identify_private_key_format,
|
||||
)
|
||||
|
||||
MINIMAL_PYOPENSSL_VERSION = '0.6'
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = '1.2.3'
|
||||
@@ -314,20 +338,12 @@ except ImportError:
|
||||
else:
|
||||
CRYPTOGRAPHY_FOUND = True
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto import (
|
||||
CRYPTOGRAPHY_HAS_X25519,
|
||||
CRYPTOGRAPHY_HAS_X25519_FULL,
|
||||
CRYPTOGRAPHY_HAS_X448,
|
||||
CRYPTOGRAPHY_HAS_ED25519,
|
||||
CRYPTOGRAPHY_HAS_ED448,
|
||||
)
|
||||
|
||||
|
||||
class PrivateKeyError(crypto_utils.OpenSSLObjectError):
|
||||
class PrivateKeyError(OpenSSLObjectError):
|
||||
pass
|
||||
|
||||
|
||||
class PrivateKeyBase(crypto_utils.OpenSSLObject):
|
||||
class PrivateKeyBase(OpenSSLObject):
|
||||
|
||||
def __init__(self, module):
|
||||
super(PrivateKeyBase, self).__init__(
|
||||
@@ -385,7 +401,7 @@ class PrivateKeyBase(crypto_utils.OpenSSLObject):
|
||||
privatekey_data = self._get_private_key_data()
|
||||
if self.return_content:
|
||||
self.privatekey_bytes = privatekey_data
|
||||
crypto_utils.write_file(module, privatekey_data, 0o600)
|
||||
write_file(module, privatekey_data, 0o600)
|
||||
self.changed = True
|
||||
elif not self.check(module, perms_required=False, ignore_conversion=False):
|
||||
# Convert
|
||||
@@ -395,7 +411,7 @@ class PrivateKeyBase(crypto_utils.OpenSSLObject):
|
||||
privatekey_data = self._get_private_key_data()
|
||||
if self.return_content:
|
||||
self.privatekey_bytes = privatekey_data
|
||||
crypto_utils.write_file(module, privatekey_data, 0o600)
|
||||
write_file(module, privatekey_data, 0o600)
|
||||
self.changed = True
|
||||
|
||||
self.fingerprint = self._get_fingerprint()
|
||||
@@ -473,9 +489,9 @@ class PrivateKeyBase(crypto_utils.OpenSSLObject):
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
if self.privatekey_bytes is None:
|
||||
self.privatekey_bytes = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
self.privatekey_bytes = load_file_if_exists(self.path, ignore_errors=True)
|
||||
if self.privatekey_bytes:
|
||||
if crypto_utils.identify_private_key_format(self.privatekey_bytes) == 'raw':
|
||||
if identify_private_key_format(self.privatekey_bytes) == 'raw':
|
||||
result['privatekey'] = base64.b64encode(self.privatekey_bytes)
|
||||
else:
|
||||
result['privatekey'] = self.privatekey_bytes.decode('utf-8')
|
||||
@@ -513,8 +529,8 @@ class PrivateKeyPyOpenSSL(PrivateKeyBase):
|
||||
"""Make sure that the private key has been loaded."""
|
||||
if self.privatekey is None:
|
||||
try:
|
||||
self.privatekey = privatekey = crypto_utils.load_privatekey(self.path, self.passphrase)
|
||||
except crypto_utils.OpenSSLBadPassphraseError as exc:
|
||||
self.privatekey = privatekey = load_privatekey(self.path, self.passphrase)
|
||||
except OpenSSLBadPassphraseError as exc:
|
||||
raise PrivateKeyError(exc)
|
||||
|
||||
def _get_private_key_data(self):
|
||||
@@ -526,11 +542,11 @@ class PrivateKeyPyOpenSSL(PrivateKeyBase):
|
||||
return crypto.dump_privatekey(crypto.FILETYPE_PEM, self.privatekey)
|
||||
|
||||
def _get_fingerprint(self):
|
||||
return crypto_utils.get_fingerprint(self.path, self.passphrase)
|
||||
return get_fingerprint(self.path, self.passphrase)
|
||||
|
||||
def _check_passphrase(self):
|
||||
try:
|
||||
crypto_utils.load_privatekey(self.path, self.passphrase)
|
||||
load_privatekey(self.path, self.passphrase)
|
||||
return True
|
||||
except Exception as dummy:
|
||||
return False
|
||||
@@ -719,7 +735,7 @@ class PrivateKeyCryptography(PrivateKeyBase):
|
||||
with open(self.path, 'rb') as f:
|
||||
data = f.read()
|
||||
# Interpret bytes depending on format.
|
||||
format = crypto_utils.identify_private_key_format(data)
|
||||
format = identify_private_key_format(data)
|
||||
if format == 'raw':
|
||||
if len(data) == 56 and CRYPTOGRAPHY_HAS_X448:
|
||||
return cryptography.hazmat.primitives.asymmetric.x448.X448PrivateKey.from_private_bytes(data)
|
||||
@@ -754,13 +770,13 @@ class PrivateKeyCryptography(PrivateKeyBase):
|
||||
cryptography.hazmat.primitives.serialization.PublicFormat.SubjectPublicKeyInfo
|
||||
)
|
||||
# Get fingerprints of public_key_bytes
|
||||
return crypto_utils.get_fingerprint_of_bytes(public_key_bytes)
|
||||
return get_fingerprint_of_bytes(public_key_bytes)
|
||||
|
||||
def _check_passphrase(self):
|
||||
try:
|
||||
with open(self.path, 'rb') as f:
|
||||
data = f.read()
|
||||
format = crypto_utils.identify_private_key_format(data)
|
||||
format = identify_private_key_format(data)
|
||||
if format == 'raw':
|
||||
# Raw keys cannot be encrypted. To avoid incompatibilities, we try to
|
||||
# actually load the key (and return False when this fails).
|
||||
@@ -807,7 +823,7 @@ class PrivateKeyCryptography(PrivateKeyBase):
|
||||
try:
|
||||
with open(self.path, 'rb') as f:
|
||||
content = f.read()
|
||||
format = crypto_utils.identify_private_key_format(content)
|
||||
format = identify_private_key_format(content)
|
||||
return format == self._get_wanted_format()
|
||||
except Exception as dummy:
|
||||
return False
|
||||
@@ -926,7 +942,7 @@ def main():
|
||||
|
||||
result = private_key.dump()
|
||||
module.exit_json(**result)
|
||||
except crypto_utils.OpenSSLObjectError as exc:
|
||||
except OpenSSLObjectError as exc:
|
||||
module.fail_json(msg=to_native(exc))
|
||||
|
||||
|
||||
|
||||
@@ -145,7 +145,25 @@ from distutils.version import LooseVersion
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils._text import to_native, to_bytes
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils import crypto as crypto_utils
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
CRYPTOGRAPHY_HAS_X25519,
|
||||
CRYPTOGRAPHY_HAS_X448,
|
||||
CRYPTOGRAPHY_HAS_ED25519,
|
||||
CRYPTOGRAPHY_HAS_ED448,
|
||||
OpenSSLObjectError,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
OpenSSLObject,
|
||||
load_privatekey,
|
||||
get_fingerprint_of_bytes,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.math import (
|
||||
binary_exp_mod,
|
||||
quick_is_not_prime,
|
||||
)
|
||||
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = '1.2.3'
|
||||
MINIMAL_PYOPENSSL_VERSION = '0.15'
|
||||
@@ -166,26 +184,6 @@ try:
|
||||
import cryptography
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
CRYPTOGRAPHY_VERSION = LooseVersion(cryptography.__version__)
|
||||
try:
|
||||
import cryptography.hazmat.primitives.asymmetric.x25519
|
||||
CRYPTOGRAPHY_HAS_X25519 = True
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_HAS_X25519 = False
|
||||
try:
|
||||
import cryptography.hazmat.primitives.asymmetric.x448
|
||||
CRYPTOGRAPHY_HAS_X448 = True
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_HAS_X448 = False
|
||||
try:
|
||||
import cryptography.hazmat.primitives.asymmetric.ed25519
|
||||
CRYPTOGRAPHY_HAS_ED25519 = True
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_HAS_ED25519 = False
|
||||
try:
|
||||
import cryptography.hazmat.primitives.asymmetric.ed448
|
||||
CRYPTOGRAPHY_HAS_ED448 = True
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_HAS_ED448 = False
|
||||
except ImportError:
|
||||
CRYPTOGRAPHY_IMP_ERR = traceback.format_exc()
|
||||
CRYPTOGRAPHY_FOUND = False
|
||||
@@ -254,13 +252,13 @@ def _check_dsa_consistency(key_public_data, key_private_data):
|
||||
if (p - 1) % q != 0:
|
||||
return False
|
||||
# Check that g**q mod p == 1
|
||||
if crypto_utils.binary_exp_mod(g, q, p) != 1:
|
||||
if binary_exp_mod(g, q, p) != 1:
|
||||
return False
|
||||
# Check whether g**x mod p == y
|
||||
if crypto_utils.binary_exp_mod(g, x, p) != y:
|
||||
if binary_exp_mod(g, x, p) != y:
|
||||
return False
|
||||
# Check (quickly) whether p or q are not primes
|
||||
if crypto_utils.quick_is_not_prime(q) or crypto_utils.quick_is_not_prime(p):
|
||||
if quick_is_not_prime(q) or quick_is_not_prime(p):
|
||||
return False
|
||||
return True
|
||||
|
||||
@@ -320,7 +318,7 @@ def _is_cryptography_key_consistent(key, key_public_data, key_private_data):
|
||||
return None
|
||||
|
||||
|
||||
class PrivateKeyInfo(crypto_utils.OpenSSLObject):
|
||||
class PrivateKeyInfo(OpenSSLObject):
|
||||
def __init__(self, module, backend):
|
||||
super(PrivateKeyInfo, self).__init__(
|
||||
module.params['path'] or '',
|
||||
@@ -336,11 +334,11 @@ class PrivateKeyInfo(crypto_utils.OpenSSLObject):
|
||||
self.return_private_key_data = module.params['return_private_key_data']
|
||||
|
||||
def generate(self):
|
||||
# Empty method because crypto_utils.OpenSSLObject wants this
|
||||
# Empty method because OpenSSLObject wants this
|
||||
pass
|
||||
|
||||
def dump(self):
|
||||
# Empty method because crypto_utils.OpenSSLObject wants this
|
||||
# Empty method because OpenSSLObject wants this
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
@@ -372,19 +370,19 @@ class PrivateKeyInfo(crypto_utils.OpenSSLObject):
|
||||
except (IOError, OSError) as exc:
|
||||
self.module.fail_json(msg=to_native(exc), **result)
|
||||
try:
|
||||
self.key = crypto_utils.load_privatekey(
|
||||
self.key = load_privatekey(
|
||||
path=None,
|
||||
content=priv_key_detail,
|
||||
passphrase=to_bytes(self.passphrase) if self.passphrase is not None else self.passphrase,
|
||||
backend=self.backend
|
||||
)
|
||||
result['can_parse_key'] = True
|
||||
except crypto_utils.OpenSSLObjectError as exc:
|
||||
except OpenSSLObjectError as exc:
|
||||
self.module.fail_json(msg=to_native(exc), **result)
|
||||
|
||||
result['public_key'] = self._get_public_key(binary=False)
|
||||
pk = self._get_public_key(binary=True)
|
||||
result['public_key_fingerprints'] = crypto_utils.get_fingerprint_of_bytes(pk) if pk is not None else dict()
|
||||
result['public_key_fingerprints'] = get_fingerprint_of_bytes(pk) if pk is not None else dict()
|
||||
|
||||
key_type, key_public_data, key_private_data = self._get_key_info()
|
||||
result['type'] = key_type
|
||||
@@ -643,7 +641,7 @@ def main():
|
||||
|
||||
result = privatekey.get_info()
|
||||
module.exit_json(**result)
|
||||
except crypto_utils.OpenSSLObjectError as exc:
|
||||
except OpenSSLObjectError as exc:
|
||||
module.fail_json(msg=to_native(exc))
|
||||
|
||||
|
||||
|
||||
@@ -184,7 +184,21 @@ from distutils.version import LooseVersion
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils._text import to_native
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils import crypto as crypto_utils
|
||||
from ansible_collections.community.crypto.plugins.module_utils.io import (
|
||||
load_file_if_exists,
|
||||
write_file,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
OpenSSLObjectError,
|
||||
OpenSSLBadPassphraseError,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
OpenSSLObject,
|
||||
load_privatekey,
|
||||
get_fingerprint,
|
||||
)
|
||||
|
||||
MINIMAL_PYOPENSSL_VERSION = '16.0.0'
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = '1.2.3'
|
||||
@@ -214,11 +228,11 @@ else:
|
||||
CRYPTOGRAPHY_FOUND = True
|
||||
|
||||
|
||||
class PublicKeyError(crypto_utils.OpenSSLObjectError):
|
||||
class PublicKeyError(OpenSSLObjectError):
|
||||
pass
|
||||
|
||||
|
||||
class PublicKey(crypto_utils.OpenSSLObject):
|
||||
class PublicKey(OpenSSLObject):
|
||||
|
||||
def __init__(self, module, backend):
|
||||
super(PublicKey, self).__init__(
|
||||
@@ -243,7 +257,7 @@ class PublicKey(crypto_utils.OpenSSLObject):
|
||||
self.backup_file = None
|
||||
|
||||
def _create_publickey(self, module):
|
||||
self.privatekey = crypto_utils.load_privatekey(
|
||||
self.privatekey = load_privatekey(
|
||||
path=self.privatekey_path,
|
||||
content=self.privatekey_content,
|
||||
passphrase=self.privatekey_passphrase,
|
||||
@@ -282,15 +296,15 @@ class PublicKey(crypto_utils.OpenSSLObject):
|
||||
|
||||
if self.backup:
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
crypto_utils.write_file(module, publickey_content)
|
||||
write_file(module, publickey_content)
|
||||
|
||||
self.changed = True
|
||||
except crypto_utils.OpenSSLBadPassphraseError as exc:
|
||||
except OpenSSLBadPassphraseError as exc:
|
||||
raise PublicKeyError(exc)
|
||||
except (IOError, OSError) as exc:
|
||||
raise PublicKeyError(exc)
|
||||
|
||||
self.fingerprint = crypto_utils.get_fingerprint(
|
||||
self.fingerprint = get_fingerprint(
|
||||
path=self.privatekey_path,
|
||||
content=self.privatekey_content,
|
||||
passphrase=self.privatekey_passphrase,
|
||||
@@ -338,7 +352,7 @@ class PublicKey(crypto_utils.OpenSSLObject):
|
||||
|
||||
try:
|
||||
desired_publickey = self._create_publickey(module)
|
||||
except crypto_utils.OpenSSLBadPassphraseError as exc:
|
||||
except OpenSSLBadPassphraseError as exc:
|
||||
raise PublicKeyError(exc)
|
||||
|
||||
return publickey_content == desired_publickey
|
||||
@@ -367,7 +381,7 @@ class PublicKey(crypto_utils.OpenSSLObject):
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
if self.publickey_bytes is None:
|
||||
self.publickey_bytes = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
self.publickey_bytes = load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['publickey'] = self.publickey_bytes.decode('utf-8') if self.publickey_bytes else None
|
||||
|
||||
return result
|
||||
@@ -464,7 +478,7 @@ def main():
|
||||
|
||||
result = public_key.dump()
|
||||
module.exit_json(**result)
|
||||
except crypto_utils.OpenSSLObjectError as exc:
|
||||
except OpenSSLObjectError as exc:
|
||||
module.fail_json(msg=to_native(exc))
|
||||
|
||||
|
||||
|
||||
@@ -860,10 +860,38 @@ from random import randint
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils._text import to_native, to_bytes, to_text
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils import crypto as crypto_utils
|
||||
from ansible_collections.community.crypto.plugins.module_utils.compat import ipaddress as compat_ipaddress
|
||||
from ansible_collections.community.crypto.plugins.module_utils.ecs.api import ECSClient, RestOperationException, SessionConfigurationException
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.io import (
|
||||
load_file_if_exists,
|
||||
write_file,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
OpenSSLObjectError,
|
||||
OpenSSLBadPassphraseError,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
OpenSSLObject,
|
||||
load_privatekey,
|
||||
load_certificate,
|
||||
load_certificate_request,
|
||||
parse_name_field,
|
||||
get_relative_time_option,
|
||||
select_message_digest,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
cryptography_compare_public_keys,
|
||||
cryptography_get_name,
|
||||
cryptography_name_to_oid,
|
||||
cryptography_key_needs_digest_for_signing,
|
||||
cryptography_parse_key_usage_params,
|
||||
cryptography_serial_number_of_cert,
|
||||
)
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = '1.6'
|
||||
MINIMAL_PYOPENSSL_VERSION = '0.15'
|
||||
|
||||
@@ -894,11 +922,11 @@ else:
|
||||
CRYPTOGRAPHY_FOUND = True
|
||||
|
||||
|
||||
class CertificateError(crypto_utils.OpenSSLObjectError):
|
||||
class CertificateError(OpenSSLObjectError):
|
||||
pass
|
||||
|
||||
|
||||
class Certificate(crypto_utils.OpenSSLObject):
|
||||
class Certificate(OpenSSLObject):
|
||||
|
||||
def __init__(self, module, backend):
|
||||
super(Certificate, self).__init__(
|
||||
@@ -944,7 +972,7 @@ class Certificate(crypto_utils.OpenSSLObject):
|
||||
except OpenSSL.SSL.Error:
|
||||
return False
|
||||
elif self.backend == 'cryptography':
|
||||
return crypto_utils.cryptography_compare_public_keys(self.cert.public_key(), self.privatekey.public_key())
|
||||
return cryptography_compare_public_keys(self.cert.public_key(), self.privatekey.public_key())
|
||||
|
||||
def _validate_csr(self):
|
||||
if self.backend == 'pyopenssl':
|
||||
@@ -971,7 +999,7 @@ class Certificate(crypto_utils.OpenSSLObject):
|
||||
# Verify that CSR is signed by certificate's private key
|
||||
if not self.csr.is_signature_valid:
|
||||
return False
|
||||
if not crypto_utils.cryptography_compare_public_keys(self.csr.public_key(), self.cert.public_key()):
|
||||
if not cryptography_compare_public_keys(self.csr.public_key(), self.cert.public_key()):
|
||||
return False
|
||||
# Check subject
|
||||
if self.csr.subject != self.cert.subject:
|
||||
@@ -1012,25 +1040,25 @@ class Certificate(crypto_utils.OpenSSLObject):
|
||||
return False
|
||||
|
||||
try:
|
||||
self.cert = crypto_utils.load_certificate(self.path, backend=self.backend)
|
||||
self.cert = load_certificate(self.path, backend=self.backend)
|
||||
except Exception as dummy:
|
||||
return False
|
||||
|
||||
if self.privatekey_path or self.privatekey_content:
|
||||
try:
|
||||
self.privatekey = crypto_utils.load_privatekey(
|
||||
self.privatekey = load_privatekey(
|
||||
path=self.privatekey_path,
|
||||
content=self.privatekey_content,
|
||||
passphrase=self.privatekey_passphrase,
|
||||
backend=self.backend
|
||||
)
|
||||
except crypto_utils.OpenSSLBadPassphraseError as exc:
|
||||
except OpenSSLBadPassphraseError as exc:
|
||||
raise CertificateError(exc)
|
||||
if not self._validate_privatekey():
|
||||
return False
|
||||
|
||||
if self.csr_path or self.csr_content:
|
||||
self.csr = crypto_utils.load_certificate_request(
|
||||
self.csr = load_certificate_request(
|
||||
path=self.csr_path,
|
||||
content=self.csr_content,
|
||||
backend=self.backend
|
||||
@@ -1093,9 +1121,9 @@ class SelfSignedCertificateCryptography(Certificate):
|
||||
def __init__(self, module):
|
||||
super(SelfSignedCertificateCryptography, self).__init__(module, 'cryptography')
|
||||
self.create_subject_key_identifier = module.params['selfsigned_create_subject_key_identifier']
|
||||
self.notBefore = crypto_utils.get_relative_time_option(module.params['selfsigned_not_before'], 'selfsigned_not_before', backend=self.backend)
|
||||
self.notAfter = crypto_utils.get_relative_time_option(module.params['selfsigned_not_after'], 'selfsigned_not_after', backend=self.backend)
|
||||
self.digest = crypto_utils.select_message_digest(module.params['selfsigned_digest'])
|
||||
self.notBefore = get_relative_time_option(module.params['selfsigned_not_before'], 'selfsigned_not_before', backend=self.backend)
|
||||
self.notAfter = get_relative_time_option(module.params['selfsigned_not_after'], 'selfsigned_not_after', backend=self.backend)
|
||||
self.digest = select_message_digest(module.params['selfsigned_digest'])
|
||||
self.version = module.params['selfsigned_version']
|
||||
self.serial_number = x509.random_serial_number()
|
||||
|
||||
@@ -1108,7 +1136,7 @@ class SelfSignedCertificateCryptography(Certificate):
|
||||
'The private key file {0} does not exist'.format(self.privatekey_path)
|
||||
)
|
||||
|
||||
self.csr = crypto_utils.load_certificate_request(
|
||||
self.csr = load_certificate_request(
|
||||
path=self.csr_path,
|
||||
content=self.csr_content,
|
||||
backend=self.backend
|
||||
@@ -1116,16 +1144,16 @@ class SelfSignedCertificateCryptography(Certificate):
|
||||
self._module = module
|
||||
|
||||
try:
|
||||
self.privatekey = crypto_utils.load_privatekey(
|
||||
self.privatekey = load_privatekey(
|
||||
path=self.privatekey_path,
|
||||
content=self.privatekey_content,
|
||||
passphrase=self.privatekey_passphrase,
|
||||
backend=self.backend
|
||||
)
|
||||
except crypto_utils.OpenSSLBadPassphraseError as exc:
|
||||
except OpenSSLBadPassphraseError as exc:
|
||||
module.fail_json(msg=to_native(exc))
|
||||
|
||||
if crypto_utils.cryptography_key_needs_digest_for_signing(self.privatekey):
|
||||
if cryptography_key_needs_digest_for_signing(self.privatekey):
|
||||
if self.digest is None:
|
||||
raise CertificateError(
|
||||
'The digest %s is not supported with the cryptography backend' % module.params['selfsigned_digest']
|
||||
@@ -1180,10 +1208,10 @@ class SelfSignedCertificateCryptography(Certificate):
|
||||
|
||||
if self.backup:
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
crypto_utils.write_file(module, certificate.public_bytes(Encoding.PEM))
|
||||
write_file(module, certificate.public_bytes(Encoding.PEM))
|
||||
self.changed = True
|
||||
else:
|
||||
self.cert = crypto_utils.load_certificate(self.path, backend=self.backend)
|
||||
self.cert = load_certificate(self.path, backend=self.backend)
|
||||
|
||||
file_args = module.load_file_common_arguments(module.params)
|
||||
if module.set_fs_attributes_if_different(file_args, False):
|
||||
@@ -1200,7 +1228,7 @@ class SelfSignedCertificateCryptography(Certificate):
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
content = load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['certificate'] = content.decode('utf-8') if content else None
|
||||
|
||||
if check_mode:
|
||||
@@ -1213,7 +1241,7 @@ class SelfSignedCertificateCryptography(Certificate):
|
||||
result.update({
|
||||
'notBefore': self.cert.not_valid_before.strftime("%Y%m%d%H%M%SZ"),
|
||||
'notAfter': self.cert.not_valid_after.strftime("%Y%m%d%H%M%SZ"),
|
||||
'serial_number': self.cert.serial_number,
|
||||
'serial_number': cryptography_serial_number_of_cert(self.cert),
|
||||
})
|
||||
|
||||
return result
|
||||
@@ -1226,8 +1254,8 @@ class SelfSignedCertificate(Certificate):
|
||||
super(SelfSignedCertificate, self).__init__(module, 'pyopenssl')
|
||||
if module.params['selfsigned_create_subject_key_identifier'] != 'create_if_not_provided':
|
||||
module.fail_json(msg='selfsigned_create_subject_key_identifier cannot be used with the pyOpenSSL backend!')
|
||||
self.notBefore = crypto_utils.get_relative_time_option(module.params['selfsigned_not_before'], 'selfsigned_not_before', backend=self.backend)
|
||||
self.notAfter = crypto_utils.get_relative_time_option(module.params['selfsigned_not_after'], 'selfsigned_not_after', backend=self.backend)
|
||||
self.notBefore = get_relative_time_option(module.params['selfsigned_not_before'], 'selfsigned_not_before', backend=self.backend)
|
||||
self.notAfter = get_relative_time_option(module.params['selfsigned_not_after'], 'selfsigned_not_after', backend=self.backend)
|
||||
self.digest = module.params['selfsigned_digest']
|
||||
self.version = module.params['selfsigned_version']
|
||||
self.serial_number = randint(1000, 99999)
|
||||
@@ -1241,17 +1269,17 @@ class SelfSignedCertificate(Certificate):
|
||||
'The private key file {0} does not exist'.format(self.privatekey_path)
|
||||
)
|
||||
|
||||
self.csr = crypto_utils.load_certificate_request(
|
||||
self.csr = load_certificate_request(
|
||||
path=self.csr_path,
|
||||
content=self.csr_content,
|
||||
)
|
||||
try:
|
||||
self.privatekey = crypto_utils.load_privatekey(
|
||||
self.privatekey = load_privatekey(
|
||||
path=self.privatekey_path,
|
||||
content=self.privatekey_content,
|
||||
passphrase=self.privatekey_passphrase,
|
||||
)
|
||||
except crypto_utils.OpenSSLBadPassphraseError as exc:
|
||||
except OpenSSLBadPassphraseError as exc:
|
||||
module.fail_json(msg=str(exc))
|
||||
|
||||
def generate(self, module):
|
||||
@@ -1282,7 +1310,7 @@ class SelfSignedCertificate(Certificate):
|
||||
|
||||
if self.backup:
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
crypto_utils.write_file(module, crypto.dump_certificate(crypto.FILETYPE_PEM, self.cert))
|
||||
write_file(module, crypto.dump_certificate(crypto.FILETYPE_PEM, self.cert))
|
||||
self.changed = True
|
||||
|
||||
file_args = module.load_file_common_arguments(module.params)
|
||||
@@ -1300,7 +1328,7 @@ class SelfSignedCertificate(Certificate):
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
content = load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['certificate'] = content.decode('utf-8') if content else None
|
||||
|
||||
if check_mode:
|
||||
@@ -1325,9 +1353,9 @@ class OwnCACertificateCryptography(Certificate):
|
||||
super(OwnCACertificateCryptography, self).__init__(module, 'cryptography')
|
||||
self.create_subject_key_identifier = module.params['ownca_create_subject_key_identifier']
|
||||
self.create_authority_key_identifier = module.params['ownca_create_authority_key_identifier']
|
||||
self.notBefore = crypto_utils.get_relative_time_option(module.params['ownca_not_before'], 'ownca_not_before', backend=self.backend)
|
||||
self.notAfter = crypto_utils.get_relative_time_option(module.params['ownca_not_after'], 'ownca_not_after', backend=self.backend)
|
||||
self.digest = crypto_utils.select_message_digest(module.params['ownca_digest'])
|
||||
self.notBefore = get_relative_time_option(module.params['ownca_not_before'], 'ownca_not_before', backend=self.backend)
|
||||
self.notAfter = get_relative_time_option(module.params['ownca_not_after'], 'ownca_not_after', backend=self.backend)
|
||||
self.digest = select_message_digest(module.params['ownca_digest'])
|
||||
self.version = module.params['ownca_version']
|
||||
self.serial_number = x509.random_serial_number()
|
||||
self.ca_cert_path = module.params['ownca_path']
|
||||
@@ -1353,27 +1381,27 @@ class OwnCACertificateCryptography(Certificate):
|
||||
'The CA private key file {0} does not exist'.format(self.ca_privatekey_path)
|
||||
)
|
||||
|
||||
self.csr = crypto_utils.load_certificate_request(
|
||||
self.csr = load_certificate_request(
|
||||
path=self.csr_path,
|
||||
content=self.csr_content,
|
||||
backend=self.backend
|
||||
)
|
||||
self.ca_cert = crypto_utils.load_certificate(
|
||||
self.ca_cert = load_certificate(
|
||||
path=self.ca_cert_path,
|
||||
content=self.ca_cert_content,
|
||||
backend=self.backend
|
||||
)
|
||||
try:
|
||||
self.ca_private_key = crypto_utils.load_privatekey(
|
||||
self.ca_private_key = load_privatekey(
|
||||
path=self.ca_privatekey_path,
|
||||
content=self.ca_privatekey_content,
|
||||
passphrase=self.ca_privatekey_passphrase,
|
||||
backend=self.backend
|
||||
)
|
||||
except crypto_utils.OpenSSLBadPassphraseError as exc:
|
||||
except OpenSSLBadPassphraseError as exc:
|
||||
module.fail_json(msg=str(exc))
|
||||
|
||||
if crypto_utils.cryptography_key_needs_digest_for_signing(self.ca_private_key):
|
||||
if cryptography_key_needs_digest_for_signing(self.ca_private_key):
|
||||
if self.digest is None:
|
||||
raise CertificateError(
|
||||
'The digest %s is not supported with the cryptography backend' % module.params['ownca_digest']
|
||||
@@ -1449,10 +1477,10 @@ class OwnCACertificateCryptography(Certificate):
|
||||
|
||||
if self.backup:
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
crypto_utils.write_file(module, certificate.public_bytes(Encoding.PEM))
|
||||
write_file(module, certificate.public_bytes(Encoding.PEM))
|
||||
self.changed = True
|
||||
else:
|
||||
self.cert = crypto_utils.load_certificate(self.path, backend=self.backend)
|
||||
self.cert = load_certificate(self.path, backend=self.backend)
|
||||
|
||||
file_args = module.load_file_common_arguments(module.params)
|
||||
if module.set_fs_attributes_if_different(file_args, False):
|
||||
@@ -1497,7 +1525,7 @@ class OwnCACertificateCryptography(Certificate):
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
content = load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['certificate'] = content.decode('utf-8') if content else None
|
||||
|
||||
if check_mode:
|
||||
@@ -1510,7 +1538,7 @@ class OwnCACertificateCryptography(Certificate):
|
||||
result.update({
|
||||
'notBefore': self.cert.not_valid_before.strftime("%Y%m%d%H%M%SZ"),
|
||||
'notAfter': self.cert.not_valid_after.strftime("%Y%m%d%H%M%SZ"),
|
||||
'serial_number': self.cert.serial_number,
|
||||
'serial_number': cryptography_serial_number_of_cert(self.cert),
|
||||
})
|
||||
|
||||
return result
|
||||
@@ -1521,8 +1549,8 @@ class OwnCACertificate(Certificate):
|
||||
|
||||
def __init__(self, module):
|
||||
super(OwnCACertificate, self).__init__(module, 'pyopenssl')
|
||||
self.notBefore = crypto_utils.get_relative_time_option(module.params['ownca_not_before'], 'ownca_not_before', backend=self.backend)
|
||||
self.notAfter = crypto_utils.get_relative_time_option(module.params['ownca_not_after'], 'ownca_not_after', backend=self.backend)
|
||||
self.notBefore = get_relative_time_option(module.params['ownca_not_before'], 'ownca_not_before', backend=self.backend)
|
||||
self.notAfter = get_relative_time_option(module.params['ownca_not_after'], 'ownca_not_after', backend=self.backend)
|
||||
self.digest = module.params['ownca_digest']
|
||||
self.version = module.params['ownca_version']
|
||||
self.serial_number = randint(1000, 99999)
|
||||
@@ -1553,21 +1581,21 @@ class OwnCACertificate(Certificate):
|
||||
'The CA private key file {0} does not exist'.format(self.ca_privatekey_path)
|
||||
)
|
||||
|
||||
self.csr = crypto_utils.load_certificate_request(
|
||||
self.csr = load_certificate_request(
|
||||
path=self.csr_path,
|
||||
content=self.csr_content,
|
||||
)
|
||||
self.ca_cert = crypto_utils.load_certificate(
|
||||
self.ca_cert = load_certificate(
|
||||
path=self.ca_cert_path,
|
||||
content=self.ca_cert_content,
|
||||
)
|
||||
try:
|
||||
self.ca_privatekey = crypto_utils.load_privatekey(
|
||||
self.ca_privatekey = load_privatekey(
|
||||
path=self.ca_privatekey_path,
|
||||
content=self.ca_privatekey_content,
|
||||
passphrase=self.ca_privatekey_passphrase
|
||||
)
|
||||
except crypto_utils.OpenSSLBadPassphraseError as exc:
|
||||
except OpenSSLBadPassphraseError as exc:
|
||||
module.fail_json(msg=str(exc))
|
||||
|
||||
def generate(self, module):
|
||||
@@ -1603,7 +1631,7 @@ class OwnCACertificate(Certificate):
|
||||
|
||||
if self.backup:
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
crypto_utils.write_file(module, crypto.dump_certificate(crypto.FILETYPE_PEM, self.cert))
|
||||
write_file(module, crypto.dump_certificate(crypto.FILETYPE_PEM, self.cert))
|
||||
self.changed = True
|
||||
|
||||
file_args = module.load_file_common_arguments(module.params)
|
||||
@@ -1623,7 +1651,7 @@ class OwnCACertificate(Certificate):
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
content = load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['certificate'] = content.decode('utf-8') if content else None
|
||||
|
||||
if check_mode:
|
||||
@@ -1666,12 +1694,12 @@ class AssertOnlyCertificateBase(Certificate):
|
||||
|
||||
self.signature_algorithms = module.params['signature_algorithms']
|
||||
if module.params['subject']:
|
||||
self.subject = crypto_utils.parse_name_field(module.params['subject'])
|
||||
self.subject = parse_name_field(module.params['subject'])
|
||||
else:
|
||||
self.subject = []
|
||||
self.subject_strict = module.params['subject_strict']
|
||||
if module.params['issuer']:
|
||||
self.issuer = crypto_utils.parse_name_field(module.params['issuer'])
|
||||
self.issuer = parse_name_field(module.params['issuer'])
|
||||
else:
|
||||
self.issuer = []
|
||||
self.issuer_strict = module.params['issuer_strict']
|
||||
@@ -1696,19 +1724,19 @@ class AssertOnlyCertificateBase(Certificate):
|
||||
self.valid_in = "+" + self.valid_in + "s"
|
||||
|
||||
# Load objects
|
||||
self.cert = crypto_utils.load_certificate(self.path, backend=self.backend)
|
||||
self.cert = load_certificate(self.path, backend=self.backend)
|
||||
if self.privatekey_path is not None or self.privatekey_content is not None:
|
||||
try:
|
||||
self.privatekey = crypto_utils.load_privatekey(
|
||||
self.privatekey = load_privatekey(
|
||||
path=self.privatekey_path,
|
||||
content=self.privatekey_content,
|
||||
passphrase=self.privatekey_passphrase,
|
||||
backend=self.backend
|
||||
)
|
||||
except crypto_utils.OpenSSLBadPassphraseError as exc:
|
||||
except OpenSSLBadPassphraseError as exc:
|
||||
raise CertificateError(exc)
|
||||
if self.csr_path is not None or self.csr_content is not None:
|
||||
self.csr = crypto_utils.load_certificate_request(
|
||||
self.csr = load_certificate_request(
|
||||
path=self.csr_path,
|
||||
content=self.csr_content,
|
||||
backend=self.backend
|
||||
@@ -1883,7 +1911,7 @@ class AssertOnlyCertificateBase(Certificate):
|
||||
|
||||
if self.not_before is not None:
|
||||
cert_not_valid_before = self._validate_not_before()
|
||||
if cert_not_valid_before != crypto_utils.get_relative_time_option(self.not_before, 'not_before', backend=self.backend):
|
||||
if cert_not_valid_before != get_relative_time_option(self.not_before, 'not_before', backend=self.backend):
|
||||
messages.append(
|
||||
'Invalid not_before component (got %s, expected %s to be present)' %
|
||||
(cert_not_valid_before, self.not_before)
|
||||
@@ -1891,7 +1919,7 @@ class AssertOnlyCertificateBase(Certificate):
|
||||
|
||||
if self.not_after is not None:
|
||||
cert_not_valid_after = self._validate_not_after()
|
||||
if cert_not_valid_after != crypto_utils.get_relative_time_option(self.not_after, 'not_after', backend=self.backend):
|
||||
if cert_not_valid_after != get_relative_time_option(self.not_after, 'not_after', backend=self.backend):
|
||||
messages.append(
|
||||
'Invalid not_after component (got %s, expected %s to be present)' %
|
||||
(cert_not_valid_after, self.not_after)
|
||||
@@ -1941,7 +1969,7 @@ class AssertOnlyCertificateBase(Certificate):
|
||||
'csr': self.csr_path,
|
||||
}
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
content = load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['certificate'] = content.decode('utf-8') if content else None
|
||||
return result
|
||||
|
||||
@@ -1952,12 +1980,12 @@ class AssertOnlyCertificateCryptography(AssertOnlyCertificateBase):
|
||||
super(AssertOnlyCertificateCryptography, self).__init__(module, 'cryptography')
|
||||
|
||||
def _validate_privatekey(self):
|
||||
return crypto_utils.cryptography_compare_public_keys(self.cert.public_key(), self.privatekey.public_key())
|
||||
return cryptography_compare_public_keys(self.cert.public_key(), self.privatekey.public_key())
|
||||
|
||||
def _validate_csr_signature(self):
|
||||
if not self.csr.is_signature_valid:
|
||||
return False
|
||||
return crypto_utils.cryptography_compare_public_keys(self.csr.public_key(), self.cert.public_key())
|
||||
return cryptography_compare_public_keys(self.csr.public_key(), self.cert.public_key())
|
||||
|
||||
def _validate_csr_subject(self):
|
||||
return self.csr.subject == self.cert.subject
|
||||
@@ -1981,14 +2009,14 @@ class AssertOnlyCertificateCryptography(AssertOnlyCertificateBase):
|
||||
return self.cert.signature_algorithm_oid._name
|
||||
|
||||
def _validate_subject(self):
|
||||
expected_subject = Name([NameAttribute(oid=crypto_utils.cryptography_name_to_oid(sub[0]), value=to_text(sub[1]))
|
||||
expected_subject = Name([NameAttribute(oid=cryptography_name_to_oid(sub[0]), value=to_text(sub[1]))
|
||||
for sub in self.subject])
|
||||
cert_subject = self.cert.subject
|
||||
if not compare_sets(expected_subject, cert_subject, self.subject_strict):
|
||||
return expected_subject, cert_subject
|
||||
|
||||
def _validate_issuer(self):
|
||||
expected_issuer = Name([NameAttribute(oid=crypto_utils.cryptography_name_to_oid(iss[0]), value=to_text(iss[1]))
|
||||
expected_issuer = Name([NameAttribute(oid=cryptography_name_to_oid(iss[0]), value=to_text(iss[1]))
|
||||
for iss in self.issuer])
|
||||
cert_issuer = self.cert.issuer
|
||||
if not compare_sets(expected_issuer, cert_issuer, self.issuer_strict):
|
||||
@@ -2026,7 +2054,7 @@ class AssertOnlyCertificateCryptography(AssertOnlyCertificateBase):
|
||||
decipher_only=current_key_usage.decipher_only
|
||||
))
|
||||
|
||||
key_usages = crypto_utils.cryptography_parse_key_usage_params(self.key_usage)
|
||||
key_usages = cryptography_parse_key_usage_params(self.key_usage)
|
||||
if not compare_dicts(key_usages, test_key_usage, self.key_usage_strict):
|
||||
return self.key_usage, [k for k, v in test_key_usage.items() if v is True]
|
||||
|
||||
@@ -2038,7 +2066,7 @@ class AssertOnlyCertificateCryptography(AssertOnlyCertificateBase):
|
||||
def _validate_extended_key_usage(self):
|
||||
try:
|
||||
current_ext_keyusage = self.cert.extensions.get_extension_for_class(x509.ExtendedKeyUsage).value
|
||||
usages = [crypto_utils.cryptography_name_to_oid(usage) for usage in self.extended_key_usage]
|
||||
usages = [cryptography_name_to_oid(usage) for usage in self.extended_key_usage]
|
||||
expected_ext_keyusage = x509.ExtendedKeyUsage(usages)
|
||||
if not compare_sets(expected_ext_keyusage, current_ext_keyusage, self.extended_key_usage_strict):
|
||||
return [eku.value for eku in expected_ext_keyusage], [eku.value for eku in current_ext_keyusage]
|
||||
@@ -2051,7 +2079,7 @@ class AssertOnlyCertificateCryptography(AssertOnlyCertificateBase):
|
||||
def _validate_subject_alt_name(self):
|
||||
try:
|
||||
current_san = self.cert.extensions.get_extension_for_class(x509.SubjectAlternativeName).value
|
||||
expected_san = [crypto_utils.cryptography_get_name(san) for san in self.subject_alt_name]
|
||||
expected_san = [cryptography_get_name(san) for san in self.subject_alt_name]
|
||||
if not compare_sets(expected_san, current_san, self.subject_alt_name_strict):
|
||||
return self.subject_alt_name, current_san
|
||||
except cryptography.x509.ExtensionNotFound:
|
||||
@@ -2066,15 +2094,15 @@ class AssertOnlyCertificateCryptography(AssertOnlyCertificateBase):
|
||||
return self.cert.not_valid_after
|
||||
|
||||
def _validate_valid_at(self):
|
||||
rt = crypto_utils.get_relative_time_option(self.valid_at, 'valid_at', backend=self.backend)
|
||||
rt = get_relative_time_option(self.valid_at, 'valid_at', backend=self.backend)
|
||||
return self.cert.not_valid_before, rt, self.cert.not_valid_after
|
||||
|
||||
def _validate_invalid_at(self):
|
||||
rt = crypto_utils.get_relative_time_option(self.invalid_at, 'invalid_at', backend=self.backend)
|
||||
rt = get_relative_time_option(self.invalid_at, 'invalid_at', backend=self.backend)
|
||||
return self.cert.not_valid_before, rt, self.cert.not_valid_after
|
||||
|
||||
def _validate_valid_in(self):
|
||||
valid_in_date = crypto_utils.get_relative_time_option(self.valid_in, "valid_in", backend=self.backend)
|
||||
valid_in_date = get_relative_time_option(self.valid_in, "valid_in", backend=self.backend)
|
||||
return self.cert.not_valid_before, valid_in_date, self.cert.not_valid_after
|
||||
|
||||
|
||||
@@ -2231,17 +2259,17 @@ class AssertOnlyCertificate(AssertOnlyCertificateBase):
|
||||
return self.cert.get_notAfter()
|
||||
|
||||
def _validate_valid_at(self):
|
||||
rt = crypto_utils.get_relative_time_option(self.valid_at, "valid_at", backend=self.backend)
|
||||
rt = get_relative_time_option(self.valid_at, "valid_at", backend=self.backend)
|
||||
rt = to_bytes(rt, errors='surrogate_or_strict')
|
||||
return self.cert.get_notBefore(), rt, self.cert.get_notAfter()
|
||||
|
||||
def _validate_invalid_at(self):
|
||||
rt = crypto_utils.get_relative_time_option(self.invalid_at, "invalid_at", backend=self.backend)
|
||||
rt = get_relative_time_option(self.invalid_at, "invalid_at", backend=self.backend)
|
||||
rt = to_bytes(rt, errors='surrogate_or_strict')
|
||||
return self.cert.get_notBefore(), rt, self.cert.get_notAfter()
|
||||
|
||||
def _validate_valid_in(self):
|
||||
valid_in_asn1 = crypto_utils.get_relative_time_option(self.valid_in, "valid_in", backend=self.backend)
|
||||
valid_in_asn1 = get_relative_time_option(self.valid_in, "valid_in", backend=self.backend)
|
||||
valid_in_date = to_bytes(valid_in_asn1, errors='surrogate_or_strict')
|
||||
return self.cert.get_notBefore(), valid_in_date, self.cert.get_notAfter()
|
||||
|
||||
@@ -2252,14 +2280,14 @@ class EntrustCertificate(Certificate):
|
||||
def __init__(self, module, backend):
|
||||
super(EntrustCertificate, self).__init__(module, backend)
|
||||
self.trackingId = None
|
||||
self.notAfter = crypto_utils.get_relative_time_option(module.params['entrust_not_after'], 'entrust_not_after', backend=self.backend)
|
||||
self.notAfter = get_relative_time_option(module.params['entrust_not_after'], 'entrust_not_after', backend=self.backend)
|
||||
|
||||
if self.csr_content is None or not os.path.exists(self.csr_path):
|
||||
raise CertificateError(
|
||||
'The certificate signing request file {0} does not exist'.format(self.csr_path)
|
||||
)
|
||||
|
||||
self.csr = crypto_utils.load_certificate_request(
|
||||
self.csr = load_certificate_request(
|
||||
path=self.csr_path,
|
||||
content=self.csr_content,
|
||||
backend=self.backend,
|
||||
@@ -2339,8 +2367,8 @@ class EntrustCertificate(Certificate):
|
||||
|
||||
if self.backup:
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
crypto_utils.write_file(module, to_bytes(result.get('endEntityCert')))
|
||||
self.cert = crypto_utils.load_certificate(self.path, backend=self.backend)
|
||||
write_file(module, to_bytes(result.get('endEntityCert')))
|
||||
self.cert = load_certificate(self.path, backend=self.backend)
|
||||
self.changed = True
|
||||
|
||||
def check(self, module, perms_required=True):
|
||||
@@ -2374,7 +2402,7 @@ class EntrustCertificate(Certificate):
|
||||
time_string = to_native(self.cert.get_notAfter())
|
||||
expiry = datetime.datetime.strptime(time_string, "%Y%m%d%H%M%SZ")
|
||||
elif self.backend == 'cryptography':
|
||||
serial_number = "{0:X}".format(self.cert.serial_number)
|
||||
serial_number = "{0:X}".format(cryptography_serial_number_of_cert(self.cert))
|
||||
expiry = self.cert.not_valid_after
|
||||
|
||||
# get some information about the expiry of this certificate
|
||||
@@ -2409,7 +2437,7 @@ class EntrustCertificate(Certificate):
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
content = load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['certificate'] = content.decode('utf-8') if content else None
|
||||
|
||||
result.update(self._get_cert_details())
|
||||
@@ -2480,7 +2508,7 @@ class AcmeCertificate(Certificate):
|
||||
crt = module.run_command(command, check_rc=True)[1]
|
||||
if self.backup:
|
||||
self.backup_file = module.backup_local(self.path)
|
||||
crypto_utils.write_file(module, to_bytes(crt))
|
||||
write_file(module, to_bytes(crt))
|
||||
self.changed = True
|
||||
except OSError as exc:
|
||||
raise CertificateError(exc)
|
||||
@@ -2501,7 +2529,7 @@ class AcmeCertificate(Certificate):
|
||||
if self.backup_file:
|
||||
result['backup_file'] = self.backup_file
|
||||
if self.return_content:
|
||||
content = crypto_utils.load_file_if_exists(self.path, ignore_errors=True)
|
||||
content = load_file_if_exists(self.path, ignore_errors=True)
|
||||
result['certificate'] = content.decode('utf-8') if content else None
|
||||
|
||||
return result
|
||||
@@ -2724,7 +2752,7 @@ def main():
|
||||
|
||||
result = certificate.dump()
|
||||
module.exit_json(**result)
|
||||
except crypto_utils.OpenSSLObjectError as exc:
|
||||
except OpenSSLObjectError as exc:
|
||||
module.fail_json(msg=to_native(exc))
|
||||
|
||||
|
||||
|
||||
@@ -306,9 +306,31 @@ from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils.six import string_types
|
||||
from ansible.module_utils._text import to_native, to_text, to_bytes
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils import crypto as crypto_utils
|
||||
from ansible_collections.community.crypto.plugins.module_utils.compat import ipaddress as compat_ipaddress
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
OpenSSLObjectError,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
OpenSSLObject,
|
||||
get_relative_time_option,
|
||||
load_certificate,
|
||||
get_fingerprint_of_bytes,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
cryptography_decode_name,
|
||||
cryptography_get_extensions_from_cert,
|
||||
cryptography_oid_to_name,
|
||||
cryptography_serial_number_of_cert,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.pyopenssl_support import (
|
||||
pyopenssl_get_extensions_from_cert,
|
||||
pyopenssl_normalize_name,
|
||||
)
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = '1.6'
|
||||
MINIMAL_PYOPENSSL_VERSION = '0.15'
|
||||
|
||||
@@ -347,7 +369,7 @@ else:
|
||||
TIMESTAMP_FORMAT = "%Y%m%d%H%M%SZ"
|
||||
|
||||
|
||||
class CertificateInfo(crypto_utils.OpenSSLObject):
|
||||
class CertificateInfo(OpenSSLObject):
|
||||
def __init__(self, module, backend):
|
||||
super(CertificateInfo, self).__init__(
|
||||
module.params['path'] or '',
|
||||
@@ -368,14 +390,14 @@ class CertificateInfo(crypto_utils.OpenSSLObject):
|
||||
self.module.fail_json(
|
||||
msg='The value for valid_at.{0} must be of type string (got {1})'.format(k, type(v))
|
||||
)
|
||||
self.valid_at[k] = crypto_utils.get_relative_time_option(v, 'valid_at.{0}'.format(k))
|
||||
self.valid_at[k] = get_relative_time_option(v, 'valid_at.{0}'.format(k))
|
||||
|
||||
def generate(self):
|
||||
# Empty method because crypto_utils.OpenSSLObject wants this
|
||||
# Empty method because OpenSSLObject wants this
|
||||
pass
|
||||
|
||||
def dump(self):
|
||||
# Empty method because crypto_utils.OpenSSLObject wants this
|
||||
# Empty method because OpenSSLObject wants this
|
||||
pass
|
||||
|
||||
@abc.abstractmethod
|
||||
@@ -448,7 +470,7 @@ class CertificateInfo(crypto_utils.OpenSSLObject):
|
||||
|
||||
def get_info(self):
|
||||
result = dict()
|
||||
self.cert = crypto_utils.load_certificate(self.path, content=self.content, backend=self.backend)
|
||||
self.cert = load_certificate(self.path, content=self.content, backend=self.backend)
|
||||
|
||||
result['signature_algorithm'] = self._get_signature_algorithm()
|
||||
subject = self._get_subject_ordered()
|
||||
@@ -481,7 +503,7 @@ class CertificateInfo(crypto_utils.OpenSSLObject):
|
||||
|
||||
result['public_key'] = self._get_public_key(binary=False)
|
||||
pk = self._get_public_key(binary=True)
|
||||
result['public_key_fingerprints'] = crypto_utils.get_fingerprint_of_bytes(pk) if pk is not None else dict()
|
||||
result['public_key_fingerprints'] = get_fingerprint_of_bytes(pk) if pk is not None else dict()
|
||||
|
||||
if self.backend != 'pyopenssl':
|
||||
ski = self._get_subject_key_identifier()
|
||||
@@ -511,18 +533,18 @@ class CertificateInfoCryptography(CertificateInfo):
|
||||
super(CertificateInfoCryptography, self).__init__(module, 'cryptography')
|
||||
|
||||
def _get_signature_algorithm(self):
|
||||
return crypto_utils.cryptography_oid_to_name(self.cert.signature_algorithm_oid)
|
||||
return cryptography_oid_to_name(self.cert.signature_algorithm_oid)
|
||||
|
||||
def _get_subject_ordered(self):
|
||||
result = []
|
||||
for attribute in self.cert.subject:
|
||||
result.append([crypto_utils.cryptography_oid_to_name(attribute.oid), attribute.value])
|
||||
result.append([cryptography_oid_to_name(attribute.oid), attribute.value])
|
||||
return result
|
||||
|
||||
def _get_issuer_ordered(self):
|
||||
result = []
|
||||
for attribute in self.cert.issuer:
|
||||
result.append([crypto_utils.cryptography_oid_to_name(attribute.oid), attribute.value])
|
||||
result.append([cryptography_oid_to_name(attribute.oid), attribute.value])
|
||||
return result
|
||||
|
||||
def _get_version(self):
|
||||
@@ -574,7 +596,7 @@ class CertificateInfoCryptography(CertificateInfo):
|
||||
try:
|
||||
ext_keyusage_ext = self.cert.extensions.get_extension_for_class(x509.ExtendedKeyUsage)
|
||||
return sorted([
|
||||
crypto_utils.cryptography_oid_to_name(eku) for eku in ext_keyusage_ext.value
|
||||
cryptography_oid_to_name(eku) for eku in ext_keyusage_ext.value
|
||||
]), ext_keyusage_ext.critical
|
||||
except cryptography.x509.ExtensionNotFound:
|
||||
return None, False
|
||||
@@ -608,7 +630,7 @@ class CertificateInfoCryptography(CertificateInfo):
|
||||
def _get_subject_alt_name(self):
|
||||
try:
|
||||
san_ext = self.cert.extensions.get_extension_for_class(x509.SubjectAlternativeName)
|
||||
result = [crypto_utils.cryptography_decode_name(san) for san in san_ext.value]
|
||||
result = [cryptography_decode_name(san) for san in san_ext.value]
|
||||
return result, san_ext.critical
|
||||
except cryptography.x509.ExtensionNotFound:
|
||||
return None, False
|
||||
@@ -637,16 +659,16 @@ class CertificateInfoCryptography(CertificateInfo):
|
||||
ext = self.cert.extensions.get_extension_for_class(x509.AuthorityKeyIdentifier)
|
||||
issuer = None
|
||||
if ext.value.authority_cert_issuer is not None:
|
||||
issuer = [crypto_utils.cryptography_decode_name(san) for san in ext.value.authority_cert_issuer]
|
||||
issuer = [cryptography_decode_name(san) for san in ext.value.authority_cert_issuer]
|
||||
return ext.value.key_identifier, issuer, ext.value.authority_cert_serial_number
|
||||
except cryptography.x509.ExtensionNotFound:
|
||||
return None, None, None
|
||||
|
||||
def _get_serial_number(self):
|
||||
return self.cert.serial_number
|
||||
return cryptography_serial_number_of_cert(self.cert)
|
||||
|
||||
def _get_all_extensions(self):
|
||||
return crypto_utils.cryptography_get_extensions_from_cert(self.cert)
|
||||
return cryptography_get_extensions_from_cert(self.cert)
|
||||
|
||||
def _get_ocsp_uri(self):
|
||||
try:
|
||||
@@ -672,7 +694,7 @@ class CertificateInfoPyOpenSSL(CertificateInfo):
|
||||
def __get_name(self, name):
|
||||
result = []
|
||||
for sub in name.get_components():
|
||||
result.append([crypto_utils.pyopenssl_normalize_name(sub[0]), to_text(sub[1])])
|
||||
result.append([pyopenssl_normalize_name(sub[0]), to_text(sub[1])])
|
||||
return result
|
||||
|
||||
def _get_subject_ordered(self):
|
||||
@@ -691,7 +713,7 @@ class CertificateInfoPyOpenSSL(CertificateInfo):
|
||||
extension = self.cert.get_extension(extension_idx)
|
||||
if extension.get_short_name() == short_name:
|
||||
result = [
|
||||
crypto_utils.pyopenssl_normalize_name(usage.strip()) for usage in to_text(extension, errors='surrogate_or_strict').split(',')
|
||||
pyopenssl_normalize_name(usage.strip()) for usage in to_text(extension, errors='surrogate_or_strict').split(',')
|
||||
]
|
||||
return sorted(result), bool(extension.get_critical())
|
||||
return None, False
|
||||
@@ -777,7 +799,7 @@ class CertificateInfoPyOpenSSL(CertificateInfo):
|
||||
return self.cert.get_serial_number()
|
||||
|
||||
def _get_all_extensions(self):
|
||||
return crypto_utils.pyopenssl_get_extensions_from_cert(self.cert)
|
||||
return pyopenssl_get_extensions_from_cert(self.cert)
|
||||
|
||||
def _get_ocsp_uri(self):
|
||||
for i in range(self.cert.get_extension_count()):
|
||||
@@ -856,7 +878,7 @@ def main():
|
||||
|
||||
result = certificate.get_info()
|
||||
module.exit_json(**result)
|
||||
except crypto_utils.OpenSSLObjectError as exc:
|
||||
except OpenSSLObjectError as exc:
|
||||
module.fail_json(msg=to_native(exc))
|
||||
|
||||
|
||||
|
||||
@@ -354,7 +354,38 @@ from distutils.version import LooseVersion
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils._text import to_native, to_text
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils import crypto as crypto_utils
|
||||
from ansible_collections.community.crypto.plugins.module_utils.io import (
|
||||
write_file,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
OpenSSLObjectError,
|
||||
OpenSSLBadPassphraseError,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
OpenSSLObject,
|
||||
load_privatekey,
|
||||
load_certificate,
|
||||
parse_name_field,
|
||||
get_relative_time_option,
|
||||
select_message_digest,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
cryptography_get_name,
|
||||
cryptography_name_to_oid,
|
||||
cryptography_oid_to_name,
|
||||
cryptography_serial_number_of_cert,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_crl import (
|
||||
REVOCATION_REASON_MAP,
|
||||
TIMESTAMP_FORMAT,
|
||||
cryptography_decode_revoked_certificate,
|
||||
cryptography_dump_revoked,
|
||||
cryptography_get_signature_algorithm_oid_from_crl,
|
||||
)
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = '1.2'
|
||||
|
||||
@@ -378,14 +409,11 @@ else:
|
||||
CRYPTOGRAPHY_FOUND = True
|
||||
|
||||
|
||||
TIMESTAMP_FORMAT = "%Y%m%d%H%M%SZ"
|
||||
|
||||
|
||||
class CRLError(crypto_utils.OpenSSLObjectError):
|
||||
class CRLError(OpenSSLObjectError):
|
||||
pass
|
||||
|
||||
|
||||
class CRL(crypto_utils.OpenSSLObject):
|
||||
class CRL(OpenSSLObject):
|
||||
|
||||
def __init__(self, module):
|
||||
super(CRL, self).__init__(
|
||||
@@ -406,13 +434,13 @@ class CRL(crypto_utils.OpenSSLObject):
|
||||
self.privatekey_content = self.privatekey_content.encode('utf-8')
|
||||
self.privatekey_passphrase = module.params['privatekey_passphrase']
|
||||
|
||||
self.issuer = crypto_utils.parse_name_field(module.params['issuer'])
|
||||
self.issuer = parse_name_field(module.params['issuer'])
|
||||
self.issuer = [(entry[0], entry[1]) for entry in self.issuer if entry[1]]
|
||||
|
||||
self.last_update = crypto_utils.get_relative_time_option(module.params['last_update'], 'last_update')
|
||||
self.next_update = crypto_utils.get_relative_time_option(module.params['next_update'], 'next_update')
|
||||
self.last_update = get_relative_time_option(module.params['last_update'], 'last_update')
|
||||
self.next_update = get_relative_time_option(module.params['next_update'], 'next_update')
|
||||
|
||||
self.digest = crypto_utils.select_message_digest(module.params['digest'])
|
||||
self.digest = select_message_digest(module.params['digest'])
|
||||
if self.digest is None:
|
||||
raise CRLError('The digest "{0}" is not supported'.format(module.params['digest']))
|
||||
|
||||
@@ -434,13 +462,9 @@ class CRL(crypto_utils.OpenSSLObject):
|
||||
try:
|
||||
if rc['content'] is not None:
|
||||
rc['content'] = rc['content'].encode('utf-8')
|
||||
cert = crypto_utils.load_certificate(rc['path'], content=rc['content'], backend='cryptography')
|
||||
try:
|
||||
result['serial_number'] = cert.serial_number
|
||||
except AttributeError:
|
||||
# The property was called "serial" before cryptography 1.4
|
||||
result['serial_number'] = cert.serial
|
||||
except crypto_utils.OpenSSLObjectError as e:
|
||||
cert = load_certificate(rc['path'], content=rc['content'], backend='cryptography')
|
||||
result['serial_number'] = cryptography_serial_number_of_cert(cert)
|
||||
except OpenSSLObjectError as e:
|
||||
if rc['content'] is not None:
|
||||
module.fail_json(
|
||||
msg='Cannot parse certificate from {0}content: {1}'.format(path_prefix, to_native(e))
|
||||
@@ -454,17 +478,17 @@ class CRL(crypto_utils.OpenSSLObject):
|
||||
result['serial_number'] = rc['serial_number']
|
||||
# All other options
|
||||
if rc['issuer']:
|
||||
result['issuer'] = [crypto_utils.cryptography_get_name(issuer) for issuer in rc['issuer']]
|
||||
result['issuer'] = [cryptography_get_name(issuer) for issuer in rc['issuer']]
|
||||
result['issuer_critical'] = rc['issuer_critical']
|
||||
result['revocation_date'] = crypto_utils.get_relative_time_option(
|
||||
result['revocation_date'] = get_relative_time_option(
|
||||
rc['revocation_date'],
|
||||
path_prefix + 'revocation_date'
|
||||
)
|
||||
if rc['reason']:
|
||||
result['reason'] = crypto_utils.REVOCATION_REASON_MAP[rc['reason']]
|
||||
result['reason'] = REVOCATION_REASON_MAP[rc['reason']]
|
||||
result['reason_critical'] = rc['reason_critical']
|
||||
if rc['invalidity_date']:
|
||||
result['invalidity_date'] = crypto_utils.get_relative_time_option(
|
||||
result['invalidity_date'] = get_relative_time_option(
|
||||
rc['invalidity_date'],
|
||||
path_prefix + 'invalidity_date'
|
||||
)
|
||||
@@ -477,13 +501,13 @@ class CRL(crypto_utils.OpenSSLObject):
|
||||
self.backup_file = None
|
||||
|
||||
try:
|
||||
self.privatekey = crypto_utils.load_privatekey(
|
||||
self.privatekey = load_privatekey(
|
||||
path=self.privatekey_path,
|
||||
content=self.privatekey_content,
|
||||
passphrase=self.privatekey_passphrase,
|
||||
backend='cryptography'
|
||||
)
|
||||
except crypto_utils.OpenSSLBadPassphraseError as exc:
|
||||
except OpenSSLBadPassphraseError as exc:
|
||||
raise CRLError(exc)
|
||||
|
||||
self.crl = None
|
||||
@@ -543,11 +567,11 @@ class CRL(crypto_utils.OpenSSLObject):
|
||||
if self.digest.name != self.crl.signature_hash_algorithm.name:
|
||||
return False
|
||||
|
||||
want_issuer = [(crypto_utils.cryptography_name_to_oid(entry[0]), entry[1]) for entry in self.issuer]
|
||||
want_issuer = [(cryptography_name_to_oid(entry[0]), entry[1]) for entry in self.issuer]
|
||||
if want_issuer != [(sub.oid, sub.value) for sub in self.crl.issuer]:
|
||||
return False
|
||||
|
||||
old_entries = [self._compress_entry(crypto_utils.cryptography_decode_revoked_certificate(cert)) for cert in self.crl]
|
||||
old_entries = [self._compress_entry(cryptography_decode_revoked_certificate(cert)) for cert in self.crl]
|
||||
new_entries = [self._compress_entry(cert) for cert in self.revoked_certificates]
|
||||
if self.update:
|
||||
# We don't simply use a set so that duplicate entries are treated correctly
|
||||
@@ -568,7 +592,7 @@ class CRL(crypto_utils.OpenSSLObject):
|
||||
|
||||
try:
|
||||
crl = crl.issuer_name(Name([
|
||||
NameAttribute(crypto_utils.cryptography_name_to_oid(entry[0]), to_text(entry[1]))
|
||||
NameAttribute(cryptography_name_to_oid(entry[0]), to_text(entry[1]))
|
||||
for entry in self.issuer
|
||||
]))
|
||||
except ValueError as e:
|
||||
@@ -580,7 +604,7 @@ class CRL(crypto_utils.OpenSSLObject):
|
||||
if self.update and self.crl:
|
||||
new_entries = set([self._compress_entry(entry) for entry in self.revoked_certificates])
|
||||
for entry in self.crl:
|
||||
decoded_entry = self._compress_entry(crypto_utils.cryptography_decode_revoked_certificate(entry))
|
||||
decoded_entry = self._compress_entry(cryptography_decode_revoked_certificate(entry))
|
||||
if decoded_entry not in new_entries:
|
||||
crl = crl.add_revoked_certificate(entry)
|
||||
for entry in self.revoked_certificates:
|
||||
@@ -590,7 +614,7 @@ class CRL(crypto_utils.OpenSSLObject):
|
||||
if entry['issuer'] is not None:
|
||||
revoked_cert = revoked_cert.add_extension(
|
||||
x509.CertificateIssuer([
|
||||
crypto_utils.cryptography_get_name(name) for name in self.entry['issuer']
|
||||
cryptography_get_name(name) for name in entry['issuer']
|
||||
]),
|
||||
entry['issuer_critical']
|
||||
)
|
||||
@@ -616,29 +640,13 @@ class CRL(crypto_utils.OpenSSLObject):
|
||||
self.crl_content = result
|
||||
if self.backup:
|
||||
self.backup_file = self.module.backup_local(self.path)
|
||||
crypto_utils.write_file(self.module, result)
|
||||
write_file(self.module, result)
|
||||
self.changed = True
|
||||
|
||||
file_args = self.module.load_file_common_arguments(self.module.params)
|
||||
if self.module.set_fs_attributes_if_different(file_args, False):
|
||||
self.changed = True
|
||||
|
||||
def _dump_revoked(self, entry):
|
||||
return {
|
||||
'serial_number': entry['serial_number'],
|
||||
'revocation_date': entry['revocation_date'].strftime(TIMESTAMP_FORMAT),
|
||||
'issuer':
|
||||
[crypto_utils.cryptography_decode_name(issuer) for issuer in entry['issuer']]
|
||||
if entry['issuer'] is not None else None,
|
||||
'issuer_critical': entry['issuer_critical'],
|
||||
'reason': crypto_utils.REVOCATION_REASON_MAP_INVERSE.get(entry['reason']) if entry['reason'] is not None else None,
|
||||
'reason_critical': entry['reason_critical'],
|
||||
'invalidity_date':
|
||||
entry['invalidity_date'].strftime(TIMESTAMP_FORMAT)
|
||||
if entry['invalidity_date'] is not None else None,
|
||||
'invalidity_date_critical': entry['invalidity_date_critical'],
|
||||
}
|
||||
|
||||
def dump(self, check_mode=False):
|
||||
result = {
|
||||
'changed': self.changed,
|
||||
@@ -657,7 +665,7 @@ class CRL(crypto_utils.OpenSSLObject):
|
||||
if check_mode:
|
||||
result['last_update'] = self.last_update.strftime(TIMESTAMP_FORMAT)
|
||||
result['next_update'] = self.next_update.strftime(TIMESTAMP_FORMAT)
|
||||
# result['digest'] = crypto_utils.cryptography_oid_to_name(self.crl.signature_algorithm_oid)
|
||||
# result['digest'] = cryptography_oid_to_name(self.crl.signature_algorithm_oid)
|
||||
result['digest'] = self.module.params['digest']
|
||||
result['issuer_ordered'] = self.issuer
|
||||
result['issuer'] = {}
|
||||
@@ -665,32 +673,22 @@ class CRL(crypto_utils.OpenSSLObject):
|
||||
result['issuer'][k] = v
|
||||
result['revoked_certificates'] = []
|
||||
for entry in self.revoked_certificates:
|
||||
result['revoked_certificates'].append(self._dump_revoked(entry))
|
||||
result['revoked_certificates'].append(cryptography_dump_revoked(entry))
|
||||
elif self.crl:
|
||||
result['last_update'] = self.crl.last_update.strftime(TIMESTAMP_FORMAT)
|
||||
result['next_update'] = self.crl.next_update.strftime(TIMESTAMP_FORMAT)
|
||||
try:
|
||||
result['digest'] = crypto_utils.cryptography_oid_to_name(self.crl.signature_algorithm_oid)
|
||||
except AttributeError:
|
||||
# Older cryptography versions don't have signature_algorithm_oid yet
|
||||
dotted = crypto_utils._obj2txt(
|
||||
self.crl._backend._lib,
|
||||
self.crl._backend._ffi,
|
||||
self.crl._x509_crl.sig_alg.algorithm
|
||||
)
|
||||
oid = x509.oid.ObjectIdentifier(dotted)
|
||||
result['digest'] = crypto_utils.cryptography_oid_to_name(oid)
|
||||
result['digest'] = cryptography_oid_to_name(cryptography_get_signature_algorithm_oid_from_crl(self.crl))
|
||||
issuer = []
|
||||
for attribute in self.crl.issuer:
|
||||
issuer.append([crypto_utils.cryptography_oid_to_name(attribute.oid), attribute.value])
|
||||
issuer.append([cryptography_oid_to_name(attribute.oid), attribute.value])
|
||||
result['issuer_ordered'] = issuer
|
||||
result['issuer'] = {}
|
||||
for k, v in issuer:
|
||||
result['issuer'][k] = v
|
||||
result['revoked_certificates'] = []
|
||||
for cert in self.crl:
|
||||
entry = crypto_utils.cryptography_decode_revoked_certificate(cert)
|
||||
result['revoked_certificates'].append(self._dump_revoked(entry))
|
||||
entry = cryptography_decode_revoked_certificate(cert)
|
||||
result['revoked_certificates'].append(cryptography_dump_revoked(entry))
|
||||
|
||||
if self.return_content:
|
||||
result['crl'] = self.crl_content
|
||||
@@ -776,7 +774,7 @@ def main():
|
||||
|
||||
result = crl.dump()
|
||||
module.exit_json(**result)
|
||||
except crypto_utils.OpenSSLObjectError as exc:
|
||||
except OpenSSLObjectError as exc:
|
||||
module.fail_json(msg=to_native(exc))
|
||||
|
||||
|
||||
|
||||
@@ -134,7 +134,26 @@ from distutils.version import LooseVersion
|
||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||
from ansible.module_utils._text import to_native
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils import crypto as crypto_utils
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.basic import (
|
||||
OpenSSLObjectError,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
OpenSSLObject,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
cryptography_oid_to_name,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_crl import (
|
||||
TIMESTAMP_FORMAT,
|
||||
cryptography_decode_revoked_certificate,
|
||||
cryptography_dump_revoked,
|
||||
cryptography_get_signature_algorithm_oid_from_crl,
|
||||
)
|
||||
|
||||
# crypto_utils
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = '1.2'
|
||||
|
||||
@@ -151,14 +170,11 @@ else:
|
||||
CRYPTOGRAPHY_FOUND = True
|
||||
|
||||
|
||||
TIMESTAMP_FORMAT = "%Y%m%d%H%M%SZ"
|
||||
|
||||
|
||||
class CRLError(crypto_utils.OpenSSLObjectError):
|
||||
class CRLError(OpenSSLObjectError):
|
||||
pass
|
||||
|
||||
|
||||
class CRLInfo(crypto_utils.OpenSSLObject):
|
||||
class CRLInfo(OpenSSLObject):
|
||||
"""The main module implementation."""
|
||||
|
||||
def __init__(self, module):
|
||||
@@ -188,22 +204,6 @@ class CRLInfo(crypto_utils.OpenSSLObject):
|
||||
except Exception as e:
|
||||
self.module.fail_json(msg='Error while decoding CRL: {0}'.format(e))
|
||||
|
||||
def _dump_revoked(self, entry):
|
||||
return {
|
||||
'serial_number': entry['serial_number'],
|
||||
'revocation_date': entry['revocation_date'].strftime(TIMESTAMP_FORMAT),
|
||||
'issuer':
|
||||
[crypto_utils.cryptography_decode_name(issuer) for issuer in entry['issuer']]
|
||||
if entry['issuer'] is not None else None,
|
||||
'issuer_critical': entry['issuer_critical'],
|
||||
'reason': crypto_utils.REVOCATION_REASON_MAP_INVERSE.get(entry['reason']) if entry['reason'] is not None else None,
|
||||
'reason_critical': entry['reason_critical'],
|
||||
'invalidity_date':
|
||||
entry['invalidity_date'].strftime(TIMESTAMP_FORMAT)
|
||||
if entry['invalidity_date'] is not None else None,
|
||||
'invalidity_date_critical': entry['invalidity_date_critical'],
|
||||
}
|
||||
|
||||
def get_info(self):
|
||||
result = {
|
||||
'changed': False,
|
||||
@@ -217,37 +217,27 @@ class CRLInfo(crypto_utils.OpenSSLObject):
|
||||
|
||||
result['last_update'] = self.crl.last_update.strftime(TIMESTAMP_FORMAT)
|
||||
result['next_update'] = self.crl.next_update.strftime(TIMESTAMP_FORMAT)
|
||||
try:
|
||||
result['digest'] = crypto_utils.cryptography_oid_to_name(self.crl.signature_algorithm_oid)
|
||||
except AttributeError:
|
||||
# Older cryptography versions don't have signature_algorithm_oid yet
|
||||
dotted = crypto_utils._obj2txt(
|
||||
self.crl._backend._lib,
|
||||
self.crl._backend._ffi,
|
||||
self.crl._x509_crl.sig_alg.algorithm
|
||||
)
|
||||
oid = x509.oid.ObjectIdentifier(dotted)
|
||||
result['digest'] = crypto_utils.cryptography_oid_to_name(oid)
|
||||
result['digest'] = cryptography_oid_to_name(cryptography_get_signature_algorithm_oid_from_crl(self.crl))
|
||||
issuer = []
|
||||
for attribute in self.crl.issuer:
|
||||
issuer.append([crypto_utils.cryptography_oid_to_name(attribute.oid), attribute.value])
|
||||
issuer.append([cryptography_oid_to_name(attribute.oid), attribute.value])
|
||||
result['issuer_ordered'] = issuer
|
||||
result['issuer'] = {}
|
||||
for k, v in issuer:
|
||||
result['issuer'][k] = v
|
||||
result['revoked_certificates'] = []
|
||||
for cert in self.crl:
|
||||
entry = crypto_utils.cryptography_decode_revoked_certificate(cert)
|
||||
result['revoked_certificates'].append(self._dump_revoked(entry))
|
||||
entry = cryptography_decode_revoked_certificate(cert)
|
||||
result['revoked_certificates'].append(cryptography_dump_revoked(entry))
|
||||
|
||||
return result
|
||||
|
||||
def generate(self):
|
||||
# Empty method because crypto_utils.OpenSSLObject wants this
|
||||
# Empty method because OpenSSLObject wants this
|
||||
pass
|
||||
|
||||
def dump(self):
|
||||
# Empty method because crypto_utils.OpenSSLObject wants this
|
||||
# Empty method because OpenSSLObject wants this
|
||||
pass
|
||||
|
||||
|
||||
@@ -274,7 +264,7 @@ def main():
|
||||
crl = CRLInfo(module)
|
||||
result = crl.get_info()
|
||||
module.exit_json(**result)
|
||||
except crypto_utils.OpenSSLObjectError as e:
|
||||
except OpenSSLObjectError as e:
|
||||
module.fail_json(msg=to_native(e))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user