Issue #13636: Weak ciphers are now disabled by default in the ssl module

(except when SSLv2 is explicitly asked for).
This commit is contained in:
Antoine Pitrou 2012-01-03 22:46:48 +01:00
parent ea320abcae
commit 8f85f907e3
3 changed files with 34 additions and 3 deletions

View File

@ -86,8 +86,9 @@ _PROTOCOL_NAMES = {
} }
try: try:
from _ssl import PROTOCOL_SSLv2 from _ssl import PROTOCOL_SSLv2
_SSLv2_IF_EXISTS = PROTOCOL_SSLv2
except ImportError: except ImportError:
pass _SSLv2_IF_EXISTS = None
else: else:
_PROTOCOL_NAMES[PROTOCOL_SSLv2] = "SSLv2" _PROTOCOL_NAMES[PROTOCOL_SSLv2] = "SSLv2"
@ -98,6 +99,10 @@ import base64 # for DER-to-PEM translation
import traceback import traceback
import errno import errno
# Disable weak or insecure ciphers by default
# (OpenSSL's default setting is 'DEFAULT:!aNULL:!eNULL')
_DEFAULT_CIPHERS = 'DEFAULT:!aNULL:!eNULL:!LOW:!EXPORT:!SSLv2'
class CertificateError(ValueError): class CertificateError(ValueError):
pass pass
@ -165,7 +170,10 @@ class SSLContext(_SSLContext):
__slots__ = ('protocol',) __slots__ = ('protocol',)
def __new__(cls, protocol, *args, **kwargs): def __new__(cls, protocol, *args, **kwargs):
return _SSLContext.__new__(cls, protocol) self = _SSLContext.__new__(cls, protocol)
if protocol != _SSLv2_IF_EXISTS:
self.set_ciphers(_DEFAULT_CIPHERS)
return self
def __init__(self, protocol): def __init__(self, protocol):
self.protocol = protocol self.protocol = protocol

View File

@ -762,10 +762,11 @@ else:
try: try:
self.sslconn = self.server.context.wrap_socket( self.sslconn = self.server.context.wrap_socket(
self.sock, server_side=True) self.sock, server_side=True)
except ssl.SSLError: except ssl.SSLError as e:
# XXX Various errors can have happened here, for example # XXX Various errors can have happened here, for example
# a mismatching protocol version, an invalid certificate, # a mismatching protocol version, an invalid certificate,
# or a low-level bug. This should be made more discriminating. # or a low-level bug. This should be made more discriminating.
self.server.conn_errors.append(e)
if self.server.chatty: if self.server.chatty:
handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n") handle_error("\n server: bad connection attempt from " + repr(self.addr) + ":\n")
self.running = False self.running = False
@ -878,12 +879,14 @@ else:
self.port = support.bind_port(self.sock) self.port = support.bind_port(self.sock)
self.flag = None self.flag = None
self.active = False self.active = False
self.conn_errors = []
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.daemon = True self.daemon = True
def __enter__(self): def __enter__(self):
self.start(threading.Event()) self.start(threading.Event())
self.flag.wait() self.flag.wait()
return self
def __exit__(self, *args): def __exit__(self, *args):
self.stop() self.stop()
@ -1004,6 +1007,7 @@ else:
def __enter__(self): def __enter__(self):
self.start(threading.Event()) self.start(threading.Event())
self.flag.wait() self.flag.wait()
return self
def __exit__(self, *args): def __exit__(self, *args):
if support.verbose: if support.verbose:
@ -1604,6 +1608,22 @@ else:
t.join() t.join()
server.close() server.close()
def test_default_ciphers(self):
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
try:
# Force a set of weak ciphers on our client context
context.set_ciphers("DES")
except ssl.SSLError:
self.skipTest("no DES cipher available")
with ThreadedEchoServer(CERTFILE,
ssl_version=ssl.PROTOCOL_SSLv23,
chatty=False) as server:
with socket.socket() as sock:
s = context.wrap_socket(sock)
with self.assertRaises((OSError, ssl.SSLError)):
s.connect((HOST, server.port))
self.assertIn("no shared cipher", str(server.conn_errors[0]))
def test_main(verbose=False): def test_main(verbose=False):
if support.verbose: if support.verbose:

View File

@ -97,6 +97,9 @@ Core and Builtins
Library Library
------- -------
- Issue #13636: Weak ciphers are now disabled by default in the ssl module
(except when SSLv2 is explicitly asked for).
- Issue #12798: Updated the mimetypes documentation. - Issue #12798: Updated the mimetypes documentation.
- Issue #11006: Don't issue low level warning in subprocess when pipe2() fails. - Issue #11006: Don't issue low level warning in subprocess when pipe2() fails.