mirror of
https://github.com/python/cpython.git
synced 2025-08-31 14:07:50 +00:00
Issue #19735: Implement private function ssl._create_stdlib_context() to
create SSLContext objects in Python's stdlib module. It provides a single configuration point and makes use of SSLContext.load_default_certs().
This commit is contained in:
parent
32eddc1bbc
commit
67986f9431
11 changed files with 100 additions and 55 deletions
50
Lib/ssl.py
50
Lib/ssl.py
|
@ -398,6 +398,43 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
|
|||
return context
|
||||
|
||||
|
||||
def _create_stdlib_context(protocol=PROTOCOL_SSLv23, *, cert_reqs=None,
|
||||
purpose=Purpose.SERVER_AUTH,
|
||||
certfile=None, keyfile=None,
|
||||
cafile=None, capath=None, cadata=None):
|
||||
"""Create a SSLContext object for Python stdlib modules
|
||||
|
||||
All Python stdlib modules shall use this function to create SSLContext
|
||||
objects in order to keep common settings in one place. The configuration
|
||||
is less restrict than create_default_context()'s to increase backward
|
||||
compatibility.
|
||||
"""
|
||||
if not isinstance(purpose, _ASN1Object):
|
||||
raise TypeError(purpose)
|
||||
|
||||
context = SSLContext(protocol)
|
||||
# SSLv2 considered harmful.
|
||||
context.options |= OP_NO_SSLv2
|
||||
|
||||
if cert_reqs is not None:
|
||||
context.verify_mode = cert_reqs
|
||||
|
||||
if keyfile and not certfile:
|
||||
raise ValueError("certfile must be specified")
|
||||
if certfile or keyfile:
|
||||
context.load_cert_chain(certfile, keyfile)
|
||||
|
||||
# load CA root certs
|
||||
if cafile or capath or cadata:
|
||||
context.load_verify_locations(cafile, capath, cadata)
|
||||
elif context.verify_mode != CERT_NONE:
|
||||
# no explicit cafile, capath or cadata but the verify mode is
|
||||
# CERT_OPTIONAL or CERT_REQUIRED. Let's try to load default system
|
||||
# root CA certificates for the given purpose. This may fail silently.
|
||||
context.load_default_certs(purpose)
|
||||
|
||||
return context
|
||||
|
||||
class SSLSocket(socket):
|
||||
"""This class implements a subtype of socket.socket that wraps
|
||||
the underlying OS socket in an SSL context when necessary, and
|
||||
|
@ -829,15 +866,16 @@ def get_server_certificate(addr, ssl_version=PROTOCOL_SSLv3, ca_certs=None):
|
|||
If 'ssl_version' is specified, use it in the connection attempt."""
|
||||
|
||||
host, port = addr
|
||||
if (ca_certs is not None):
|
||||
if ca_certs is not None:
|
||||
cert_reqs = CERT_REQUIRED
|
||||
else:
|
||||
cert_reqs = CERT_NONE
|
||||
s = create_connection(addr)
|
||||
s = wrap_socket(s, ssl_version=ssl_version,
|
||||
cert_reqs=cert_reqs, ca_certs=ca_certs)
|
||||
dercert = s.getpeercert(True)
|
||||
s.close()
|
||||
context = _create_stdlib_context(ssl_version,
|
||||
cert_reqs=cert_reqs,
|
||||
cafile=ca_certs)
|
||||
with create_connection(addr) as sock:
|
||||
with context.wrap_socket(sock) as sslsock:
|
||||
dercert = sslsock.getpeercert(True)
|
||||
return DER_cert_to_PEM_cert(dercert)
|
||||
|
||||
def get_protocol_name(protocol_code):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue