From 3ebc132c03cda63270c377974f4e013eb7a563d4 Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Mon, 14 Feb 2022 18:04:29 +0100 Subject: [PATCH] Regenerate certificate on CA's subject change. (#402) --- .../402-x509_certificate-ownca-subject.yml | 2 + .../module_backends/certificate_ownca.py | 7 ++- .../targets/x509_certificate/tasks/ownca.yml | 57 ++++++++++++++++++- .../x509_certificate/tests/validate_ownca.yml | 6 ++ 4 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 changelogs/fragments/402-x509_certificate-ownca-subject.yml diff --git a/changelogs/fragments/402-x509_certificate-ownca-subject.yml b/changelogs/fragments/402-x509_certificate-ownca-subject.yml new file mode 100644 index 00000000..8a07e261 --- /dev/null +++ b/changelogs/fragments/402-x509_certificate-ownca-subject.yml @@ -0,0 +1,2 @@ +bugfixes: + - "x509_certificate - regenerate certificate when the CA's subject changes for ``provider=ownca`` (https://github.com/ansible-collections/community.crypto/issues/400, https://github.com/ansible-collections/community.crypto/pull/402)." diff --git a/plugins/module_utils/crypto/module_backends/certificate_ownca.py b/plugins/module_utils/crypto/module_backends/certificate_ownca.py index 46c0aeff..e28d7dc3 100644 --- a/plugins/module_utils/crypto/module_backends/certificate_ownca.py +++ b/plugins/module_utils/crypto/module_backends/certificate_ownca.py @@ -173,6 +173,12 @@ class OwnCACertificateBackendCryptography(CertificateBackend): if super(OwnCACertificateBackendCryptography, self).needs_regeneration(not_before=self.notBefore, not_after=self.notAfter): return True + self._ensure_existing_certificate_loaded() + + # Check subject + if self.ca_cert.subject != self.existing_certificate.issuer: + return True + # Check AuthorityKeyIdentifier if self.create_authority_key_identifier: try: @@ -185,7 +191,6 @@ class OwnCACertificateBackendCryptography(CertificateBackend): except cryptography.x509.ExtensionNotFound: expected_ext = x509.AuthorityKeyIdentifier.from_issuer_public_key(self.ca_cert.public_key()) - self._ensure_existing_certificate_loaded() try: ext = self.existing_certificate.extensions.get_extension_for_class(x509.AuthorityKeyIdentifier) if ext.value != expected_ext: diff --git a/tests/integration/targets/x509_certificate/tasks/ownca.yml b/tests/integration/targets/x509_certificate/tasks/ownca.yml index dd402b10..4ba05435 100644 --- a/tests/integration/targets/x509_certificate/tasks/ownca.yml +++ b/tests/integration/targets/x509_certificate/tasks/ownca.yml @@ -14,14 +14,20 @@ - name: (OwnCA, {{select_crypto_backend}}) Generate CA CSR openssl_csr: - path: '{{ remote_tmp_dir }}/ca_csr.csr' + path: '{{ item.path }}' privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem' - subject: - commonName: Example CA + subject: '{{ item.subject }}' useCommonNameForSAN: no basic_constraints: - 'CA:TRUE' basic_constraints_critical: yes + loop: + - path: '{{ remote_tmp_dir }}/ca_csr.csr' + subject: + commonName: Example CA + - path: '{{ remote_tmp_dir }}/ca_csr2.csr' + subject: + commonName: Example CA 2 - name: (OwnCA, {{select_crypto_backend}}) Generate CA CSR (privatekey passphrase) openssl_csr: @@ -62,6 +68,15 @@ - result_check_mode is changed - result is changed +- name: (OwnCA, {{select_crypto_backend}}) Generate selfsigned CA certificate with different commonName + x509_certificate: + path: '{{ remote_tmp_dir }}/ca_cert2.pem' + csr_path: '{{ remote_tmp_dir }}/ca_csr2.csr' + privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem' + provider: selfsigned + selfsigned_digest: sha256 + select_crypto_backend: '{{ select_crypto_backend }}' + - name: (OwnCA, {{select_crypto_backend}}) Generate selfsigned CA certificate (privatekey passphrase) x509_certificate: path: '{{ remote_tmp_dir }}/ca_cert_pw.pem' @@ -110,6 +125,42 @@ select_crypto_backend: '{{ select_crypto_backend }}' check_mode: yes +- name: (OwnCA, {{select_crypto_backend}}) Copy ownca certificate to new file to check regeneration + copy: + src: '{{ remote_tmp_dir }}/ownca_cert.pem' + dest: '{{ item }}' + remote_src: true + loop: + - '{{ remote_tmp_dir }}/ownca_cert_ca_cn.pem' + - '{{ remote_tmp_dir }}/ownca_cert_ca_key.pem' + +- name: (OwnCA, {{select_crypto_backend}}) Regenerate ownca certificate with different CA subject + x509_certificate: + path: '{{ remote_tmp_dir }}/ownca_cert_ca_cn.pem' + csr_path: '{{ remote_tmp_dir }}/csr.csr' + privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem' + ownca_path: '{{ remote_tmp_dir }}/ca_cert2.pem' + ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey.pem' + provider: ownca + ownca_digest: sha256 + select_crypto_backend: '{{ select_crypto_backend }}' + return_content: yes + register: ownca_certificate_ca_subject_changed + +- name: (OwnCA, {{select_crypto_backend}}) Regenerate ownca certificate with different CA key + x509_certificate: + path: '{{ remote_tmp_dir }}/ownca_cert_ca_key.pem' + csr_path: '{{ remote_tmp_dir }}/csr.csr' + privatekey_path: '{{ remote_tmp_dir }}/privatekey.pem' + ownca_path: '{{ remote_tmp_dir }}/ca_cert_pw.pem' + ownca_privatekey_path: '{{ remote_tmp_dir }}/ca_privatekey_pw.pem' + ownca_privatekey_passphrase: hunter2 + provider: ownca + ownca_digest: sha256 + select_crypto_backend: '{{ select_crypto_backend }}' + return_content: yes + register: ownca_certificate_ca_key_changed + - name: (OwnCA, {{select_crypto_backend}}) Get certificate information community.crypto.x509_certificate_info: path: '{{ remote_tmp_dir }}/ownca_cert.pem' diff --git a/tests/integration/targets/x509_certificate/tests/validate_ownca.yml b/tests/integration/targets/x509_certificate/tests/validate_ownca.yml index cac0c242..29bfec1c 100644 --- a/tests/integration/targets/x509_certificate/tests/validate_ownca.yml +++ b/tests/integration/targets/x509_certificate/tests/validate_ownca.yml @@ -31,6 +31,12 @@ - ownca_certificate.notBefore == ownca_certificate_idempotence.notBefore - ownca_certificate.notAfter == ownca_certificate_idempotence.notAfter +- name: (OwnCA validation, {{select_crypto_backend}}) Validate ownca certificate regeneration + assert: + that: + - ownca_certificate_ca_subject_changed is changed + - ownca_certificate_ca_key_changed is changed + - name: (OwnCA validation, {{select_crypto_backend}}) Read certificate slurp: src: '{{ remote_tmp_dir }}/ownca_cert.pem'