ansible-collections / community.crypto

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

x509_certificate_info error in ansible 2.9.11 <ObjectIdentifier(oid=2.5.29.32, name=certificatePolicies)> extension is invalid and can't be parsed #93

Open yodatak opened 4 years ago

yodatak commented 4 years ago

SUMMARY

When verify all the file in /etc/ssl/certs i got this error

  File "/tmp/ansible_community.crypto.x509_certificate_info_payload_gna4u96f/ansible_community.crypto.x509_certificate_info_payload.zip/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py", line 881, in <module>

  File "/tmp/ansible_community.crypto.x509_certificate_info_payload_gna4u96f/ansible_community.crypto.x509_certificate_info_payload.zip/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py", line 874, in main

  File "/tmp/ansible_community.crypto.x509_certificate_info_payload_gna4u96f/ansible_community.crypto.x509_certificate_info_payload.zip/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py", line 488, in get_info

  File "/tmp/ansible_community.crypto.x509_certificate_info_payload_gna4u96f/ansible_community.crypto.x509_certificate_info_payload.zip/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py", line 560, in _get_key_usage

  File "/usr/local/lib64/python3.6/site-packages/cryptography/utils.py", line 170, in inner

    result = func(instance)

  File "/usr/local/lib64/python3.6/site-packages/cryptography/hazmat/backends/openssl/x509.py", line 127, in extensions

    self._backend, self._x509

  File "/usr/local/lib64/python3.6/site-packages/cryptography/hazmat/backends/openssl/decode_asn1.py", line 249, in parse

    "parsed".format(oid)

ValueError: The <ObjectIdentifier(oid=2.5.29.32, name=certificatePolicies)> extension is invalid and can't be parsed
ISSUE TYPE
COMPONENT NAME

x509_certificate_info

ANSIBLE VERSION
/-\|+ ansible --version
ansible 2.9.11
  config file = /X/ansible-sik/ansible.cfg
  configured module search path = [u'/home/X/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /X/lib/python2.7/site-packages/ansible
  executable location = /X/bin/ansible
  python version = 2.7.5 (default, Dec  3 2013, 08:35:16) [GCC 4.4.6 20120305 (Red Hat 4.4.6-4)]
CONFIGURATION

+ ansible-config dump --only-changed
ANSIBLE_FORCE_COLOR(env: ANSIBLE_FORCE_COLOR) = True
ANSIBLE_SSH_ARGS(/X/ansible.cfg) = -o ControlMaster=no -o UserKnownHostsFile=/dev/null
ANSIBLE_SSH_CONTROL_PATH(/X/ansible.cfg) = %(directory)s/%%h-%%r
CACHE_PLUGIN(/X/ansible.cfg) = jsonfile
CACHE_PLUGIN_CONNECTION(/X/ansible.cfg) = ./tmp/.ansible_fact_cache
CACHE_PLUGIN_TIMEOUT(/X/ansible.cfg) = 7200
DEFAULT_CALLBACK_WHITELIST(/X/ansible.cfg) = [u'profile_tasks']
DEFAULT_FILTER_PLUGIN_PATH(/X/ansible.cfg) = [u'/X/library/filters']
DEFAULT_FORKS(/X/ansible.cfg) = 25
DEFAULT_GATHERING(/X/ansible.cfg) = smart
DEFAULT_GATHER_TIMEOUT(/X/ansible.cfg) = 30
DEFAULT_LOCAL_TMP(env: ANSIBLE_LOCAL_TEMP) = /X/tmp/ansible/ansible-local-24783uQEOb_
DEFAULT_LOOKUP_PLUGIN_PATH(/X/ansible.cfg) = [u'/X/library/lookup']
DEFAULT_POLL_INTERVAL(/X/ansible.cfg) = 5
DEFAULT_ROLES_PATH(/X/ansible.cfg) = [u'/X/roles', u'/X/galaxy_roles']
DEFAULT_STDOUT_CALLBACK(/X/ansible.cfg) = debug
DEFAULT_STRATEGY(/X/ansible.cfg) = linear
DEFAULT_STRATEGY_PLUGIN_PATH(/X/ansible.cfg) = [u'/X/library/mitogen-0.2.9/ansible_mitogen/plugins/strategy']
DEFAULT_TIMEOUT(/X/ansible.cfg) = 15
HOST_KEY_CHECKING(env: ANSIBLE_HOST_KEY_CHECKING) = False
OS / ENVIRONMENT

Red Hat 7.3 python2

STEPS TO REPRODUCE
- name: Find cert files under /etc/ssl/certs
  find:
    paths: /etc/ssl/certs
    file_type: file
    patterns: "*.crt,*.pem,*.cer"
    recurse: yes
    exclude: "*crl*"
  register: find_result

- name: Check validity
  community.crypto.x509_certificate_info:
    path: "{{ item.path }}"
    valid_at:
      point_1: "+1w"
      point_2: "+10w"
  register: cert_info
  loop: "{{ find_result.files }}"

- name: Filter out valid certs
  set_fact:
    outdated_certs: "{{ cert_info | json_query('results[? !(valid_at.point_1) || !(valid_at.point_2)]') }}"

- block:
    - name: Check that all certificates are valid
      assert:
        that:
          - outdated_certs | count == 0

  rescue:
    - name: Show info about outdated certs
      debug:
        msg: >-
          {{ { "Outdated Certs": outdated_certs | json_query("[].item.path") } }}

    - fail:
        msg: "Outdated certs found. See list above"
EXPECTED RESULTS

Verify certificate

ACTUAL RESULTS

it append on 2 files /etc/ssl/certs/multisite_XXX.cer and ca_multisite_chain_complete.pem

An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ValueError: The <ObjectIdentifier(oid=2.5.29.32, name=certificatePolicies)> extension is invalid and can't be parsed
failed: [XXXXXX] (item={u'rusr': True, u'uid': 0, u'rgrp': True, u'xoth': False, u'islnk': False, u'woth': False, u'nlink': 1, u'issock': False, u'mtime': 1558689976.840408, u'gr_name': u'root', u'path': u'/etc/ssl/certs/ca_multisite_chaine_complete.pem', u'xusr': False, u'atime': 1595420107.449019, u'inode': 7210673, u'isgid': False, u'size': 13966, u'isdir': False, u'ctime': 1558690057.8965392, u'roth': True, u'wgrp': False, u'xgrp': False, u'isuid': False, u'dev': 64768, u'isblk': False, u'isreg': True, u'isfifo': False, u'mode': u'0644', u'pw_name': u'root', u'gid': 0, u'ischr': False, u'wusr': True}) => {
    "ansible_loop_var": "item", 
    "changed": false, 
    "item": {
        "atime": 1595420107.449019, 
        "ctime": 1558690057.8965392, 
        "dev": 64768, 
        "gid": 0, 
        "gr_name": "root", 
        "inode": 7210673, 
        "isblk": false, 
        "ischr": false, 
        "isdir": false, 
        "isfifo": false, 
        "isgid": false, 
        "islnk": false, 
        "isreg": true, 
        "issock": false, 
        "isuid": false, 
        "mode": "0644", 
        "mtime": 1558689976.840408, 
        "nlink": 1, 
        "path": "/etc/ssl/certs/ca_multisite_chain_complete.pem", 
        "pw_name": "root", 
        "rgrp": true, 
        "roth": true, 
        "rusr": true, 
        "size": 13966, 
        "uid": 0, 
        "wgrp": false, 
        "woth": false, 
        "wusr": true, 
        "xgrp": false, 
        "xoth": false, 
        "xusr": false
    }, 
    "rc": 1
}

MSG:

MODULE FAILURE
See stdout/stderr for the exact error

MODULE_STDOUT:

Traceback (most recent call last):

  File "/tmp/ansible-tmp-1595432655.5-24980-6466534372655/AnsiballZ_x509_certificate_info.py", line 102, in <module>

    _ansiballz_main()

  File "/tmp/ansible-tmp-1595432655.5-24980-6466534372655/AnsiballZ_x509_certificate_info.py", line 94, in _ansiballz_main

    invoke_module(zipped_mod, temp_path, ANSIBALLZ_PARAMS)

  File "/tmp/ansible-tmp-1595432655.5-24980-6466534372655/AnsiballZ_x509_certificate_info.py", line 40, in invoke_module

    runpy.run_module(mod_name='ansible_collections.community.crypto.plugins.modules.x509_certificate_info', init_globals=None, run_name='__main__', alter_sys=True)

  File "/usr/lib64/python3.6/runpy.py", line 205, in run_module

    return _run_module_code(code, init_globals, run_name, mod_spec)

  File "/usr/lib64/python3.6/runpy.py", line 96, in _run_module_code

    mod_name, mod_spec, pkg_name, script_name)

  File "/usr/lib64/python3.6/runpy.py", line 85, in _run_code

    exec(code, run_globals)

  File "/tmp/ansible_community.crypto.x509_certificate_info_payload_6sv72yl8/ansible_community.crypto.x509_certificate_info_payload.zip/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py", line 881, in <module>

  File "/tmp/ansible_community.crypto.x509_certificate_info_payload_6sv72yl8/ansible_community.crypto.x509_certificate_info_payload.zip/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py", line 874, in main

  File "/tmp/ansible_community.crypto.x509_certificate_info_payload_6sv72yl8/ansible_community.crypto.x509_certificate_info_payload.zip/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py", line 488, in get_info

  File "/tmp/ansible_community.crypto.x509_certificate_info_payload_6sv72yl8/ansible_community.crypto.x509_certificate_info_payload.zip/ansible_collections/community/crypto/plugins/modules/x509_certificate_info.py", line 560, in _get_key_usage

  File "/usr/local/lib64/python3.6/site-packages/cryptography/utils.py", line 170, in inner

    result = func(instance)

  File "/usr/local/lib64/python3.6/site-packages/cryptography/hazmat/backends/openssl/x509.py", line 127, in extensions

    self._backend, self._x509

  File "/usr/local/lib64/python3.6/site-packages/cryptography/hazmat/backends/openssl/decode_asn1.py", line 249, in parse

    "parsed".format(oid)

