Skip to content

Commit

Permalink
openssl_csr: idempotency doesn't work correctly for keyUsage (#50361)
Browse files Browse the repository at this point in the history
* Fix key usage idempotency bug.

* Extend tests.

* Add changelog.

(cherry picked from commit a5bf71a)
  • Loading branch information
felixfontein authored and abadger committed Jan 7, 2019
1 parent 755761e commit 7ced444
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 3 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/50361-openssl_csr-idempotency.yml
@@ -0,0 +1,2 @@
bugfixes:
- "openssl_csr - fix problem with idempotency of keyUsage option."
13 changes: 12 additions & 1 deletion lib/ansible/modules/crypto/openssl_csr.py
Expand Up @@ -456,7 +456,18 @@ def _check_keyUsage_(extensions, extName, expected, critical):
return set(current) == set(expected) and usages_ext[0].get_critical() == critical

def _check_keyUsage(extensions):
return _check_keyUsage_(extensions, b'keyUsage', self.keyUsage, self.keyUsage_critical)
usages_ext = [ext for ext in extensions if ext.get_short_name() == b'keyUsage']
if (not usages_ext and self.keyUsage) or (usages_ext and not self.keyUsage):
return False
elif not usages_ext and not self.keyUsage:
return True
else:
# OpenSSL._util.lib.OBJ_txt2nid() always returns 0 for all keyUsage values
# (since keyUsage has a fixed bitfield for these values and is not extensible).
# Therefore, we create an extension for the wanted values, and compare the
# data of the extensions (which is the serialized bitfield).
expected_ext = crypto.X509Extension(b"keyUsage", False, ', '.join(self.keyUsage).encode('ascii'))
return usages_ext[0].get_data() == expected_ext.get_data() and usages_ext[0].get_critical() == self.keyUsage_critical

def _check_extenededKeyUsage(extensions):
return _check_keyUsage_(extensions, b'extendedKeyUsage', self.extendedKeyUsage, self.extendedKeyUsage_critical)
Expand Down
58 changes: 57 additions & 1 deletion test/integration/targets/openssl_csr/tasks/main.yml
Expand Up @@ -3,12 +3,39 @@
openssl_privatekey:
path: '{{ output_dir }}/privatekey.pem'

- name: Generate CSR (check mode)
openssl_csr:
path: '{{ output_dir }}/csr.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
check_mode: yes
register: generate_csr_check

- name: Generate CSR
openssl_csr:
path: '{{ output_dir }}/csr.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
register: generate_csr

- name: Generate CSR (idempotent)
openssl_csr:
path: '{{ output_dir }}/csr.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
register: generate_csr_check_idempotent

- name: Generate CSR (idempotent, check mode)
openssl_csr:
path: '{{ output_dir }}/csr.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
subject:
commonName: www.ansible.com
check_mode: yes
register: generate_csr_check_idempotent_check

# keyUsage longname and shortname should be able to be used
# interchangeably. Hence the long name is specified here
Expand Down Expand Up @@ -36,15 +63,44 @@
subject:
commonName: 'www.ansible.com'
keyUsage:
- Key Agreement
- digitalSignature
- keyAgreement
extendedKeyUsage:
- ipsecUser
- qcStatements
- DVCS
- Biometric Info
register: csr_ku_xku

- name: Generate CSR with KU and XKU (test XKU change)
openssl_csr:
path: '{{ output_dir }}/csr_ku_xku.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
subject:
commonName: 'www.ansible.com'
keyUsage:
- digitalSignature
- keyAgreement
extendedKeyUsage:
- ipsecUser
- qcStatements
- Biometric Info
register: csr_ku_xku_change

- name: Generate CSR with KU and XKU (test KU change)
openssl_csr:
path: '{{ output_dir }}/csr_ku_xku.csr'
privatekey_path: '{{ output_dir }}/privatekey.pem'
subject:
commonName: 'www.ansible.com'
keyUsage:
- digitalSignature
extendedKeyUsage:
- ipsecUser
- qcStatements
- Biometric Info
register: csr_ku_xku_change_2

- name: Generate CSR with old API
openssl_csr:
path: '{{ output_dir }}/csr_oldapi.csr'
Expand Down
12 changes: 11 additions & 1 deletion test/integration/targets/openssl_csr/tests/validate.yml
Expand Up @@ -16,10 +16,20 @@
- csr_cn.stdout.split('=')[-1] == 'www.ansible.com'
- csr_modulus.stdout == privatekey_modulus.stdout

- name: Validate CSR_KU_XKU (assert idempotency)
- name: Validate CSR (check mode, idempotency)
assert:
that:
- generate_csr_check is changed
- generate_csr is changed
- generate_csr_check_idempotent is not changed
- generate_csr_check_idempotent_check is not changed

- name: Validate CSR_KU_XKU (assert idempotency, change)
assert:
that:
- csr_ku_xku is not changed
- csr_ku_xku_change is changed
- csr_ku_xku_change_2 is changed

- name: Validate old_API CSR (test - Common Name)
shell: "openssl req -noout -subject -in {{ output_dir }}/csr_oldapi.csr -nameopt oneline,-space_eq"
Expand Down

0 comments on commit 7ced444

Please sign in to comment.