ansible-collections / community.crypto

The community.crypto collection for Ansible.
https://galaxy.ansible.com/ui/repo/published/community/crypto/
Other
100 stars 89 forks source link

Using x509_certificate_info on certificates with unicode SANs fails #312

Closed hakong closed 3 years ago

hakong commented 3 years ago
SUMMARY

Using x509_certificate_info on certificates with unicode SANs fails. UnicodeEncodeError: 'ascii' codec can't encode character u'\xe6'

Could this be a similar issue to https://github.com/ansible-collections/community.crypto/issues/270?

ISSUE TYPE
COMPONENT NAME

x509_certificate_info

ANSIBLE VERSION
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /bin/ansible
  python version = 2.7.5 (default, Aug 13 2020, 02:51:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
COLLECTION VERSION
-bash-4.2$ ansible-galaxy collection list community.crypto
usage: ansible-galaxy collection [-h] COLLECTION_ACTION ...
ansible-galaxy collection: error: argument COLLECTION_ACTION: invalid choice: u'list' (choose from 'init', 'build', 'publish', 'install')
CONFIGURATION
-bash-4.2$ ansible-config dump --only-changed
ANSIBLE_FORCE_COLOR(/usr/share/foreman-proxy/.ansible.cfg) = True
ANSIBLE_PIPELINING(/usr/share/foreman-proxy/.ansible.cfg) = True
ANSIBLE_SSH_ARGS(/usr/share/foreman-proxy/.ansible.cfg) = -o ProxyCommand=none -o ControlMaster=auto -o ControlPersist=60s -o PreferredAuthentications=publickey
DEFAULT_CALLBACK_WHITELIST(/usr/share/foreman-proxy/.ansible.cfg) = [u'foreman']
DEFAULT_LOCAL_TMP(/usr/share/foreman-proxy/.ansible.cfg) = /tmp/ansible-local-2666jYJKdN
DEFAULT_ROLES_PATH(/usr/share/foreman-proxy/.ansible.cfg) = [u'/etc/ansible/roles', u'/usr/share/ansible/roles']
DEFAULT_STDOUT_CALLBACK(/usr/share/foreman-proxy/.ansible.cfg) = yaml
DEFAULT_VAULT_PASSWORD_FILE(/usr/share/foreman-proxy/.ansible.cfg) = /usr/share/foreman-proxy/.ansible_vault_password
HOST_KEY_CHECKING(/usr/share/foreman-proxy/.ansible.cfg) = False
OS / ENVIRONMENT
[root@hostname~]# uname -r
3.10.0-1160.45.1.el7.x86_64

[root@hostname ~]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.9 (Maipo)

[root@hostname ~]# rpm -qa|grep ansible|sort
ansible-2.9.27-1.el7ae.noarch
ansible-collection-redhat-satellite-2.0.1-1.el7sat.noarch
ansiblerole-foreman_scap_client-0.1.0-1.el7sat.noarch
ansiblerole-insights-client-1.7.1-1.el7sat.noarch
ansiblerole-satellite-receptor-installer-0.6.13-1.el7sat.noarch
ansible-runner-1.4.6-1.el7ar.noarch
python2-ansible-runner-1.4.6-1.el7ar.noarch
tfm-rubygem-foreman_ansible-6.1.1-1.el7sat.noarch
tfm-rubygem-foreman_ansible_core-4.0.0-1.el7sat.noarch
tfm-rubygem-hammer_cli_foreman_ansible-0.3.2-1.el7sat.noarch
tfm-rubygem-pulp_ansible_client-0.4.2-1.el7sat.noarch
tfm-rubygem-smart_proxy_ansible-3.0.1-6.el7sat.noarch
vim-ansible-3.2-1.el7.noarch
STEPS TO REPRODUCE

I created a certificate with acme.sh that contained an encoded Internationalized domain name (IDNA encoding). Tried to read it with _openssl_certificateinfo but that failed, so I installed the latest collection and tried with community.crypto.x509_certificate_info but that fails too.

The task I first used:

---
- name: certificate | Register new certificate info and validity time
  openssl_certificate_info:
    path: "{{ certificate_new_cert_path }}/{{ certificate_new_cert_name }}"
    valid_at:
      point_1: "{{ certificate_min_validity_time }}"
  register: new_cert_result
  delegate_to: "{{ certificate_source_host }}"

The error that resulted:

An exception occurred during task execution. To see the full traceback, use -vvv. The error was: UnicodeEncodeError: 'ascii' codec can't encode character u'\xe6' in position 5: ordinal not in range(128)
  94:
fatal: [hostname1 -> hostname2]: FAILED! => {"changed": false, "module_stderr": "Traceback (most recent call last):
  File \"<stdin>\", line 102, in <module>
  File \"<stdin>\", line 94, in _ansiballz_main
  File \"<stdin>\", line 40, in invoke_module
  File \"/usr/lib64/python2.7/runpy.py\", line 176, in run_module
    fname, loader, pkg_name)
  File \"/usr/lib64/python2.7/runpy.py\", line 82, in _run_module_code
    mod_name, mod_fname, mod_loader, pkg_name)
  File \"/usr/lib64/python2.7/runpy.py\", line 72, in _run_code
    exec code in run_globals
  File \"/tmp/ansible_openssl_certificate_info_payload_nizRIa/ansible_openssl_certificate_info_payload.zip/ansible/modules/crypto/openssl_certificate_info.py\", line 871, in <module>
  File \"/tmp/ansible_openssl_certificate_info_payload_nizRIa/ansible_openssl_certificate_info_payload.zip/ansible/modules/crypto/openssl_certificate_info.py\", line 864, in main
  File \"/tmp/ansible_openssl_certificate_info_payload_nizRIa/ansible_openssl_certificate_info_payload.zip/ansible/modules/crypto/openssl_certificate_info.py\", line 486, in get_info
  File \"/tmp/ansible_openssl_certificate_info_payload_nizRIa/ansible_openssl_certificate_info_payload.zip/ansible/modules/crypto/openssl_certificate_info.py\", line 628, in _get_subject_alt_name
  File \"/tmp/ansible_openssl_certificate_info_payload_nizRIa/ansible_openssl_certificate_info_payload.zip/ansible/module_utils/crypto.py\", line 1802, in cryptography_decode_name
