[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