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

Adding support for TLS authentication #1469

merged 2 commits into from Sep 7, 2019


Copy link

@barsand barsand commented Mar 8, 2019

Continuation of PR #1188.

With this change added, one can use a dict with extra information to be added to socket creation on load_ssl_context.

Adding a more complex set of parameters to ssl_context, when using Flask, for example, will be possible through a new valid instance of ssl context, such as:

from flask import Flask
app = Flask(__name__)
ssl_context = {
		'cert_file': 'auth/server/crt.crt',
		'pkey_file': 'auth/server/key.key',
		'ca_certs': 'auth/server/ca.crt',
		'cert_reqs': ssl.CERT_REQUIRED
	}, ssl_context=ssl_context)

If possible - and valid, returned values from SSLSocket.getpeercert will be stored into environ['SSL_CLIENT_CERT'].

@barsand barsand force-pushed the cert-forwarding branch from dd0307d to 1c0b481 Mar 8, 2019
@davidism davidism added this to the 1.0 milestone Mar 8, 2019
@davidism davidism force-pushed the cert-forwarding branch 2 times, most recently from daf134c to 8008e7a Jul 15, 2019
Copy link

@davidism davidism commented Sep 6, 2019

I'm trying to verify this, but as soon as I add ssl.CERT_REQUIRED, Firefox gives me SEC_ERROR_LIBRARY_FAILURE. Can't tell if it's a problem with my machine/Firefox, or with the way I generated the cert. I used mkcert:

$ mkcert -install
$ mkcert localhost
$ mkcert -client david
    'keyfile': 'localhost-key.pem',
    'certfile': 'localhost.pem',
    'ca_certs': '/home/david/.local/share/mkcert/rootCA.pem',
    'cert_reqs': ssl.CERT_REQUIRED,

Copy link

@davidism davidism commented Sep 7, 2019

Must have been my computer, I tried on another and it's working as expected.

@davidism davidism force-pushed the cert-forwarding branch from 8008e7a to 320abb6 Sep 7, 2019
Copy link

@davidism davidism commented Sep 7, 2019

While self.connection.getpeercert() gives very nice information, it won't match what Nginx or another server could put in the SSL_CLIENT_CERT header. Nginx passes the cert in PEM format. getpeercert(binary_form=True) returns DER bytes, which can be converted to PEM. cryptography can be used to read the cert.

from cryptography import x509
from cryptography.hazmat.backends import default_backend
x509.load_pem_x509_certificate(cert.encode('ascii'), default_backend())

Also rolling back the ability to pass a dict to ssl_context. I started trying to write documentation for it and it was looking too complicated. Werkzeug already supports passing a real SSLContext object for complex stuff like this.

context = ssl.SSLContext()
context.load_cert_chain("localhost.pem", "localhost-key.pem")
context.verify_mode = ssl.CERT_REQUIRED

@davidism davidism merged commit dd9342b into pallets:master Sep 7, 2019
11 checks passed
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

2 participants