over many years ❏ complicated ❏ _ssl._SSLSocket is wrapped by ssl.SSLObject, which is wrapped again by ssl.SSLSocket, which is a subclass of socket.socket. ❏ insane, footgunny legacy API ❏ SSLSocket.getpeercert() returns empty dict for CERT_NONE ❏ SSLContext() defaults to no verification, must use custom factory ❏ stdlib modules accept context or cert/key/verify args
to cert chain ❏ private keys can only be loaded from a file ❏ no memory buffer ❏ no PKCS#11 engine ❏ incomprehensible error messages when cert validation failed ❏ no SPKI hash for cert pinning (HPKP) ❏ no OCSP validation
around OpenSSL ❏ written in C ❏ PyPy, Jython and IronPython have to roll their own implementation ❏ additional work ❏ additional bugs ❏ stuck to OpenSSL 0.9.8 features ❏ stuck to custom host name verification code
2.7. x ❏ PEP 476 -- Enabling certificate verification ❏ backports to Python 2.7 ❏ ssl.create_default_context() Thanks to Alex, Antoine, Donald, Nick and whoever contributed to the cause!
❏ push 3rd party libraries to use context argument ❏ ABC ❏ context.wrap_socket(socket, hostname) → SSLSocket ❏ SSLSocket ❏ SSL-specific exceptions ❏ creation and configuration of context object is not standardized
-> bool ❏ X509 type ❏ instead of getpeercert() dict ❏ VerifyContext type (X509_STORE_CTX) ❏ current subject, issuer, error ❏ PrivateKey type ❏ OCSP staple verification ❏ PyCapsule export of internal C API ❏ allow 3rd party to interact with internal C API and OpenSSL objects
has cleaner API ❏ provide 1.0.2 compatibility layer (implemented in #26470) ❏ deprecate OpenSSL 1.0.1 and 0.9.8 ❏ use OpenSSL to verify host names ❏ backward compatibility? ❏ OSX? ❏ LibreSSL?
❏ Python must never ever ship its own root certificate bundle. Period. ❏ Trust the operating system and use its root store. ❏ OSX? ❏ Windows implementation is semi-broken. SChannel fetch unknown root certs from MS, Python doesn’t. ❏ Libraries should provide SSLContext argument so users can customize trust settings or use env var SSL_CERT_FILE.