[Python-Dev] Simplify and unify SSL verification (original) (raw)

Nick Coghlan ncoghlan at gmail.com
Thu Nov 7 23:25:25 CET 2013


On 8 Nov 2013 04:18, "Christian Heimes" <christian at python.org> wrote:

Hi, I'd like to simplify, unify and tighten SSL handling and verification code in Python 3.5. Therefore I propose to deprecate some features for Python 3.4. SSLContext objects are going to be the central instance for configuration. In order to archive the goal I propose to - deprecate the keyfile, certfile and checkhostname arguments in various in favor of context. Python 3.5 will no longer have these arguments in http.client, smtplib etc. - deprecate implicit verifymode=CERTNONE. Python 3.5 will default to CERTREQUIRED. - enforce hostname matching in CERTOPTIONAL or CERTREQUIRED mode by default in Python 3.5. - add ssl.getdefaultcontext() to acquire a default SSLContext object if the context argument is None. (Python 3.4)

Change this to create_default_context() (to make it clearer there is no global context object) and I'm generally +1.

- add checkcert option to SSLContext and a checkcert() function to SSLSocket in order to unify certificate validation and hostname matching. (Python 3.4)

The SSLContext's checkcert option will support four values:

I suggest just making this a "verifier" argument that's always a callable.

None (default) use matchhostname() if verifymode is CERTOPTIONAL or CERTREQUIRED True always use matchhostname() False never use matchhostname() callable function: call func(sslsock, hostname, initiator, **kwargs)

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.

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.

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.

The initiator argument is the object that has initiated the SSL connection, e.g. http.client.HTTPSConnection object. sslsock.context points to its SSLContext object

A connect method may look like this: def connect(self): hostname = self.hostname s = socket.createconnection((hostname, self.port)) sock = self.context.wrapsocket(sock, serverhostname=hostname) sock.checkcert(hostname, initiator=self) return sock The checkcert option for SSLContext makes it easy to customize cert handling. Application developers just need to configure a SSLContext object in order to customize SSL cert verification and matching. In Python 3.4 it will be possible to get the full peer chain, cert information in CERTNONE verification mode and SPKI data for SSL pinning. A custom checkcert callback can be used to validate self-signed certs or test for pinned certificates. The proposal does NOT address the CA certificates difficulty. It's a different story that needs to be addressed for all platforms separately. Most Linux distributions, (Net|Free|Open) BSD and Mac Ports come with SSL certs anyway, although some do not correctly handle the certs' purposes. I have working code for Windows' cert system store that will land in 3.4. Native Mac OS X hasn't been addressed yet. AIX, HP-UX, Solaris etc. don't come with CA certs. Christian


Python-Dev mailing list Python-Dev at python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20131108/9da0b1e0/attachment.html>



More information about the Python-Dev mailing list