diff -r 015c4d785be7 Doc/library/ssl.rst --- a/Doc/library/ssl.rst Sun Mar 23 16:31:34 2014 +0100 +++ b/Doc/library/ssl.rst Sun Mar 23 13:29:22 2014 -0400 @@ -250,13 +250,13 @@ :const:`None`, this function can choose to trust the system's default CA certificates instead. - The settings in Python 3.4 are: :data:`PROTOCOL_TLSv1` with high encryption - cipher suites without RC4 and without unauthenticated cipher suites. - Passing :data:`~Purpose.SERVER_AUTH` as *purpose* sets - :data:`~SSLContext.verify_mode` to :data:`CERT_REQUIRED` and either - loads CA certificates (when at least one of *cafile*, *capath* or *cadata* - is given) or uses :meth:`SSLContext.load_default_certs` to load default - CA certificates. + The settings in Python 3.4 are: :data:`PROTOCOL_SSLv23`, :data:`OP_NO_SSLv2`, + and :data:`OP_NO_SSLv3` with high encryption cipher suites without RC4 and + without unauthenticated cipher suites. Passing :data:`~Purpose.SERVER_AUTH` + as *purpose* sets :data:`~SSLContext.verify_mode` to :data:`CERT_REQUIRED` + and either loads CA certificates (when at least one of *cafile*, *capath* or + *cadata* is given) or uses :meth:`SSLContext.load_default_certs` to load + default CA certificates. .. note:: The protocol, options, cipher and other settings may change to more @@ -266,6 +266,19 @@ If your application needs specific settings, you should create a :class:`SSLContext` and apply the settings yourself. + .. note:: + If you find that when certain older clients or servers attempt to connect + with a :class:`SSLContext` created by this function that they get an + error stating "Protocol or cipher suite mismatch", it may be that they + only support SSL3.0 which this function excludes using the + :data:`OP_NO_SSLv3`. SSL3.0 has problematic security due to a number of + poor implementations and it's reliance on MD5 within the protocol. If you + wish to continue to use this function but still allow SSL 3.0 connections + you can re-enable them using:: + + ctx = ssl.create_default_context(Purpose.CLIENT_AUTH) + ctx.options &= ~ssl.OP_NO_SSLv3 + .. versionadded:: 3.4 diff -r 015c4d785be7 Lib/ssl.py --- a/Lib/ssl.py Sun Mar 23 16:31:34 2014 +0100 +++ b/Lib/ssl.py Sun Mar 23 13:29:22 2014 -0400 @@ -179,7 +179,7 @@ 'DH+RC4:RSA+RC4:!aNULL:!eNULL:!MD5' ) -# Restricted and more secure ciphers +# Restricted and more secure ciphers for the server side # This list has been explicitly chosen to: # * Prefer cipher suites that offer perfect forward secrecy (DHE/ECDHE) # * Prefer ECDHE over DHE for better performance @@ -188,7 +188,7 @@ # * Then Use 3DES as fallback which is secure but slow # * Disable NULL authentication, NULL encryption, MD5 MACs, DSS, and RC4 for # security reasons -_RESTRICTED_CIPHERS = ( +_RESTRICTED_SERVER_CIPHERS = ( 'ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+HIGH:' 'DH+HIGH:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+HIGH:RSA+3DES:!aNULL:' '!eNULL:!MD5:!DSS:!RC4' @@ -404,17 +404,35 @@ """ if not isinstance(purpose, _ASN1Object): raise TypeError(purpose) - context = SSLContext(PROTOCOL_TLSv1) + + context = SSLContext(PROTOCOL_SSLv23) + # SSLv2 considered harmful. context.options |= OP_NO_SSLv2 + + # SSLv3 has problematic security and is only required for really old + # clients such as IE6 on Windows XP + context.options |= OP_NO_SSLv3 + # disable compression to prevent CRIME attacks (OpenSSL 1.0+) context.options |= getattr(_ssl, "OP_NO_COMPRESSION", 0) - # disallow ciphers with known vulnerabilities - context.set_ciphers(_RESTRICTED_CIPHERS) - # verify certs and host name in client mode + if purpose == Purpose.SERVER_AUTH: + # verify certs and host name in client mode context.verify_mode = CERT_REQUIRED context.check_hostname = True + elif purpose == Purpose.CLIENT_AUTH: + # Prefer the server's ciphers by default so that we get stronger + # encryption + context.options |= getattr(_ssl, "OP_CIPHER_SERVER_PREFERENCE", 0) + + # Use single use keys in order to improve forward secrecy + context.options |= getattr(_ssl, "OP_SINGLE_DH_USE", 0) + context.options |= getattr(_ssl, "OP_SINGLE_ECDH_USE", 0) + + # disallow ciphers with known vulnerabilities + context.set_ciphers(_RESTRICTED_SERVER_CIPHERS) + if cafile or capath or cadata: context.load_verify_locations(cafile, capath, cadata) elif context.verify_mode != CERT_NONE: diff -r 015c4d785be7 Lib/test/test_ssl.py --- a/Lib/test/test_ssl.py Sun Mar 23 16:31:34 2014 +0100 +++ b/Lib/test/test_ssl.py Sun Mar 23 13:29:22 2014 -0400 @@ -1014,23 +1014,43 @@ def test_create_default_context(self): ctx = ssl.create_default_context() - self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1) + self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23) self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED) self.assertTrue(ctx.check_hostname) self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2) + self.assertEqual( + ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0), + getattr(ssl, "OP_NO_COMPRESSION", 0), + ) 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.protocol, ssl.PROTOCOL_SSLv23) self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED) self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2) + self.assertEqual( + ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0), + getattr(ssl, "OP_NO_COMPRESSION", 0), + ) ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) - self.assertEqual(ctx.protocol, ssl.PROTOCOL_TLSv1) + self.assertEqual(ctx.protocol, ssl.PROTOCOL_SSLv23) self.assertEqual(ctx.verify_mode, ssl.CERT_NONE) self.assertEqual(ctx.options & ssl.OP_NO_SSLv2, ssl.OP_NO_SSLv2) + self.assertEqual( + ctx.options & getattr(ssl, "OP_NO_COMPRESSION", 0), + getattr(ssl, "OP_NO_COMPRESSION", 0), + ) + self.assertEqual( + ctx.options & getattr(ssl, "OP_SINGLE_DH_USE", 0), + getattr(ssl, "OP_SINGLE_DH_USE", 0), + ) + self.assertEqual( + ctx.options & getattr(ssl, "OP_SINGLE_ECDH_USE", 0), + getattr(ssl, "OP_SINGLE_ECDH_USE", 0), + ) def test__create_stdlib_context(self): ctx = ssl._create_stdlib_context() diff -r 015c4d785be7 Misc/NEWS --- a/Misc/NEWS Sun Mar 23 16:31:34 2014 +0100 +++ b/Misc/NEWS Sun Mar 23 13:29:22 2014 -0400 @@ -23,6 +23,9 @@ Library ------- +- Issue #21013: Enhance ssl.create_default_context() when used for server side + sockets to provide better security by default. + - Issue #20633: Replace relative import by absolute import. - Issue #20980: Stop wrapping exception when using ThreadPool.