Skip to main content

Lib/ssl.py

cpython 3.14 @ ab2d84fe1023/Lib/ssl.py

ssl.py is the pure-Python facade that sits between application code and the _ssl C extension. It defines SSLContext, SSLSocket, SSLObject, and the full exception hierarchy, and re-exports every constant from _ssl so that callers never need to import the C module directly. The practical entry point for most users is create_default_context(), which builds a PROTOCOL_TLS_CLIENT context with certificate verification enabled and system-trusted CAs loaded.

The module distinguishes between two usage patterns. The legacy path wraps a plain socket.socket with SSLContext.wrap_socket() and returns an SSLSocket that can be used as a drop-in for the wrapped socket. The non-blocking and asyncio path uses SSLContext.wrap_bio() to return a memory-buffer-based SSLObject that performs TLS state-machine steps without owning an OS file descriptor, letting the event loop manage I/O separately.

Error handling is layered. SSLError is a subclass of OSError and carries an errno-style library and reason string sourced from the OpenSSL error queue. Specialised subclasses SSLZeroReturnError, SSLWantReadError, SSLWantWriteError, SSLSyscallError, and SSLCertVerificationError map to the OpenSSL SSL_ERROR_* codes so that callers can distinguish a clean TLS close from a genuine I/O error without inspecting numeric codes.

Map​

LinesSymbolRolegopy
1-100module preambleImports, __all__, re-export of _ssl constants and SSLError subclasses-
101-250SSLError hierarchySSLZeroReturnError, SSLWantReadError, SSLWantWriteError, SSLSyscallError, SSLCertVerificationError-
251-400DefaultVerifyPaths, _ASN1Object, PurposeNamed tuples and enum for CA paths and certificate purpose OIDs-
401-600SSLContextContext object wrapping _ssl.SSLContext; load_cert_chain, load_verify_locations, set_ciphers, set_alpn_protocols-
601-750SSLContext.wrap_socket, SSLContext.wrap_bioFactory methods that create SSLSocket or SSLObject from a context-
751-900create_default_context(), _create_unverified_context()Opinionated factory functions; load system cert store, set hostname checking-
901-1100SSLSocketTLS-aware socket subclass: read, write, do_handshake, unwrap, getpeercert, shutdown-
1101-1300SSLObjectMemory-BIO TLS object for async use: read, write, do_handshake, getpeercert, selected_alpn_protocol-
1301-1450match_hostname() (deprecated), cert_time_to_seconds()Legacy hostname matcher now delegated to OpenSSL; cert timestamp parser-
1451-1600get_server_certificate(), DER_cert_to_PEM_cert(), PEM_cert_to_DER_cert()Utility helpers for certificate format conversion and one-shot server inspection-

Reading​

SSLError hierarchy (lines 101 to 250)​

cpython 3.14 @ ab2d84fe1023/Lib/ssl.py#L101-250

Each subclass maps to one of the OpenSSL SSL_ERROR_* return codes that SSL_get_error() can produce. SSLWantReadError and SSLWantWriteError are not real errors; they signal that a non-blocking operation would block and the caller should re-drive the handshake or I/O after the socket becomes ready. SSLCertVerificationError adds a verify_code and verify_message attribute populated from the OpenSSL verification result, which gives the application a structured reason rather than just an error string.

class SSLCertVerificationError(SSLError):
"""A certificate could not be verified."""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.verify_code = kwargs.get('verify_code', 0)
self.verify_message = kwargs.get('verify_message', '')

SSLContext setup methods (lines 401 to 600)​

cpython 3.14 @ ab2d84fe1023/Lib/ssl.py#L401-600

SSLContext is a thin Python shell around the C-level _ssl.SSLContext. The Python layer adds property-based access to options flags, protocol version filtering, and higher-level helpers such as set_alpn_protocols (which marshals the list of strings into the wire-format length-prefixed byte string expected by the C layer). load_default_certs(purpose) maps the Purpose enum to the correct Windows certificate store name on that platform, or falls back to the OpenSSL default paths elsewhere.

create_default_context() (lines 751 to 900)​

cpython 3.14 @ ab2d84fe1023/Lib/ssl.py#L751-900

This function is the recommended way to create a context for outbound TLS connections. It hardcodes PROTOCOL_TLS_CLIENT, enables CERT_REQUIRED, sets check_hostname = True, and calls load_default_certs() so that the operating system trust store is used. The result rejects SSLv2, SSLv3, and (since 3.10) TLS 1.0 and 1.1 by default. A cafile, capath, or cadata argument can override the system store when connecting to services with a private CA.

def create_default_context(purpose=Purpose.SERVER_AUTH, *,
cafile=None, capath=None, cadata=None):
context = SSLContext(PROTOCOL_TLS_CLIENT)
context.load_default_certs(purpose)
if cafile or capath or cadata:
context.load_verify_locations(cafile, capath, cadata)
return context

SSLSocket I/O methods (lines 901 to 1100)​

cpython 3.14 @ ab2d84fe1023/Lib/ssl.py#L901-1100

SSLSocket.read() and SSLSocket.write() delegate immediately to the underlying SSLObject. The interesting logic is in the retry loop inside SSLSocket._sslobj.read and the handshake state guard: if do_handshake_on_connect is True the handshake runs inside connect() and accept(), keeping the interface compatible with plain socket.socket. The unwrap() method performs a bidirectional TLS close-notify exchange and returns the underlying plaintext socket, which callers can continue to use for non-TLS traffic.

SSLObject for async use (lines 1101 to 1300)​

cpython 3.14 @ ab2d84fe1023/Lib/ssl.py#L1101-1300

SSLObject wraps an in-memory BIO pair rather than an OS socket. The caller is responsible for moving bytes between the two BIOs and the actual transport. read() pulls plaintext out; write() pushes plaintext in; read_bio and write_bio expose the raw MemoryBIO objects that the event loop reads from and writes to. This design lets asyncio.SSLProtocol implement TLS without any blocking system calls.

gopy mirror​

Not yet ported.