mirror of
https://github.com/python/cpython.git
synced 2025-11-03 03:22:27 +00:00
bpo-36076: Add SNI support to ssl.get_server_certificate. (GH-16820)
Many servers in the cloud environment require SNI to be used during the SSL/TLS handshake, therefore it is not possible to fetch their certificates using the ssl.get_server_certificate interface. This change adds an additional optional hostname argument that can be used to set the SNI. Note that it is intentionally a separate argument instead of using the host part of the addr tuple, because one might want to explicitly fetch the default certificate or fetch a certificate from a specific IP address with the specified SNI hostname. A separate argument also works better for backwards compatibility. Automerge-Triggered-By: GH:tiran
This commit is contained in:
parent
2798f247c0
commit
49fdf118ae
4 changed files with 28 additions and 2 deletions
|
|
@ -1962,7 +1962,9 @@ class SimpleBackgroundTests(unittest.TestCase):
|
|||
"""Tests that connect to a simple server running in the background"""
|
||||
|
||||
def setUp(self):
|
||||
server = ThreadedEchoServer(SIGNED_CERTFILE)
|
||||
self.server_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
|
||||
self.server_context.load_cert_chain(SIGNED_CERTFILE)
|
||||
server = ThreadedEchoServer(context=self.server_context)
|
||||
self.server_addr = (HOST, server.port)
|
||||
server.__enter__()
|
||||
self.addCleanup(server.__exit__, None, None, None)
|
||||
|
|
@ -2143,6 +2145,28 @@ class SimpleBackgroundTests(unittest.TestCase):
|
|||
def test_get_server_certificate(self):
|
||||
_test_get_server_certificate(self, *self.server_addr, cert=SIGNING_CA)
|
||||
|
||||
@needs_sni
|
||||
def test_get_server_certificate_sni(self):
|
||||
host, port = self.server_addr
|
||||
server_names = []
|
||||
|
||||
# We store servername_cb arguments to make sure they match the host
|
||||
def servername_cb(ssl_sock, server_name, initial_context):
|
||||
server_names.append(server_name)
|
||||
self.server_context.set_servername_callback(servername_cb)
|
||||
|
||||
pem = ssl.get_server_certificate((host, port))
|
||||
if not pem:
|
||||
self.fail("No server certificate on %s:%s!" % (host, port))
|
||||
|
||||
pem = ssl.get_server_certificate((host, port), ca_certs=SIGNING_CA)
|
||||
if not pem:
|
||||
self.fail("No server certificate on %s:%s!" % (host, port))
|
||||
if support.verbose:
|
||||
sys.stdout.write("\nVerified certificate for %s:%s is\n%s\n" % (host, port, pem))
|
||||
|
||||
self.assertEqual(server_names, [host, host])
|
||||
|
||||
def test_get_server_certificate_fail(self):
|
||||
# Connection failure crashes ThreadedEchoServer, so run this in an
|
||||
# independent test method
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue