[Python-Dev] Simplify and unify SSL verification

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 key_file, cert_file and check_hostname arguments in
>   various in favor of context. Python 3.5 will no longer have these
>   arguments in http.client, smtplib etc.
>
> - deprecate implicit verify_mode=CERT_NONE. Python 3.5 will default
>   to CERT_REQUIRED.
>
> - enforce hostname matching in CERT_OPTIONAL or CERT_REQUIRED mode
>   by default in Python 3.5.
>
> - add ssl.get_default_context() 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 check_cert option to SSLContext and a check_cert() function to
>   SSLSocket in order to unify certificate validation and hostname
>   matching. (Python 3.4)
>
>
> The SSLContext's check_cert option will support four values:

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

> None (default)
>   use match_hostname() if verify_mode is CERT_OPTIONAL or
>   CERT_REQUIRED
> True
>   always use match_hostname()
> False
>   never use match_hostname()
> 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.create_connection((hostname, self.port))
>       sock = self.context.wrap_socket(sock,
>                                       server_hostname=hostname)
>       sock.check_cert(hostname, initiator=self)
>       return sock
>
>
> The check_cert 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 CERT_NONE verification mode and SPKI data for SSL
> pinning. A custom check_cert 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