The OpenJDK issue of keytool does not appear to return RCs > 0 for at least some errors, which is the only check performed in java_cert. Some errors may be caught if the keystore is newly created (for PKCS12 only), but modifications and failures to modify are not necessarily identified correctly.
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 20.04.6 LTS
Release: 20.04
Codename: focal
keytool is provided by openjdk-11-jre-headless in version 11.0.19+7~us1-0ubuntu1~20.04.1
Steps to Reproduce
- name: Test faulty create with pkcs12
hosts: localhost
gather_facts: false
vars:
test_pkcs12_path: testpkcs.p12
test_keystore_path: keystore.dat
tasks:
- name: Setup tempdir
ansible.builtin.tempfile:
state: directory
register: tmpdir
- name: Use cert from test suite
ansible.builtin.get_url:
dest: "{{ tmpdir.path }}/{{ test_pkcs12_path }}"
url: "https://github.com/ansible-collections/community.general/blob/main/tests/integration/targets/java_cert/files/testpkcs.p12?raw=true"
- name: This incidentally fails properly due to no file being created
community.general.java_cert:
pkcs12_path: "{{ remote_tmp_dir }}/{{ test_pkcs12_path }}"
pkcs12_password: changeit
pkcs12_alias: default
cert_alias: default
keystore_path: "{{ remote_tmp_dir }}/{{ test_keystore_path }}"
keystore_pass: ""
keystore_create: true
state: present
vars:
remote_tmp_dir: "{{ tmpdir.path }}"
ignore_errors: true
register: pkcs12store
- ansible.builtin.assert:
that:
- pkcs12store.failed
fail_msg: "Keystore setup should have failed"
- name: Test faulty create with pem
hosts: localhost
gather_facts: false
vars:
test_keystore_path: keystore.dat
tasks:
- name: Setup tempdir
ansible.builtin.tempfile:
state: directory
register: tmpdir
- name: Create private key
community.crypto.openssl_privatekey:
path: "{{ tmpdir.path }}/test.key"
- name: Create simple self-signed certificate
community.crypto.x509_certificate:
path: "{{ tmpdir.path }}/test.pem"
privatekey_path: "{{ tmpdir.path }}/test.key"
provider: selfsigned
- name: This does not fail properly
community.general.java_cert:
cert_path: "{{ tmpdir.path }}/test.pem"
cert_alias: default
keystore_path: "{{ remote_tmp_dir }}/{{ test_keystore_path }}"
keystore_pass: ""
keystore_create: true
state: present
vars:
remote_tmp_dir: "{{ tmpdir.path }}"
ignore_errors: true
register: certstore
- ansible.builtin.assert:
that:
- certstore.failed
fail_msg: "Keystore setup should have failed"
Expected Results
Neither assertion should be triggered because the underlying command does not complete in either case and the keystore is not created. I would have expected either call to java_cert to result in a fail.
Actual Results
$ ansible-playbook test.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match
'all'
PLAY [Test faulty create with pkcs12] *********************************************************************************
TASK [Setup tempdir] **************************************************************************************************
changed: [localhost]
TASK [Use cert from test suite] ***************************************************************************************
changed: [localhost]
TASK [This incidentally fails properly due to no file being created] **************************************************
fatal: [localhost]: FAILED! => {"changed": false, "cmd": ["keytool", "-importkeystore", "-noprompt", "-srcstoretype", "pkcs12", "-srckeystore", "/tmp/ansible.vu3wpgm2/testpkcs.p12", "-srcalias", "default", "-destkeystore", "/tmp/ansible.vu3wpgm2/keystore.dat", "-destalias", "default"], "error": "Keystore /tmp/ansible.vu3wpgm2/testpkcs.p12 wird in /tmp/ansible.vu3wpgm2/keystore.dat importiert...\nZiel-Keystore-Kennwort eingeben: Keystore-Kennwort ist zu kurz. Es muss mindestens sechs Zeichen lang sein\nZiel-Keystore-Kennwort eingeben: Keystore-Kennwort ist zu kurz. Es muss mindestens sechs Zeichen lang sein\nZiel-Keystore-Kennwort eingeben: Neues Kennwort erneut eingeben: Keine Übereinstimmung. Wiederholen Sie den Vorgang\nZu viele Fehler. Versuchen Sie es später erneut\n", "msg": "", "rc": 0}
...ignoring
TASK [ansible.builtin.assert] *****************************************************************************************
ok: [localhost] => {
"changed": false,
"msg": "All assertions passed"
}
PLAY [Test faulty create with pem] ************************************************************************************
TASK [Setup tempdir] **************************************************************************************************
changed: [localhost]
TASK [Create private key] *********************************************************************************************
changed: [localhost]
TASK [Create simple self-signed certificate] **************************************************************************
changed: [localhost]
TASK [This does not fail properly] ************************************************************************************
changed: [localhost]
TASK [ansible.builtin.assert] *****************************************************************************************
fatal: [localhost]: FAILED! => {
"assertion": "certstore.failed",
"changed": false,
"evaluated_to": false,
"msg": "Keystore setup should have failed"
}
PLAY RECAP ************************************************************************************************************
localhost : ok=8 changed=6 unreachable=0 failed=1 skipped=0 rescued=0 ignored=1
Output of the relevant tasks with -v:
TASK [This incidentally fails properly due to no file being created] **************************************************
fatal: [localhost]: FAILED! => {"changed": false, "cmd": ["keytool", "-importkeystore", "-noprompt", "-srcstoretype", "pkcs12", "-srckeystore", "/tmp/ansible.m3s37ttz/testpkcs.p12", "-srcalias", "default", "-destkeystore", "/tmp/ansible.m3s37ttz/keystore.dat", "-destalias", "default"], "error": "Keystore /tmp/ansible.m3s37ttz/testpkcs.p12 wird in /tmp/ansible.m3s37ttz/keystore.dat importiert...\nZiel-Keystore-Kennwort eingeben: Keystore-Kennwort ist zu kurz. Es muss mindestens sechs Zeichen lang sein\nZiel-Keystore-Kennwort eingeben: Keystore-Kennwort ist zu kurz. Es muss mindestens sechs Zeichen lang sein\nZiel-Keystore-Kennwort eingeben: Neues Kennwort erneut eingeben: Keine Übereinstimmung. Wiederholen Sie den Vorgang\nZu viele Fehler. Versuchen Sie es später erneut\n", "msg": "", "rc": 0}
[...]
TASK [This does not fail properly] ************************************************************************************
changed: [localhost] => {"changed": true, "cmd": ["keytool", "-importcert", "-noprompt", "-keystore", "/tmp/ansible.3bs7p9h9/keystore.dat", "-file", "/tmp/ansible.3bs7p9h9/test.pem", "-alias", "default"], "error": "Keystore-Kennwort eingeben: Keystore-Kennwort ist zu kurz. Es muss mindestens sechs Zeichen lang sein\nKeystore-Kennwort eingeben: Keystore-Kennwort ist zu kurz. Es muss mindestens sechs Zeichen lang sein\nKeystore-Kennwort eingeben: Keystore-Kennwort ist zu kurz. Es muss mindestens sechs Zeichen lang sein\nZu viele Fehler. Versuchen Sie es später erneut\n", "msg": "", "rc": 0, "stdout": "", "stdout_lines": []}
The equivalent output of keytool in an english locale is
Enter keystore password: Keystore password is too short - must be at least 6 characters
Enter keystore password: Keystore password is too short - must be at least 6 characters
Enter keystore password: Keystore password is too short - must be at least 6 characters
Too many failures - try later
Summary
The OpenJDK issue of
keytool
does not appear to return RCs > 0 for at least some errors, which is the only check performed injava_cert
. Some errors may be caught if the keystore is newly created (for PKCS12 only), but modifications and failures to modify are not necessarily identified correctly.Relevant code segments:
Issue Type
Bug Report
Component Name
java_cert
Ansible Version
Community.general Version
Configuration
OS / Environment
keytool
is provided byopenjdk-11-jre-headless
in version11.0.19+7~us1-0ubuntu1~20.04.1
Steps to Reproduce
Expected Results
Neither assertion should be triggered because the underlying command does not complete in either case and the keystore is not created. I would have expected either call to
java_cert
to result in a fail.Actual Results
Output of the relevant tasks with
-v
:The equivalent output of
keytool
in an english locale isCode of Conduct