mirror of
https://github.com/python/cpython.git
synced 2025-08-19 00:00:48 +00:00
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:
parent
499718de49
commit
d76088d972
3 changed files with 37 additions and 2 deletions
11
Lib/ssl.py
11
Lib/ssl.py
|
@ -81,8 +81,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"
|
||||||
|
|
||||||
|
@ -91,6 +92,11 @@ from socket import getnameinfo as _getnameinfo
|
||||||
import base64 # for DER-to-PEM translation
|
import base64 # for DER-to-PEM translation
|
||||||
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 SSLSocket(socket):
|
class SSLSocket(socket):
|
||||||
|
|
||||||
"""This class implements a subtype of socket.socket that wraps
|
"""This class implements a subtype of socket.socket that wraps
|
||||||
|
@ -112,6 +118,9 @@ class SSLSocket(socket):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
if ciphers is None and ssl_version != _SSLv2_IF_EXISTS:
|
||||||
|
ciphers = _DEFAULT_CIPHERS
|
||||||
|
|
||||||
if certfile and not keyfile:
|
if certfile and not keyfile:
|
||||||
keyfile = certfile
|
keyfile = certfile
|
||||||
# see if it's connected
|
# see if it's connected
|
||||||
|
|
|
@ -417,10 +417,11 @@ else:
|
||||||
ca_certs=self.server.cacerts,
|
ca_certs=self.server.cacerts,
|
||||||
cert_reqs=self.server.certreqs,
|
cert_reqs=self.server.certreqs,
|
||||||
ciphers=self.server.ciphers)
|
ciphers=self.server.ciphers)
|
||||||
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 " +
|
handle_error("\n server: bad connection attempt from " +
|
||||||
str(self.sock.getpeername()) + ":\n")
|
str(self.sock.getpeername()) + ":\n")
|
||||||
|
@ -529,12 +530,14 @@ else:
|
||||||
sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
|
sys.stdout.write(' server: wrapped server socket as %s\n' % str(self.sock))
|
||||||
self.port = test_support.bind_port(self.sock)
|
self.port = test_support.bind_port(self.sock)
|
||||||
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()
|
||||||
|
@ -649,6 +652,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 test_support.verbose:
|
if test_support.verbose:
|
||||||
|
@ -1310,6 +1314,25 @@ else:
|
||||||
t.join()
|
t.join()
|
||||||
server.close()
|
server.close()
|
||||||
|
|
||||||
|
def test_default_ciphers(self):
|
||||||
|
with ThreadedEchoServer(CERTFILE,
|
||||||
|
ssl_version=ssl.PROTOCOL_SSLv23,
|
||||||
|
chatty=False) as server:
|
||||||
|
sock = socket.socket()
|
||||||
|
try:
|
||||||
|
# Force a set of weak ciphers on our client socket
|
||||||
|
try:
|
||||||
|
s = ssl.wrap_socket(sock,
|
||||||
|
ssl_version=ssl.PROTOCOL_SSLv23,
|
||||||
|
ciphers="DES")
|
||||||
|
except ssl.SSLError:
|
||||||
|
self.skipTest("no DES cipher available")
|
||||||
|
with self.assertRaises((OSError, ssl.SSLError)):
|
||||||
|
s.connect((HOST, server.port))
|
||||||
|
finally:
|
||||||
|
sock.close()
|
||||||
|
self.assertIn("no shared cipher", str(server.conn_errors[0]))
|
||||||
|
|
||||||
|
|
||||||
def test_main(verbose=False):
|
def test_main(verbose=False):
|
||||||
global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, NOKIACERT
|
global CERTFILE, SVN_PYTHON_ORG_ROOT_CERT, NOKIACERT
|
||||||
|
|
|
@ -89,6 +89,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 #13639: Accept unicode filenames in tarfile.open(mode="w|gz").
|
- Issue #13639: Accept unicode filenames in tarfile.open(mode="w|gz").
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue