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

get_certificate module is not using SNI resulting in certs coming back as invalid #69

Closed
ToniCipriani opened this issue Jun 15, 2020 · 1 comment · Fixed by #84
Closed

Comments

@ToniCipriani
Copy link

ToniCipriani commented Jun 15, 2020

SUMMARY

When using get_certificate, the client does not provide an SNI, causing some certs to come back as invalid. One example of this is from AppSpot (testsafebrowsing.appspot.com).

ISSUE TYPE
  • Bug Report
COMPONENT NAME

get_certificate

ANSIBLE VERSION
ansible-playbook 2.9.7
  config file = None
  configured module search path = ['/Users/calcheu/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.7/site-packages/ansible
  executable location = /usr/local/bin/ansible-playbook
  python version = 3.7.5 (default, Nov  1 2019, 02:16:32) [Clang 11.0.0 (clang-1100.0.33.8)]
CONFIGURATION

OS / ENVIRONMENT

MacOS X Mojave

STEPS TO REPRODUCE
  - name: "Fetch Cert from URL"
    get_certificate:
      host: "testsafebrowsing.appspot.com"
      port: 443
EXPECTED RESULTS

Certificate string returned by get_certificate is valid

ACTUAL RESULTS
Connection is rejected by AppSpot. Certificate has CN of "invalid".
@felixfontein
Copy link
Contributor

I guess this can be fixed by using a method similar to the one handling proxies, but for without proxies. Probably this would work:

        try:
            ctx = create_default_context()
            ctx.check_hostname = False
            ctx.verify_mode = CERT_NONE

            if ca_cert:
                ctx.verify_mode = CERT_OPTIONAL
                ctx.load_verify_locations(cafile=ca_cert)

            with socket.create_connection((host, port)) as sock:
                cert = ctx.wrap_socket(sock, server_hostname=host).getpeercert(True)

            cert = DER_cert_to_PEM_cert(cert)
        except Exception as e:
            module.fail_json(msg="Failed to get cert from port with error: {0}".format(e))

(See https://docs.python.org/3/library/ssl.html#ssl.SSLContext.wrap_socket)

felixfontein added a commit that referenced this issue Jul 13, 2020
* get_certificate - Add support of SNI

For python versions supporting `create_default_context` support SNI by using low-level
SSLContext.wrap_socket().getpeercert().

Add also more information in the error message

fixes #69

* Make sure default CA certificates are not loaded when ca_cert is specified.

* Refactor to combine common code.

* Update changelogs/fragments/get_certificate-add_support_for_SNI.yml

Co-authored-by: Felix Fontein <[email protected]>

Co-authored-by: Felix Fontein <[email protected]>
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.

2 participants