mirror of
https://github.com/ansible-collections/community.crypto.git
synced 2026-05-06 13:22:58 +00:00
Use timezone aware functionality when using cryptography >= 42.0.0 (#727)
* Use timezone aware functionality when using cryptography >= 42.0.0. * Adjust OpenSSH certificate code to avoid functions deprecated in Python 3.12. * Strip timezone info from isoformat() output. * InvalidityDate.invalidity_date currently has no _utc variant.
This commit is contained in:
@@ -165,6 +165,16 @@ from ansible_collections.community.crypto.plugins.module_utils.acme.io import (
|
||||
read_file,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
get_now_datetime,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
CRYPTOGRAPHY_TIMEZONE,
|
||||
set_not_valid_after,
|
||||
set_not_valid_before,
|
||||
)
|
||||
|
||||
CRYPTOGRAPHY_IMP_ERR = None
|
||||
try:
|
||||
import cryptography
|
||||
@@ -244,8 +254,9 @@ def main():
|
||||
domain = to_text(challenge_data['resource'])
|
||||
identifier_type, identifier = to_text(challenge_data.get('resource_original', 'dns:' + challenge_data['resource'])).split(':', 1)
|
||||
subject = issuer = cryptography.x509.Name([])
|
||||
not_valid_before = datetime.datetime.utcnow()
|
||||
not_valid_after = datetime.datetime.utcnow() + datetime.timedelta(days=10)
|
||||
now = get_now_datetime(with_timezone=CRYPTOGRAPHY_TIMEZONE)
|
||||
not_valid_before = now
|
||||
not_valid_after = now + datetime.timedelta(days=10)
|
||||
if identifier_type == 'dns':
|
||||
san = cryptography.x509.DNSName(identifier)
|
||||
elif identifier_type == 'ip':
|
||||
@@ -254,7 +265,7 @@ def main():
|
||||
raise ModuleFailException('Unsupported identifier type "{0}"'.format(identifier_type))
|
||||
|
||||
# Generate regular self-signed certificate
|
||||
regular_certificate = cryptography.x509.CertificateBuilder().subject_name(
|
||||
cert_builder = cryptography.x509.CertificateBuilder().subject_name(
|
||||
subject
|
||||
).issuer_name(
|
||||
issuer
|
||||
@@ -262,14 +273,13 @@ def main():
|
||||
private_key.public_key()
|
||||
).serial_number(
|
||||
cryptography.x509.random_serial_number()
|
||||
).not_valid_before(
|
||||
not_valid_before
|
||||
).not_valid_after(
|
||||
not_valid_after
|
||||
).add_extension(
|
||||
cryptography.x509.SubjectAlternativeName([san]),
|
||||
critical=False,
|
||||
).sign(
|
||||
)
|
||||
cert_builder = set_not_valid_before(cert_builder, not_valid_before)
|
||||
cert_builder = set_not_valid_after(cert_builder, not_valid_after)
|
||||
regular_certificate = cert_builder.sign(
|
||||
private_key,
|
||||
cryptography.hazmat.primitives.hashes.SHA256(),
|
||||
_cryptography_backend
|
||||
@@ -278,7 +288,7 @@ def main():
|
||||
# Process challenge
|
||||
if challenge == 'tls-alpn-01':
|
||||
value = base64.b64decode(challenge_data['resource_value'])
|
||||
challenge_certificate = cryptography.x509.CertificateBuilder().subject_name(
|
||||
cert_builder = cryptography.x509.CertificateBuilder().subject_name(
|
||||
subject
|
||||
).issuer_name(
|
||||
issuer
|
||||
@@ -286,10 +296,6 @@ def main():
|
||||
private_key.public_key()
|
||||
).serial_number(
|
||||
cryptography.x509.random_serial_number()
|
||||
).not_valid_before(
|
||||
not_valid_before
|
||||
).not_valid_after(
|
||||
not_valid_after
|
||||
).add_extension(
|
||||
cryptography.x509.SubjectAlternativeName([san]),
|
||||
critical=False,
|
||||
@@ -299,7 +305,10 @@ def main():
|
||||
encode_octet_string(value),
|
||||
),
|
||||
critical=True,
|
||||
).sign(
|
||||
)
|
||||
cert_builder = set_not_valid_before(cert_builder, not_valid_before)
|
||||
cert_builder = set_not_valid_after(cert_builder, not_valid_after)
|
||||
challenge_certificate = cert_builder.sign(
|
||||
private_key,
|
||||
cryptography.hazmat.primitives.hashes.SHA256(),
|
||||
_cryptography_backend
|
||||
|
||||
@@ -209,7 +209,6 @@ EXAMPLES = '''
|
||||
|
||||
import atexit
|
||||
import base64
|
||||
import datetime
|
||||
import traceback
|
||||
|
||||
from os.path import isfile
|
||||
@@ -221,9 +220,16 @@ from ansible.module_utils.common.text.converters import to_bytes
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.version import LooseVersion
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.support import (
|
||||
get_now_datetime,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
CRYPTOGRAPHY_TIMEZONE,
|
||||
cryptography_oid_to_name,
|
||||
cryptography_get_extensions_from_cert,
|
||||
get_not_valid_after,
|
||||
get_not_valid_before,
|
||||
)
|
||||
|
||||
MINIMAL_CRYPTOGRAPHY_VERSION = '1.6'
|
||||
@@ -392,7 +398,7 @@ def main():
|
||||
for attribute in x509.subject:
|
||||
result['subject'][cryptography_oid_to_name(attribute.oid, short=True)] = attribute.value
|
||||
|
||||
result['expired'] = x509.not_valid_after < datetime.datetime.utcnow()
|
||||
result['expired'] = get_not_valid_after(x509) < get_now_datetime(with_timezone=CRYPTOGRAPHY_TIMEZONE)
|
||||
|
||||
result['extensions'] = []
|
||||
for dotted_number, entry in cryptography_get_extensions_from_cert(x509).items():
|
||||
@@ -410,8 +416,8 @@ def main():
|
||||
for attribute in x509.issuer:
|
||||
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['not_after'] = get_not_valid_after(x509).strftime('%Y%m%d%H%M%SZ')
|
||||
result['not_before'] = get_not_valid_before(x509).strftime('%Y%m%d%H%M%SZ')
|
||||
|
||||
result['serial_number'] = x509.serial_number
|
||||
result['signature_algorithm'] = cryptography_oid_to_name(x509.signature_algorithm_oid)
|
||||
|
||||
@@ -410,6 +410,10 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.support im
|
||||
get_relative_time_option,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
CRYPTOGRAPHY_TIMEZONE,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.module_backends.certificate_info import (
|
||||
select_backend,
|
||||
)
|
||||
@@ -451,7 +455,7 @@ def main():
|
||||
module.fail_json(
|
||||
msg='The value for valid_at.{0} must be of type string (got {1})'.format(k, type(v))
|
||||
)
|
||||
valid_at[k] = get_relative_time_option(v, 'valid_at.{0}'.format(k))
|
||||
valid_at[k] = get_relative_time_option(v, 'valid_at.{0}'.format(k), with_timezone=CRYPTOGRAPHY_TIMEZONE)
|
||||
|
||||
try:
|
||||
result = module_backend.get_info(der_support_enabled=module.params['content'] is None)
|
||||
|
||||
@@ -475,6 +475,7 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.support im
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_support import (
|
||||
CRYPTOGRAPHY_TIMEZONE,
|
||||
cryptography_decode_name,
|
||||
cryptography_get_name,
|
||||
cryptography_key_needs_digest_for_signing,
|
||||
@@ -484,11 +485,17 @@ from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptograp
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.cryptography_crl import (
|
||||
CRYPTOGRAPHY_TIMEZONE_INVALIDITY_DATE,
|
||||
REVOCATION_REASON_MAP,
|
||||
TIMESTAMP_FORMAT,
|
||||
cryptography_decode_revoked_certificate,
|
||||
cryptography_dump_revoked,
|
||||
cryptography_get_signature_algorithm_oid_from_crl,
|
||||
get_next_update,
|
||||
get_last_update,
|
||||
set_next_update,
|
||||
set_last_update,
|
||||
set_revocation_date,
|
||||
)
|
||||
|
||||
from ansible_collections.community.crypto.plugins.module_utils.crypto.pem import (
|
||||
@@ -560,8 +567,8 @@ class CRL(OpenSSLObject):
|
||||
except (TypeError, ValueError) as exc:
|
||||
module.fail_json(msg=to_native(exc))
|
||||
|
||||
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.last_update = get_relative_time_option(module.params['last_update'], 'last_update', with_timezone=CRYPTOGRAPHY_TIMEZONE)
|
||||
self.next_update = get_relative_time_option(module.params['next_update'], 'next_update', with_timezone=CRYPTOGRAPHY_TIMEZONE)
|
||||
|
||||
self.digest = select_message_digest(module.params['digest'])
|
||||
if self.digest is None:
|
||||
@@ -607,7 +614,8 @@ class CRL(OpenSSLObject):
|
||||
result['issuer_critical'] = rc['issuer_critical']
|
||||
result['revocation_date'] = get_relative_time_option(
|
||||
rc['revocation_date'],
|
||||
path_prefix + 'revocation_date'
|
||||
path_prefix + 'revocation_date',
|
||||
with_timezone=CRYPTOGRAPHY_TIMEZONE,
|
||||
)
|
||||
if rc['reason']:
|
||||
result['reason'] = REVOCATION_REASON_MAP[rc['reason']]
|
||||
@@ -615,7 +623,8 @@ class CRL(OpenSSLObject):
|
||||
if rc['invalidity_date']:
|
||||
result['invalidity_date'] = get_relative_time_option(
|
||||
rc['invalidity_date'],
|
||||
path_prefix + 'invalidity_date'
|
||||
path_prefix + 'invalidity_date',
|
||||
with_timezone=CRYPTOGRAPHY_TIMEZONE_INVALIDITY_DATE,
|
||||
)
|
||||
result['invalidity_date_critical'] = rc['invalidity_date_critical']
|
||||
self.revoked_certificates.append(result)
|
||||
@@ -731,9 +740,9 @@ class CRL(OpenSSLObject):
|
||||
if self.crl is None:
|
||||
return False
|
||||
|
||||
if self.last_update != self.crl.last_update and not self.ignore_timestamps:
|
||||
if self.last_update != get_last_update(self.crl) and not self.ignore_timestamps:
|
||||
return False
|
||||
if self.next_update != self.crl.next_update and not self.ignore_timestamps:
|
||||
if self.next_update != get_next_update(self.crl) and not self.ignore_timestamps:
|
||||
return False
|
||||
if cryptography_key_needs_digest_for_signing(self.privatekey):
|
||||
if self.crl.signature_hash_algorithm is None or self.digest.name != self.crl.signature_hash_algorithm.name:
|
||||
@@ -780,8 +789,8 @@ class CRL(OpenSSLObject):
|
||||
except ValueError as e:
|
||||
raise CRLError(e)
|
||||
|
||||
crl = crl.last_update(self.last_update)
|
||||
crl = crl.next_update(self.next_update)
|
||||
crl = set_last_update(crl, self.last_update)
|
||||
crl = set_next_update(crl, self.next_update)
|
||||
|
||||
if self.update and self.crl:
|
||||
new_entries = set([self._compress_entry(entry) for entry in self.revoked_certificates])
|
||||
@@ -792,7 +801,7 @@ class CRL(OpenSSLObject):
|
||||
for entry in self.revoked_certificates:
|
||||
revoked_cert = RevokedCertificateBuilder()
|
||||
revoked_cert = revoked_cert.serial_number(entry['serial_number'])
|
||||
revoked_cert = revoked_cert.revocation_date(entry['revocation_date'])
|
||||
revoked_cert = set_revocation_date(revoked_cert, entry['revocation_date'])
|
||||
if entry['issuer'] is not None:
|
||||
revoked_cert = revoked_cert.add_extension(
|
||||
x509.CertificateIssuer(entry['issuer']),
|
||||
@@ -876,8 +885,8 @@ class CRL(OpenSSLObject):
|
||||
for entry in self.revoked_certificates:
|
||||
result['revoked_certificates'].append(cryptography_dump_revoked(entry, idn_rewrite=self.name_encoding))
|
||||
elif self.crl:
|
||||
result['last_update'] = self.crl.last_update.strftime(TIMESTAMP_FORMAT)
|
||||
result['next_update'] = self.crl.next_update.strftime(TIMESTAMP_FORMAT)
|
||||
result['last_update'] = get_last_update(self.crl).strftime(TIMESTAMP_FORMAT)
|
||||
result['next_update'] = get_next_update(self.crl).strftime(TIMESTAMP_FORMAT)
|
||||
result['digest'] = cryptography_oid_to_name(cryptography_get_signature_algorithm_oid_from_crl(self.crl))
|
||||
issuer = []
|
||||
for attribute in self.crl.issuer:
|
||||
|
||||
Reference in New Issue
Block a user