summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Fontein <felix@fontein.de>2019-03-04 16:34:14 +0100
committerToshio Kuratomi <a.badger@gmail.com>2019-03-04 07:34:14 -0800
commit597db1dc287f39329ff0e9689080e471a91726ec (patch)
treed388cdab30d602e7d465b545c22f63607b4c080f
parent59beb460d82103ace61f9a3b64f1ec964739e4fb (diff)
downloadansible-597db1dc287f39329ff0e9689080e471a91726ec.tar.gz
[2.7] openssl_certificate, fixed has_expired to check the cert expiration date (#53203)
* Type error in openssl_certificate (#47508) * Fixed #47505: Type error in openssl_certificate * Use to_bytes instead of str.encode in SelfSignedCertificate. Updates #47508 * Use to_bytes instead of str.encode in OwnCACertificate * Added integration tests for openssl_certificate: selfsigned_not_before/after and ownca_not_before/after (cherry picked from commit 5b1c68579d3e8ecc28a6b85383a85c1f279da63c) * openssl_certificate, fixed has_expired to check the cert expiration date (#53168) (cherry picked from commit d5d92e4a70d87eda4cbdd160f6bb6459ee05cea7) * Use fixed timestamp in past instead of relative time (relative times are a feature of devel). * Add changelog for #47508.
-rw-r--r--changelogs/fragments/47508-openssl_certificate-fix-not-before-after.yml2
-rw-r--r--changelogs/fragments/openssl_certificate_fix_has_expired.yml2
-rw-r--r--lib/ansible/modules/crypto/openssl_certificate.py32
-rw-r--r--test/integration/targets/openssl_certificate/tasks/expired.yml39
-rw-r--r--test/integration/targets/openssl_certificate/tasks/main.yml2
-rw-r--r--test/integration/targets/openssl_certificate/tasks/ownca.yml11
-rw-r--r--test/integration/targets/openssl_certificate/tasks/selfsigned.yml20
-rw-r--r--test/integration/targets/openssl_certificate/tests/validate_ownca.yml18
-rw-r--r--test/integration/targets/openssl_certificate/tests/validate_selfsigned.yml18
9 files changed, 132 insertions, 12 deletions
diff --git a/changelogs/fragments/47508-openssl_certificate-fix-not-before-after.yml b/changelogs/fragments/47508-openssl_certificate-fix-not-before-after.yml
new file mode 100644
index 0000000000..524c58b74b
--- /dev/null
+++ b/changelogs/fragments/47508-openssl_certificate-fix-not-before-after.yml
@@ -0,0 +1,2 @@
+bugfixes:
+- "openssl_certificate - fix Python 3 string/bytes problems for `notBefore`/`notAfter` for self-signed and ownCA providers."
diff --git a/changelogs/fragments/openssl_certificate_fix_has_expired.yml b/changelogs/fragments/openssl_certificate_fix_has_expired.yml
new file mode 100644
index 0000000000..b33b2da9d4
--- /dev/null
+++ b/changelogs/fragments/openssl_certificate_fix_has_expired.yml
@@ -0,0 +1,2 @@
+bugfixes:
+ - openssl_certificate - ``has_expired`` correctly checks if the certificate is expired or not
diff --git a/lib/ansible/modules/crypto/openssl_certificate.py b/lib/ansible/modules/crypto/openssl_certificate.py
index 32db6e4017..3db7405ea7 100644
--- a/lib/ansible/modules/crypto/openssl_certificate.py
+++ b/lib/ansible/modules/crypto/openssl_certificate.py
@@ -179,10 +179,11 @@ options:
version_added: "2.5"
has_expired:
- default: False
- type: bool
description:
- - Checks if the certificate is expired/not expired at the time the module is executed.
+ - Checks if the certificate is expired/not expired at the time the module is executed. This only applies to
+ the C(assertonly) provider.
+ type: bool
+ default: no
version:
description:
@@ -521,11 +522,11 @@ class SelfSignedCertificate(Certificate):
cert = crypto.X509()
cert.set_serial_number(self.serial_number)
if self.notBefore:
- cert.set_notBefore(self.notBefore)
+ cert.set_notBefore(to_bytes(self.notBefore))
else:
cert.gmtime_adj_notBefore(0)
if self.notAfter:
- cert.set_notAfter(self.notAfter)
+ cert.set_notAfter(to_bytes(self.notAfter))
else:
# If no NotAfter specified, expire in
# 10 years. 315360000 is 10 years in seconds.
@@ -618,11 +619,11 @@ class OwnCACertificate(Certificate):
cert = crypto.X509()
cert.set_serial_number(self.serial_number)
if self.notBefore:
- cert.set_notBefore(self.notBefore.encode())
+ cert.set_notBefore(to_bytes(self.notBefore))
else:
cert.gmtime_adj_notBefore(0)
if self.notAfter:
- cert.set_notAfter(self.notAfter.encode())
+ cert.set_notAfter(to_bytes(self.notAfter))
else:
# If no NotAfter specified, expire in
# 10 years. 315360000 is 10 years in seconds.
@@ -763,11 +764,18 @@ class AssertOnlyCertificate(Certificate):
)
def _validate_has_expired():
- if self.has_expired:
- if self.has_expired != self.cert.has_expired():
- self.message.append(
- 'Certificate expiration check failed (certificate expiration is %s, expected %s)' % (self.cert.has_expired(), self.has_expired)
- )
+ # The following 3 lines are the same as the current PyOpenSSL code for cert.has_expired().
+ # Older version of PyOpenSSL have a buggy implementation,
+ # to avoid issues with those we added the code from a more recent release here.
+
+ time_string = to_native(self.cert.get_notAfter())
+ not_after = datetime.datetime.strptime(time_string, "%Y%m%d%H%M%SZ")
+ cert_expired = not_after < datetime.datetime.utcnow()
+
+ if self.has_expired != cert_expired:
+ self.message.append(
+ 'Certificate expiration check failed (certificate expiration is %s, expected %s)' % (cert_expired, self.has_expired)
+ )
def _validate_version():
if self.version:
diff --git a/test/integration/targets/openssl_certificate/tasks/expired.yml b/test/integration/targets/openssl_certificate/tasks/expired.yml
new file mode 100644
index 0000000000..34ae359ee8
--- /dev/null
+++ b/test/integration/targets/openssl_certificate/tasks/expired.yml
@@ -0,0 +1,39 @@
+---
+- name: Generate privatekey
+ openssl_privatekey:
+ path: '{{ output_dir }}/has_expired_privatekey.pem'
+
+- name: Generate CSR
+ openssl_csr:
+ path: '{{ output_dir }}/has_expired_csr.csr'
+ privatekey_path: '{{ output_dir }}/has_expired_privatekey.pem'
+ subject:
+ commonName: www.example.com
+
+- name: Generate expired selfsigned certificate
+ openssl_certificate:
+ path: '{{ output_dir }}/has_expired_cert.pem'
+ csr_path: '{{ output_dir }}/has_expired_csr.csr'
+ privatekey_path: '{{ output_dir }}/has_expired_privatekey.pem'
+ provider: selfsigned
+ selfsigned_digest: sha256
+ selfsigned_not_after: "20181231000000Z"
+
+- name: "Check task fails because cert is expired (has_expired: false)"
+ openssl_certificate:
+ provider: assertonly
+ path: "{{ output_dir }}/has_expired_cert.pem"
+ has_expired: false
+ ignore_errors: true
+ register: expired_cert_check
+
+- name: Ensure previous task failed
+ assert:
+ that: expired_cert_check is failed
+
+- name: "Check expired cert check is ignored (has_expired: true)"
+ openssl_certificate:
+ provider: assertonly
+ path: "{{ output_dir }}/has_expired_cert.pem"
+ has_expired: true
+ register: expired_cert_skip
diff --git a/test/integration/targets/openssl_certificate/tasks/main.yml b/test/integration/targets/openssl_certificate/tasks/main.yml
index a452f23495..1fdc1a674d 100644
--- a/test/integration/targets/openssl_certificate/tasks/main.yml
+++ b/test/integration/targets/openssl_certificate/tasks/main.yml
@@ -1,5 +1,7 @@
- block:
+ - import_tasks: expired.yml
+
- import_tasks: selfsigned.yml
- import_tasks: ownca.yml
diff --git a/test/integration/targets/openssl_certificate/tasks/ownca.yml b/test/integration/targets/openssl_certificate/tasks/ownca.yml
index 9f7dbbff5c..63edbd2610 100644
--- a/test/integration/targets/openssl_certificate/tasks/ownca.yml
+++ b/test/integration/targets/openssl_certificate/tasks/ownca.yml
@@ -116,4 +116,15 @@
issuer:
commonName: Example CA
+- name: Create ownca certificate with notBefore and notAfter
+ openssl_certificate:
+ provider: ownca
+ ownca_not_before: 20181023133742Z
+ ownca_not_after: 20191023133742Z
+ path: "{{ output_dir }}/ownca_cert3.pem"
+ csr_path: "{{ output_dir }}/csr.csr"
+ privatekey_path: "{{ output_dir }}/privatekey3.pem"
+ ownca_path: '{{ output_dir }}/ca_cert.pem'
+ ownca_privatekey_path: '{{ output_dir }}/ca_privatekey.pem'
+
- import_tasks: ../tests/validate_ownca.yml
diff --git a/test/integration/targets/openssl_certificate/tasks/selfsigned.yml b/test/integration/targets/openssl_certificate/tasks/selfsigned.yml
index 82b290dbe0..b57a11f196 100644
--- a/test/integration/targets/openssl_certificate/tasks/selfsigned.yml
+++ b/test/integration/targets/openssl_certificate/tasks/selfsigned.yml
@@ -114,4 +114,24 @@
- ipsecUser
- biometricInfo
+- name: Create private key 3
+ openssl_privatekey:
+ path: "{{ output_dir }}/privatekey3.pem"
+
+- name: Create CSR 3
+ openssl_csr:
+ subject:
+ CN: www.example.com
+ privatekey_path: "{{ output_dir }}/privatekey3.pem"
+ path: "{{ output_dir }}/csr3.pem"
+
+- name: Create certificate3 with notBefore and notAfter
+ openssl_certificate:
+ provider: selfsigned
+ selfsigned_not_before: 20181023133742Z
+ selfsigned_not_after: 20191023133742Z
+ path: "{{ output_dir }}/cert3.pem"
+ csr_path: "{{ output_dir }}/csr3.pem"
+ privatekey_path: "{{ output_dir }}/privatekey3.pem"
+
- import_tasks: ../tests/validate_selfsigned.yml
diff --git a/test/integration/targets/openssl_certificate/tests/validate_ownca.yml b/test/integration/targets/openssl_certificate/tests/validate_ownca.yml
index 779452fb18..d54287ecd9 100644
--- a/test/integration/targets/openssl_certificate/tests/validate_ownca.yml
+++ b/test/integration/targets/openssl_certificate/tests/validate_ownca.yml
@@ -47,3 +47,21 @@
assert:
that:
- ownca_cert2_modulus.stdout == privatekey2_modulus.stdout
+
+- name: Validate owncal certificate3 (test - notBefore)
+ shell: 'openssl x509 -noout -in {{ output_dir }}/ownca_cert3.pem -text | grep "Not Before" | sed "s/.*: \(.*\) .*/\1/g"'
+ register: ownca_cert3_notBefore
+
+- name: Validate ownca certificate3 (test - notAfter)
+ shell: 'openssl x509 -noout -in {{ output_dir }}/ownca_cert3.pem -text | grep "Not After" | sed "s/.*: \(.*\) .*/\1/g"'
+ register: ownca_cert3_notAfter
+
+- name: Validate ownca certificate3 (assert - notBefore)
+ assert:
+ that:
+ - ownca_cert3_notBefore.stdout == 'Oct 23 13:37:42 2018'
+
+- name: Validate ownca certificate3 (assert - notAfter)
+ assert:
+ that:
+ - ownca_cert3_notAfter.stdout == 'Oct 23 13:37:42 2019'
diff --git a/test/integration/targets/openssl_certificate/tests/validate_selfsigned.yml b/test/integration/targets/openssl_certificate/tests/validate_selfsigned.yml
index de37106945..f98d6f191e 100644
--- a/test/integration/targets/openssl_certificate/tests/validate_selfsigned.yml
+++ b/test/integration/targets/openssl_certificate/tests/validate_selfsigned.yml
@@ -50,3 +50,21 @@
assert:
that:
- cert2_modulus.stdout == privatekey2_modulus.stdout
+
+- name: Validate certificate3 (test - notBefore)
+ shell: 'openssl x509 -noout -in {{ output_dir }}/cert3.pem -text | grep "Not Before" | sed "s/.*: \(.*\) .*/\1/g"'
+ register: cert3_notBefore
+
+- name: Validate certificate3 (test - notAfter)
+ shell: 'openssl x509 -noout -in {{ output_dir }}/cert3.pem -text | grep "Not After" | sed "s/.*: \(.*\) .*/\1/g"'
+ register: cert3_notAfter
+
+- name: Validate certificate3 (assert - notBefore)
+ assert:
+ that:
+ - cert3_notBefore.stdout == 'Oct 23 13:37:42 2018'
+
+- name: Validate certificate3 (assert - notAfter)
+ assert:
+ that:
+ - cert3_notAfter.stdout == 'Oct 23 13:37:42 2019'