Files
community.crypto/plugins/module_utils/_crypto/module_backends/crl_info.py

136 lines
4.4 KiB
Python

# Copyright (c) 2020, Felix Fontein <felix@fontein.de>
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later
# Note that this module util is **PRIVATE** to the collection. It can have breaking changes at any time.
# Do not use this from other collections or standalone plugins/modules!
from __future__ import annotations
import typing as t
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,
)
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.pem import (
identify_pem_format,
)
from ansible_collections.community.crypto.plugins.module_utils._cryptography_dep import (
COLLECTION_MINIMUM_CRYPTOGRAPHY_VERSION,
assert_required_cryptography_version,
)
if t.TYPE_CHECKING:
from ansible.module_utils.basic import AnsibleModule # pragma: no cover
from cryptography.hazmat.primitives.asymmetric.types import ( # pragma: no cover
PrivateKeyTypes,
)
from ansible_collections.community.crypto.plugins.plugin_utils._action_module import ( # pragma: no cover
AnsibleActionModule,
)
from ansible_collections.community.crypto.plugins.plugin_utils._filter_module import ( # pragma: no cover
FilterModuleMock,
)
GeneralAnsibleModule = t.Union[
AnsibleModule, AnsibleActionModule, FilterModuleMock
] # pragma: no cover
# crypto_utils
MINIMAL_CRYPTOGRAPHY_VERSION = COLLECTION_MINIMUM_CRYPTOGRAPHY_VERSION
try:
from cryptography import x509
except ImportError:
pass
class CRLInfoRetrieval:
def __init__(
self,
*,
module: GeneralAnsibleModule,
content: bytes,
list_revoked_certificates: bool = True,
) -> None:
# content must be a bytes string
self.module = module
self.content = content
self.list_revoked_certificates = list_revoked_certificates
self.name_encoding = module.params.get("name_encoding", "ignore")
def get_info(self) -> dict[str, t.Any]:
crl_pem = identify_pem_format(self.content)
try:
if crl_pem:
crl = x509.load_pem_x509_crl(self.content)
else:
crl = x509.load_der_x509_crl(self.content)
except ValueError as e:
self.module.fail_json(msg=f"Error while decoding CRL: {e}")
result: dict[str, t.Any] = {
"changed": False,
"format": "pem" if crl_pem else "der",
"last_update": None,
"next_update": None,
"digest": None,
"issuer_ordered": None,
"issuer": None,
}
result["last_update"] = crl.last_update.strftime(TIMESTAMP_FORMAT)
result["next_update"] = (
crl.next_update.strftime(TIMESTAMP_FORMAT) if crl.next_update else None
)
result["digest"] = cryptography_oid_to_name(
cryptography_get_signature_algorithm_oid_from_crl(crl)
)
issuer = []
for attribute in crl.issuer:
issuer.append([cryptography_oid_to_name(attribute.oid), attribute.value])
result["issuer_ordered"] = issuer
issuer_dict = {}
for k, v in issuer:
issuer_dict[k] = v
result["issuer"] = issuer_dict
if self.list_revoked_certificates:
result["revoked_certificates"] = []
for cert in crl:
entry = cryptography_decode_revoked_certificate(cert)
result["revoked_certificates"].append(
cryptography_dump_revoked(entry, idn_rewrite=self.name_encoding)
)
return result
def get_crl_info(
*,
module: GeneralAnsibleModule,
content: bytes,
list_revoked_certificates: bool = True,
) -> dict[str, t.Any]:
assert_required_cryptography_version(
module, minimum_cryptography_version=MINIMAL_CRYPTOGRAPHY_VERSION
)
info = CRLInfoRetrieval(
module=module,
content=content,
list_revoked_certificates=list_revoked_certificates,
)
return info.get_info()
__all__ = ("CRLInfoRetrieval", "get_crl_info")