[Python-Dev] Simplify and unify SSL verification

Christian Heimes christian at python.org
Fri Nov 8 00:27:16 CET 2013

Am 07.11.2013 23:25, schrieb Nick Coghlan:
> Change this to create_default_context() (to make it clearer there is no
> global context object) and I'm generally +1.

Good idea!

> This overlaps confusingly with "verify_mode". Perhaps just offer a
> module level "verify_hostname" API that adapts between the verifier
> signature and match_hostname, say that is the default verifier, and that
> the verifier is always called.

verify_mode = CERT_REQUIRED checks a lot of stuff like certificate
chain, expiration date, cert purpose and all the other crypto + X.509
magic. It doesn't check that the cert data matches the host name, though.

My proposal tries to make the SSLContext object *the* central
configuration point for cert validation and give the user an API for a
callback that e.g. can check a a self signed certificate or do cert
pinning. It already holds all options (protocol, verify mode, CA certs,
cert, key, cert chain, NPN protocol, ciphers ...). The context also
holds information for SSL session resumption to speed up future
connection. It's just for a way to configure hostname matching and post
connection checks.

> Also, how does the verifier know the verify_mode? Even if that info is
> set on the wrapped socket, it may be better to make it an optional
> argument to verifiers as well, to make it clearer that a verify mode of
> CERT_NONE may mean verification doesn't actually check anything.

It involves some layers of indirection. Since Python 3.2 all SSL sockets
are created from a SSLContext object. Even SSLSocket.__init__() and
ssl.wrap_socket() create a SSLContext object first. The SSLSocket
instance has a reference to its SSLContext in SSLSocket.context.

Internally SSLSocket.check_cert(hostname, **kwargs) calls
self.context.check_cert(self, hostname, **kwargs) of its SSLContext.
SSLSocket.check_cert() has also an option to shut down the SSL
connection gracefully when an exception occurs.

> For the new method API (name suggestion: verify_cert), I believe that
> should default to CERT_REQUIRED, regardless of the mode configured on
> the wrapped socket.

I don't want to create more confusion between verify_mode and the new
feature, so I didn't use the term "verify" in the method name. Do you
have a good idea for a better name that does not contain verify?


More information about the Python-Dev mailing list