[Python-Dev] Simplify and unify SSL verification

Christian Heimes christian at python.org
Thu Nov 7 19:13:38 CET 2013


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)

- 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:

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)
  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



More information about the Python-Dev mailing list