UnicodeEncodeError: 'ascii' codec can't encode character u'\\xe6' in position 5: ordinal not in range(128)
", "module_stdout": "", "msg": "MODULE FAILURE
See stdout/stderr for the exact error", "rc": 1}

After that I did ansible-galaxy collection install community.crypto and changed the task:

---
- name: certificate | Register new certificate info and validity time
  community.crypto.x509_certificate_info:
    path: "{{ certificate_new_cert_path }}/{{ certificate_new_cert_name }}"
    valid_at:
      point_1: "{{ certificate_min_validity_time }}"
  register: new_cert_result
  delegate_to: "{{ certificate_source_host }}"

The error that resulted:

An exception occurred during task execution. To see the full traceback, use -vvv. The error was: UnicodeEncodeError: 'ascii' codec can't encode character u'\xe6' in position 5: ordinal not in range(128)
  94:
fatal: [hostname1 -> hostname2]: FAILED! => {"changed": false, "module_stderr": "Traceback (most recent call last):
  File \"<stdin>\", line 102, in <module>
  File \"<stdin>\", line 94, in _ansiballz_main
  File \"<stdin>\", line 40, in invoke_module
  File \"/usr/lib64/python2.7/runpy.py\", line 176, in run_module
    fname, loader, pkg_name)
  File \"/usr/lib64/python2.7/runpy.py\", line 82, in _run_module_code
    mod_name, mod_fname, mod_loader, pkg_name)
  File \"/usr/lib64/python2.7/runpy.py\", line 72, in _run_code
    exec code in run_globals
  File \"/tmp/ansible_community.crypto.x509_certificate_info_payload_90nRXP/ansible_community.crypto.x509_certificate_info_payload.zip/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py\", line 452, in <module>
  File \"/tmp/ansible_community.crypto.x509_certificate_info_payload_90nRXP/ansible_community.crypto.x509_certificate_info_payload.zip/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py\", line 436, in main
  File \"/tmp/ansible_community.crypto.x509_certificate_info_payload_90nRXP/ansible_community.crypto.x509_certificate_info_payload.zip/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_info.py\", line 188, in get_info
  File \"/tmp/ansible_community.crypto.x509_certificate_info_payload_90nRXP/ansible_community.crypto.x509_certificate_info_payload.zip/ansible_collections/community/crypto/plugins/module_utils/crypto/module_backends/certificate_info.py\", line 340, in _get_subject_alt_name
  File \"/tmp/ansible_community.crypto.x509_certificate_info_payload_90nRXP/ansible_community.crypto.x509_certificate_info_payload.zip/ansible_collections/community/crypto/plugins/module_utils/crypto/cryptography_support.py\", line 328, in cryptography_decode_name
UnicodeEncodeError: 'ascii' codec can't encode character u'\\xe6' in position 5: ordinal not in range(128)
", "module_stdout": "", "msg": "MODULE FAILURE
See stdout/stderr for the exact error", "rc": 1}
---
- name: certificate | Register new certificate info and validity time
  community.crypto.x509_certificate_info:
    path: "{{ certificate_new_cert_path }}/{{ certificate_new_cert_name }}"
    valid_at:
      point_1: "{{ certificate_min_validity_time }}"
  register: new_cert_result
  delegate_to: "{{ certificate_source_host }}"
EXPECTED RESULTS

Expected it to parse successfully.

ACTUAL RESULTS

Give a unicode error: UnicodeEncodeError: 'ascii' codec can't encode character u'\xe6'

Ajpantuso commented 3 years ago

Different than the other issue you mentioned, but for a similar reason.

For Python 2.7.5 return 'DNS:{0}'.format(name.value) should be return u'DNS:{0}'.format(name.value) to handle Unicode correctly.

I think @felixfontein is the better person to provide a solution however.

felixfontein commented 3 years ago

Yes, adding the u prefix should do the trick. Testing this is somewhat tricky, since it only works with cryptography < 2.1 - newer versions don't automatically encode/decode IDNs. I've created a PR (#313), let's see what CI says.

hakong commented 3 years ago

Is there a workaround I can use while waiting for the fix to be released?

felixfontein commented 3 years ago

What you could do is:

hakong commented 3 years ago

Ok, thank you for that. The platform is pretty tied down in regards to using newer versions of python packages (Red Hat Satellite 6.9 on Red Hat Enterprise Linux 7.9). I will create a case with Red Hat and see what they say, but based on my experience that's going to take months to solve, if at all.

hakong commented 3 years ago

For the time being as a workaround I've just dumped the new revision in place. This seems to work.

wget https://raw.githubusercontent.com/ansible-collections/community.crypto/eb8dabce84302621351b409e7e52594e03937a17/plugins/module_utils/crypto/cryptography_support.py -O /usr/share/foreman-proxy/.ansible/collections/ansible_collections/community/crypto/plugins/module_utils/crypto/cryptography_support.py

felixfontein commented 3 years ago

community.crypto 1.9.6 is now out with a fix for this.