Issue #19689: Add ssl.create_default_context() factory function. It creates

a new SSLContext object with secure default settings.
This commit is contained in:
Christian Heimes 2013-11-23 15:58:30 +01:00
parent 6b2ff98df4
commit 4c05b472dd
4 changed files with 76 additions and 0 deletions

View File

@ -346,6 +346,24 @@ Certificate handling
.. versionchanged:: 3.3
This function is now IPv6-compatible.
.. function:: create_default_context(purpose=Purpose.SERVER_AUTH, cafile=None, capath=None, cadata=None)
Create a :class:`SSLContext` with default settings.
The current settings are: :data:`PROTOCOL_TLSv1` with high encryption
cipher suites without RC4 and without unauthenticated cipher suites. The
*purpose* :data:`Purpose.SERVER_AUTH` sets verify_mode to
:data:`CERT_REQUIRED` and either loads CA certs (when at least one of
*cafile*, *capath* or *cadata* is given) or uses
:meth:`SSLContext.load_default_certs` to load default CA certs.
.. note::
The protocol, options, cipher and other settings may change to more
restrictive values anytime without prior deprecation. The values
represent a fair balance between maximum compatibility and security.
.. versionadded:: 3.4
.. function:: DER_cert_to_PEM_cert(DER_cert_bytes)
Given a certificate as a DER-encoded blob of bytes, returns a PEM-encoded

View File

@ -165,6 +165,13 @@ else:
# (OpenSSL's default setting is 'DEFAULT:!aNULL:!eNULL')
_DEFAULT_CIPHERS = 'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2'
# restricted and more secure ciphers
# HIGH: high encryption cipher suites with key length >= 128 bits (no MD5)
# !aNULL: only authenticated cipher suites (no anonymous DH)
# !RC4: no RC4 streaming cipher, RC4 is broken
# !DSS: RSA is preferred over DSA
_RESTRICTED_CIPHERS = 'HIGH:!aNULL:!RC4:!DSS'
class CertificateError(ValueError):
pass
@ -363,6 +370,34 @@ class SSLContext(_SSLContext):
self.set_default_verify_paths()
def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
capath=None, cadata=None):
"""Create a SSLContext object with default settings.
NOTE: The protocol and settings may change anytime without prior
deprecation. The values represent a fair balance between maximum
compatibility and security.
"""
if not isinstance(purpose, _ASN1Object):
raise TypeError(purpose)
context = SSLContext(PROTOCOL_TLSv1)
# SSLv2 considered harmful.
context.options |= OP_NO_SSLv2
# disallow ciphers with known vulnerabilities
context.set_ciphers(_RESTRICTED_CIPHERS)
# verify certs in client mode
if purpose == Purpose.SERVER_AUTH:
context.verify_mode = CERT_REQUIRED
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

View File

@ -999,6 +999,26 @@ class ContextTests(unittest.TestCase):
self.assertRaises(TypeError, ctx.load_default_certs, None)
self.assertRaises(TypeError, ctx.load_default_certs, 'SERVER_AUTH')
def test_create_default_context(self):
ctx = ssl.create_default_context()
self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
with open(SIGNING_CA) as f:
cadata = f.read()
ctx = ssl.create_default_context(cafile=SIGNING_CA, capath=CAPATH,
cadata=cadata)
self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1)
self.assertEqual(ctx.verify_mode, ssl.CERT_NONE)
self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2)
class SSLErrorTests(unittest.TestCase):

View File

@ -68,6 +68,9 @@ Core and Builtins
Library
-------
- Issue #19689: Add ssl.create_default_context() factory function. It creates
a new SSLContext object with secure default settings.
- Issue #19292: Add SSLContext.load_default_certs() to load default root CA
certificates from default stores or system stores. By default the method
loads CA certs for authentication of server certs.