bpo-31346: Use PROTOCOL_TLS_CLIENT/SERVER (#3058)

Replaces PROTOCOL_TLSv* and PROTOCOL_SSLv23 with PROTOCOL_TLS_CLIENT and
PROTOCOL_TLS_SERVER.

Signed-off-by: Christian Heimes <christian@python.org>
This commit is contained in:
Christian Heimes 2017-09-15 20:27:30 +02:00 committed by GitHub
parent 4df60f18c6
commit a170fa162d
13 changed files with 321 additions and 310 deletions

View File

@ -45,7 +45,7 @@ def dummy_ssl_context():
if ssl is None: if ssl is None:
return None return None
else: else:
return ssl.SSLContext(ssl.PROTOCOL_SSLv23) return ssl.SSLContext(ssl.PROTOCOL_TLS)
def run_briefly(loop): def run_briefly(loop):

View File

@ -719,7 +719,7 @@ else:
'221 Goodbye.' '221 Goodbye.'
>>> >>>
''' '''
ssl_version = ssl.PROTOCOL_SSLv23 ssl_version = ssl.PROTOCOL_TLS_CLIENT
def __init__(self, host='', user='', passwd='', acct='', keyfile=None, def __init__(self, host='', user='', passwd='', acct='', keyfile=None,
certfile=None, context=None, certfile=None, context=None,
@ -753,7 +753,7 @@ else:
'''Set up secure control connection by using TLS/SSL.''' '''Set up secure control connection by using TLS/SSL.'''
if isinstance(self.sock, ssl.SSLSocket): if isinstance(self.sock, ssl.SSLSocket):
raise ValueError("Already using TLS") raise ValueError("Already using TLS")
if self.ssl_version >= ssl.PROTOCOL_SSLv23: if self.ssl_version >= ssl.PROTOCOL_TLS:
resp = self.voidcmd('AUTH TLS') resp = self.voidcmd('AUTH TLS')
else: else:
resp = self.voidcmd('AUTH SSL') resp = self.voidcmd('AUTH SSL')

View File

@ -522,7 +522,7 @@ def create_default_context(purpose=Purpose.SERVER_AUTH, *, cafile=None,
context.load_default_certs(purpose) context.load_default_certs(purpose)
return context return context
def _create_unverified_context(protocol=PROTOCOL_TLS, *, cert_reqs=None, def _create_unverified_context(protocol=PROTOCOL_TLS, *, cert_reqs=CERT_NONE,
check_hostname=False, purpose=Purpose.SERVER_AUTH, check_hostname=False, purpose=Purpose.SERVER_AUTH,
certfile=None, keyfile=None, certfile=None, keyfile=None,
cafile=None, capath=None, cadata=None): cafile=None, capath=None, cadata=None):
@ -541,9 +541,12 @@ def _create_unverified_context(protocol=PROTOCOL_TLS, *, cert_reqs=None,
# by default. # by default.
context = SSLContext(protocol) context = SSLContext(protocol)
if not check_hostname:
context.check_hostname = False
if cert_reqs is not None: if cert_reqs is not None:
context.verify_mode = cert_reqs context.verify_mode = cert_reqs
context.check_hostname = check_hostname if check_hostname:
context.check_hostname = True
if keyfile and not certfile: if keyfile and not certfile:
raise ValueError("certfile must be specified") raise ValueError("certfile must be specified")

View File

@ -824,13 +824,13 @@ class EventLoopTestsMixin:
'SSL not supported with proactor event loops before Python 3.5' 'SSL not supported with proactor event loops before Python 3.5'
) )
server_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
server_context.load_cert_chain(ONLYCERT, ONLYKEY) server_context.load_cert_chain(ONLYCERT, ONLYKEY)
if hasattr(server_context, 'check_hostname'): if hasattr(server_context, 'check_hostname'):
server_context.check_hostname = False server_context.check_hostname = False
server_context.verify_mode = ssl.CERT_NONE server_context.verify_mode = ssl.CERT_NONE
client_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) client_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
if hasattr(server_context, 'check_hostname'): if hasattr(server_context, 'check_hostname'):
client_context.check_hostname = False client_context.check_hostname = False
client_context.verify_mode = ssl.CERT_NONE client_context.verify_mode = ssl.CERT_NONE
@ -985,7 +985,7 @@ class EventLoopTestsMixin:
self.loop.run_until_complete(f) self.loop.run_until_complete(f)
def _create_ssl_context(self, certfile, keyfile=None): def _create_ssl_context(self, certfile, keyfile=None):
sslcontext = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
sslcontext.options |= ssl.OP_NO_SSLv2 sslcontext.options |= ssl.OP_NO_SSLv2
sslcontext.load_cert_chain(certfile, keyfile) sslcontext.load_cert_chain(certfile, keyfile)
return sslcontext return sslcontext
@ -1082,7 +1082,7 @@ class EventLoopTestsMixin:
server, host, port = self._make_ssl_server( server, host, port = self._make_ssl_server(
lambda: proto, SIGNED_CERTFILE) lambda: proto, SIGNED_CERTFILE)
sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
sslcontext_client.options |= ssl.OP_NO_SSLv2 sslcontext_client.options |= ssl.OP_NO_SSLv2
sslcontext_client.verify_mode = ssl.CERT_REQUIRED sslcontext_client.verify_mode = ssl.CERT_REQUIRED
if hasattr(sslcontext_client, 'check_hostname'): if hasattr(sslcontext_client, 'check_hostname'):
@ -1116,7 +1116,7 @@ class EventLoopTestsMixin:
server, path = self._make_ssl_unix_server( server, path = self._make_ssl_unix_server(
lambda: proto, SIGNED_CERTFILE) lambda: proto, SIGNED_CERTFILE)
sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
sslcontext_client.options |= ssl.OP_NO_SSLv2 sslcontext_client.options |= ssl.OP_NO_SSLv2
sslcontext_client.verify_mode = ssl.CERT_REQUIRED sslcontext_client.verify_mode = ssl.CERT_REQUIRED
if hasattr(sslcontext_client, 'check_hostname'): if hasattr(sslcontext_client, 'check_hostname'):
@ -1150,7 +1150,7 @@ class EventLoopTestsMixin:
server, host, port = self._make_ssl_server( server, host, port = self._make_ssl_server(
lambda: proto, SIGNED_CERTFILE) lambda: proto, SIGNED_CERTFILE)
sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
sslcontext_client.options |= ssl.OP_NO_SSLv2 sslcontext_client.options |= ssl.OP_NO_SSLv2
sslcontext_client.verify_mode = ssl.CERT_REQUIRED sslcontext_client.verify_mode = ssl.CERT_REQUIRED
sslcontext_client.load_verify_locations( sslcontext_client.load_verify_locations(
@ -1183,7 +1183,7 @@ class EventLoopTestsMixin:
server, path = self._make_ssl_unix_server( server, path = self._make_ssl_unix_server(
lambda: proto, SIGNED_CERTFILE) lambda: proto, SIGNED_CERTFILE)
sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
sslcontext_client.options |= ssl.OP_NO_SSLv2 sslcontext_client.options |= ssl.OP_NO_SSLv2
sslcontext_client.verify_mode = ssl.CERT_REQUIRED sslcontext_client.verify_mode = ssl.CERT_REQUIRED
sslcontext_client.load_verify_locations(cafile=SIGNING_CA) sslcontext_client.load_verify_locations(cafile=SIGNING_CA)
@ -1212,7 +1212,7 @@ class EventLoopTestsMixin:
server, host, port = self._make_ssl_server( server, host, port = self._make_ssl_server(
lambda: proto, SIGNED_CERTFILE) lambda: proto, SIGNED_CERTFILE)
sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sslcontext_client = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
sslcontext_client.options |= ssl.OP_NO_SSLv2 sslcontext_client.options |= ssl.OP_NO_SSLv2
sslcontext_client.verify_mode = ssl.CERT_REQUIRED sslcontext_client.verify_mode = ssl.CERT_REQUIRED
sslcontext_client.load_verify_locations(cafile=SIGNING_CA) sslcontext_client.load_verify_locations(cafile=SIGNING_CA)

View File

@ -902,17 +902,11 @@ class TestTLS_FTPClass(TestCase):
self.client.auth() self.client.auth()
self.assertRaises(ValueError, self.client.auth) self.assertRaises(ValueError, self.client.auth)
def test_auth_ssl(self):
try:
self.client.ssl_version = ssl.PROTOCOL_SSLv23
self.client.auth()
self.assertRaises(ValueError, self.client.auth)
finally:
self.client.ssl_version = ssl.PROTOCOL_TLSv1
def test_context(self): def test_context(self):
self.client.quit() self.client.quit()
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
self.assertRaises(ValueError, ftplib.FTP_TLS, keyfile=CERTFILE, self.assertRaises(ValueError, ftplib.FTP_TLS, keyfile=CERTFILE,
context=ctx) context=ctx)
self.assertRaises(ValueError, ftplib.FTP_TLS, certfile=CERTFILE, self.assertRaises(ValueError, ftplib.FTP_TLS, certfile=CERTFILE,
@ -941,9 +935,9 @@ class TestTLS_FTPClass(TestCase):
def test_check_hostname(self): def test_check_hostname(self):
self.client.quit() self.client.quit()
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.verify_mode = ssl.CERT_REQUIRED self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
ctx.check_hostname = True self.assertEqual(ctx.check_hostname, True)
ctx.load_verify_locations(CAFILE) ctx.load_verify_locations(CAFILE)
self.client = ftplib.FTP_TLS(context=ctx, timeout=TIMEOUT) self.client = ftplib.FTP_TLS(context=ctx, timeout=TIMEOUT)

View File

@ -1583,8 +1583,9 @@ class HTTPSTest(TestCase):
import ssl import ssl
support.requires('network') support.requires('network')
with support.transient_internet('self-signed.pythontest.net'): with support.transient_internet('self-signed.pythontest.net'):
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.verify_mode = ssl.CERT_REQUIRED self.assertEqual(context.verify_mode, ssl.CERT_REQUIRED)
self.assertEqual(context.check_hostname, True)
context.load_verify_locations(CERT_selfsigned_pythontestdotnet) context.load_verify_locations(CERT_selfsigned_pythontestdotnet)
h = client.HTTPSConnection('self-signed.pythontest.net', 443, context=context) h = client.HTTPSConnection('self-signed.pythontest.net', 443, context=context)
h.request('GET', '/') h.request('GET', '/')
@ -1599,8 +1600,7 @@ class HTTPSTest(TestCase):
import ssl import ssl
support.requires('network') support.requires('network')
with support.transient_internet('self-signed.pythontest.net'): with support.transient_internet('self-signed.pythontest.net'):
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations(CERT_localhost) context.load_verify_locations(CERT_localhost)
h = client.HTTPSConnection('self-signed.pythontest.net', 443, context=context) h = client.HTTPSConnection('self-signed.pythontest.net', 443, context=context)
with self.assertRaises(ssl.SSLError) as exc_info: with self.assertRaises(ssl.SSLError) as exc_info:
@ -1620,8 +1620,7 @@ class HTTPSTest(TestCase):
# The (valid) cert validates the HTTP hostname # The (valid) cert validates the HTTP hostname
import ssl import ssl
server = self.make_server(CERT_localhost) server = self.make_server(CERT_localhost)
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.verify_mode = ssl.CERT_REQUIRED
context.load_verify_locations(CERT_localhost) context.load_verify_locations(CERT_localhost)
h = client.HTTPSConnection('localhost', server.port, context=context) h = client.HTTPSConnection('localhost', server.port, context=context)
self.addCleanup(h.close) self.addCleanup(h.close)
@ -1634,9 +1633,7 @@ class HTTPSTest(TestCase):
# The (valid) cert doesn't validate the HTTP hostname # The (valid) cert doesn't validate the HTTP hostname
import ssl import ssl
server = self.make_server(CERT_fakehostname) server = self.make_server(CERT_fakehostname)
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
context.load_verify_locations(CERT_fakehostname) context.load_verify_locations(CERT_fakehostname)
h = client.HTTPSConnection('localhost', server.port, context=context) h = client.HTTPSConnection('localhost', server.port, context=context)
with self.assertRaises(ssl.CertificateError): with self.assertRaises(ssl.CertificateError):

View File

@ -479,9 +479,9 @@ class NewIMAPSSLTests(NewIMAPTestsMixin, unittest.TestCase):
server_class = SecureTCPServer server_class = SecureTCPServer
def test_ssl_raises(self): def test_ssl_raises(self):
ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.verify_mode = ssl.CERT_REQUIRED self.assertEqual(ssl_context.verify_mode, ssl.CERT_REQUIRED)
ssl_context.check_hostname = True self.assertEqual(ssl_context.check_hostname, True)
ssl_context.load_verify_locations(CAFILE) ssl_context.load_verify_locations(CAFILE)
with self.assertRaisesRegex(ssl.CertificateError, with self.assertRaisesRegex(ssl.CertificateError,
@ -492,9 +492,7 @@ class NewIMAPSSLTests(NewIMAPTestsMixin, unittest.TestCase):
client.shutdown() client.shutdown()
def test_ssl_verified(self): def test_ssl_verified(self):
ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.verify_mode = ssl.CERT_REQUIRED
ssl_context.check_hostname = True
ssl_context.load_verify_locations(CAFILE) ssl_context.load_verify_locations(CAFILE)
_, server = self._setup(SimpleIMAPHandler) _, server = self._setup(SimpleIMAPHandler)
@ -871,9 +869,7 @@ class ThreadedNetworkedTestsSSL(ThreadedNetworkedTests):
@reap_threads @reap_threads
def test_ssl_verified(self): def test_ssl_verified(self):
ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.verify_mode = ssl.CERT_REQUIRED
ssl_context.check_hostname = True
ssl_context.load_verify_locations(CAFILE) ssl_context.load_verify_locations(CAFILE)
with self.assertRaisesRegex( with self.assertRaisesRegex(
@ -953,7 +949,9 @@ class RemoteIMAP_SSLTest(RemoteIMAPTest):
pass pass
def create_ssl_context(self): def create_ssl_context(self):
ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
ssl_context.load_cert_chain(CERTFILE) ssl_context.load_cert_chain(CERTFILE)
return ssl_context return ssl_context

View File

@ -1792,7 +1792,7 @@ class HTTPHandlerTest(BaseTest):
else: else:
here = os.path.dirname(__file__) here = os.path.dirname(__file__)
localhost_cert = os.path.join(here, "keycert.pem") localhost_cert = os.path.join(here, "keycert.pem")
sslctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) sslctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
sslctx.load_cert_chain(localhost_cert) sslctx.load_cert_chain(localhost_cert)
context = ssl.create_default_context(cafile=localhost_cert) context = ssl.create_default_context(cafile=localhost_cert)

View File

@ -352,10 +352,10 @@ class TestPOP3Class(TestCase):
@requires_ssl @requires_ssl
def test_stls_context(self): def test_stls_context(self):
expected = b'+OK Begin TLS negotiation' expected = b'+OK Begin TLS negotiation'
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.load_verify_locations(CAFILE) ctx.load_verify_locations(CAFILE)
ctx.verify_mode = ssl.CERT_REQUIRED self.assertEqual(ctx.verify_mode, ssl.CERT_REQUIRED)
ctx.check_hostname = True self.assertEqual(ctx.check_hostname, True)
with self.assertRaises(ssl.CertificateError): with self.assertRaises(ssl.CertificateError):
resp = self.client.stls(context=ctx) resp = self.client.stls(context=ctx)
self.client = poplib.POP3("localhost", self.server.port, timeout=3) self.client = poplib.POP3("localhost", self.server.port, timeout=3)
@ -392,7 +392,9 @@ class TestPOP3_SSLClass(TestPOP3Class):
self.assertIn('POP3_SSL', poplib.__all__) self.assertIn('POP3_SSL', poplib.__all__)
def test_context(self): def test_context(self):
ctx = ssl.SSLContext(ssl.PROTOCOL_TLSv1) ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host, self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host,
self.server.port, keyfile=CERTFILE, context=ctx) self.server.port, keyfile=CERTFILE, context=ctx)
self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host, self.assertRaises(ValueError, poplib.POP3_SSL, self.server.host,

View File

@ -25,7 +25,9 @@ class SmtpTest(unittest.TestCase):
def test_connect_starttls(self): def test_connect_starttls(self):
support.get_attribute(smtplib, 'SMTP_SSL') support.get_attribute(smtplib, 'SMTP_SSL')
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
with support.transient_internet(self.testServer): with support.transient_internet(self.testServer):
server = smtplib.SMTP(self.testServer, self.remotePort) server = smtplib.SMTP(self.testServer, self.remotePort)
try: try:
@ -58,7 +60,9 @@ class SmtpSSLTest(unittest.TestCase):
server.quit() server.quit()
def test_connect_using_sslcontext(self): def test_connect_using_sslcontext(self):
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23) context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
context.check_hostname = False
context.verify_mode = ssl.CERT_NONE
support.get_attribute(smtplib, 'SMTP_SSL') support.get_attribute(smtplib, 'SMTP_SSL')
with support.transient_internet(self.testServer): with support.transient_internet(self.testServer):
server = smtplib.SMTP_SSL(self.testServer, self.remotePort, context=context) server = smtplib.SMTP_SSL(self.testServer, self.remotePort, context=context)

File diff suppressed because it is too large Load Diff

View File

@ -594,7 +594,7 @@ class TestUrlopen(unittest.TestCase):
def cb_sni(ssl_sock, server_name, initial_context): def cb_sni(ssl_sock, server_name, initial_context):
nonlocal sni_name nonlocal sni_name
sni_name = server_name sni_name = server_name
context = ssl.SSLContext(ssl.PROTOCOL_TLSv1) context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.set_servername_callback(cb_sni) context.set_servername_callback(cb_sni)
handler = self.start_https_server(context=context, certfile=CERT_localhost) handler = self.start_https_server(context=context, certfile=CERT_localhost)
context = ssl.create_default_context(cafile=CERT_localhost) context = ssl.create_default_context(cafile=CERT_localhost)

View File

@ -0,0 +1 @@
Prefer PROTOCOL_TLS_CLIENT and PROTOCOL_TLS_SERVER protocols for SSLContext.