|
| 1 | +# SPDX-License-Identifier: MPL-2.0 |
| 2 | +# Copyright 2020-2022 John Mille<[email protected]> |
| 3 | + |
| 4 | +""" |
| 5 | +Manages certbot certificates download from certbot-aws-store |
| 6 | +""" |
| 7 | + |
| 8 | +from __future__ import annotations |
| 9 | + |
| 10 | +import os |
| 11 | +from typing import TYPE_CHECKING |
| 12 | + |
| 13 | +from boto3.session import Session |
| 14 | + |
| 15 | +if TYPE_CHECKING: |
| 16 | + from .input import Model, CertbotAwsStoreCertificate |
| 17 | + |
| 18 | +from os import makedirs, path |
| 19 | + |
| 20 | +import jks as pyjks |
| 21 | +from certbot_aws_store.certificate import AcmeCertificate |
| 22 | +from OpenSSL import crypto |
| 23 | + |
| 24 | +from ecs_files_composer.common import LOG |
| 25 | + |
| 26 | + |
| 27 | +def create_jks_config( |
| 28 | + certificate_name: str, certificate_job: CertbotAwsStoreCertificate |
| 29 | +): |
| 30 | + with open( |
| 31 | + f"{certificate_job.storage_path}/{AcmeCertificate.full_chain_file_name}" |
| 32 | + ) as full_chain_fd: |
| 33 | + full_chain = crypto.load_certificate(crypto.FILETYPE_PEM, full_chain_fd.read()) |
| 34 | + with open( |
| 35 | + f"{certificate_job.storage_path}/{AcmeCertificate.private_key_file_name}" |
| 36 | + ) as priv_key_fd: |
| 37 | + private_key = priv_key_fd.read() |
| 38 | + |
| 39 | + jks_path = path.abspath( |
| 40 | + f"{certificate_job.storage_path}/{certificate_job.jks_config.file_name}" |
| 41 | + ) |
| 42 | + pkey = pyjks.jks.PrivateKeyEntry.new( |
| 43 | + certificate_name, |
| 44 | + certs=[crypto.dump_certificate(crypto.FILETYPE_ASN1, full_chain)], |
| 45 | + key=private_key, |
| 46 | + key_format="rsa_raw", |
| 47 | + ) |
| 48 | + pkey.encrypt(certificate_job.jks_config.passphrase) |
| 49 | + keystore = pyjks.KeyStore.new("jks", [pkey]) |
| 50 | + keystore.save(jks_path, certificate_job.jks_config.passphrase) |
| 51 | + |
| 52 | + |
| 53 | +def process_certbot_aws_store_certificates(job: Model) -> None: |
| 54 | + """ |
| 55 | + Pulls certificates from certbot-aws-store to local filesystem |
| 56 | + If the path does not exist, creates a new directory for download. |
| 57 | + """ |
| 58 | + if not job.certbot_store: |
| 59 | + return |
| 60 | + default_table_name = job.certbot_store.certificates_registry_table_name |
| 61 | + if job.certbot_store.certificates_registry_table_region: |
| 62 | + default_table_region = job.certbot_store.certificates_registry_table_region |
| 63 | + else: |
| 64 | + default_table_region = os.getenv("AWS_DEFAULT_REGION", Session().region_name) |
| 65 | + for _hostname, _definition in job.certbot_store.certificates.items(): |
| 66 | + certificate = AcmeCertificate( |
| 67 | + _hostname, |
| 68 | + None, |
| 69 | + table_name=_definition.certificates_registry_table_name |
| 70 | + if _definition.certificates_registry_table_name |
| 71 | + else default_table_name, |
| 72 | + region_name=_definition.certificates_registry_table_region |
| 73 | + if _definition.certificates_registry_table_region |
| 74 | + else default_table_region, |
| 75 | + ) |
| 76 | + if not path.exists(_definition.storage_path): |
| 77 | + makedirs(_definition.storage_path, exist_ok=True) |
| 78 | + try: |
| 79 | + certificate.pull(_definition.storage_path) |
| 80 | + LOG.info("Successfully pulled certificates for %s", _hostname) |
| 81 | + except Exception as error: |
| 82 | + LOG.exception(error) |
| 83 | + LOG.error( |
| 84 | + "Failed to download certificate from certbot-aws-store", _hostname |
| 85 | + ) |
| 86 | + if _definition.jks_config: |
| 87 | + create_jks_config(_hostname, _definition) |
0 commit comments