ValueError: The <ObjectIdentifier(oid=2.5.29.32, name=certificatePolicies)> extension is invalid and can't be parsed

MODULE_STDERR:

Warning: Permanently added 'XXXXXX,XXXXXX' (RSA) to the list of known hosts.

Connection to XXXXXX closed.
MarkusTeufelberger commented 4 years ago

From an initial glance it seems this might even bubble up from OpenSSL itself into cryptography.

Does running openssl x509 -in /etc/ssl/certs/ca_multisite_chain_complete.pem -text -noout on that host show something unusual or some errors?

Cool usage of the module by the way! :-)

yodatak commented 4 years ago

Hi no error here openssl x509 -in /etc/ssl/certs/ca_multisite_chain_complete.pem -text -noout Certificate: Data: Version: 3 (0x2) Serial Number: XXXXXXXXXXXXXXXXXXXXXX Signature Algorithm: sha1WithRSAEncryption Issuer: C=SE, O=AddTrust AB, OU=AddTrust External TTP Network, CN=AddTrust External CA Root Validity Not Before: Dec 1 00:00:00 2005 GMT Not After : Jun 24 19:06:30 2019 GMT Subject: XXXXXXXXXXXXXXXXXXXXXXXXXX INTERNET CA, CN=TBS X509 CA pro hosting Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: XXXXXX Exponent: XXXX X509v3 extensions: X509v3 Subject Key Identifier: XXXXXXXXXXXXXXX X509v3 Key Usage: critical Certificate Sign, CRL Sign X509v3 Basic Constraints: critical CA:TRUE, pathlen:0 X509v3 Extended Key Usage: Microsoft Server Gated Crypto, Netscape Server Gated Crypto X509v3 Certificate Policies: XXXXXXXXXXXXXXX 0.0 X509v3 CRL Distribution Points:

            Full Name:
              URI:http://crl.comodoca.com/AddTrustExternalCARoot.crl

            Full Name:
              URI:http://crl.comodo.net/AddTrustExternalCARoot.crl

        Authority Information Access:
            CA Issuers - URI:http://crt.comodoca.com/AddTrustUTNSGCCA.crt
            CA Issuers - URI:http://crt.comodo.net/AddTrustUTNSGCCA.crt

        Netscape Cert Type:
            SSL CA
Signature Algorithm: sha1WithRSAEncryption
     XXXXXXXXXXXXXXX
felixfontein commented 4 years ago

cryptography sometimes bundles its own libssl (depending on how you install it), so it could be that it is more strict. Anyway, this error is either caused by OpenSSL, by cryptography, or by the certificate (or by a combination of them). Without having access to the certificate itself, it's impossible for us to debug this further (and you probably won't have more success if you file this issue directly with cryptography).

yodatak commented 4 years ago

How I can i send you the certificate in a private way ?

felixfontein commented 4 years ago

You can send it by email to my email address (felix at fontein dot de).

felixfontein commented 4 years ago

@yodatak thanks for sending me the certificates. The problem is that they contain something for the X509v3 Certificate Policies extension that is invalid. You can see that already when using openssl x509 -noout -text -in /path/to/cert.pem. If the extension would be correct, the printout should look like:

            X509v3 Certificate Policies: 
                Policy: 2.23.140.1.2.1
                Policy: 1.3.6.1.4.1.44947.1.1.1
                  CPS: http://cps.root-x1.letsencrypt.org

If openssl cannot parse an extension, it simply dumps the binary data, and you get the output that it is showing for your certificate (which you unfortunately censored in the output in this issue):

            X509v3 Certificate Policies: 
                0M0[snip]....

I removed most of the content to avoid this identifying anything. It is clear from the leftovers though that this is not generated by https://github.com/openssl/openssl/blob/master/crypto/x509/v3_cpols.c#L405-L423, which it would be if the output would be parsable.

I looked at the certificate with https://lapo.it/asn1js/ (will not make network requests to the server, so your certificate is safe) and compared it to certificates that could be parsed. For my eyes, it looks like the certificate is correct according to https://tools.ietf.org/html/rfc5280#section-4.2.1.4. So this is probably a bug in OpenSSL's ASN.1 parser.

You should file an issue in https://github.com/openssl/openssl/ (the visible issue being that openssl x509 -in /path/to/cert -noout -text cannot process the extension, the underlying problem that OpenSSL cannot parse the X509v3 Certificate Policies extension). I'm not familiar with their issue process, but you'll probably also be asked to send them the certificate(s) which produce this error. See https://github.com/openssl/openssl/blob/master/SUPPORT.md#you-found-a-bug (I've already searched a bit through their issues and couldn't find anything related).