bpo-28414: ssl module idna test (#5395) · python/cpython@66e5742
@@ -105,6 +105,7 @@ def data_file(*name):
105105SIGNING_CA = data_file("capath", "ceff1710.0")
106106# cert with all kinds of subject alt names
107107ALLSANFILE = data_file("allsans.pem")
108+IDNSANSFILE = data_file("idnsans.pem")
108109109110REMOTE_HOST = "self-signed.pythontest.net"
110111@@ -1612,7 +1613,6 @@ def test_error_types(self):
161216131613161416141615class SimpleBackgroundTests(unittest.TestCase):
1615-16161616"""Tests that connect to a simple server running in the background"""
1617161716181618def setUp(self):
@@ -2630,6 +2630,70 @@ def test_dual_rsa_ecc(self):
26302630cipher = s.cipher()[0].split('-')
26312631self.assertTrue(cipher[:2], ('ECDHE', 'ECDSA'))
263226322633+def test_check_hostname_idn(self):
2634+if support.verbose:
2635+sys.stdout.write("\n")
2636+2637+server_context = ssl.SSLContext(ssl.PROTOCOL_TLS)
2638+server_context.load_cert_chain(IDNSANSFILE)
2639+2640+context = ssl.SSLContext(ssl.PROTOCOL_TLS)
2641+context.verify_mode = ssl.CERT_REQUIRED
2642+context.check_hostname = True
2643+context.load_verify_locations(SIGNING_CA)
2644+2645+# correct hostname should verify, when specified in several
2646+# different ways
2647+idn_hostnames = [
2648+ ('könig.idn.pythontest.net',
2649+'könig.idn.pythontest.net',),
2650+ ('xn--knig-5qa.idn.pythontest.net',
2651+'xn--knig-5qa.idn.pythontest.net'),
2652+ (b'xn--knig-5qa.idn.pythontest.net',
2653+b'xn--knig-5qa.idn.pythontest.net'),
2654+2655+ ('königsgäßchen.idna2003.pythontest.net',
2656+'königsgäßchen.idna2003.pythontest.net'),
2657+ ('xn--knigsgsschen-lcb0w.idna2003.pythontest.net',
2658+'xn--knigsgsschen-lcb0w.idna2003.pythontest.net'),
2659+ (b'xn--knigsgsschen-lcb0w.idna2003.pythontest.net',
2660+b'xn--knigsgsschen-lcb0w.idna2003.pythontest.net'),
2661+ ]
2662+for server_hostname, expected_hostname in idn_hostnames:
2663+server = ThreadedEchoServer(context=server_context, chatty=True)
2664+with server:
2665+with context.wrap_socket(socket.socket(),
2666+server_hostname=server_hostname) as s:
2667+self.assertEqual(s.server_hostname, expected_hostname)
2668+s.connect((HOST, server.port))
2669+cert = s.getpeercert()
2670+self.assertEqual(s.server_hostname, expected_hostname)
2671+self.assertTrue(cert, "Can't get peer certificate.")
2672+2673+with ssl.SSLSocket(socket.socket(),
2674+server_hostname=server_hostname) as s:
2675+s.connect((HOST, server.port))
2676+s.getpeercert()
2677+self.assertEqual(s.server_hostname, expected_hostname)
2678+2679+# bug https://bugs.python.org/issue28414
2680+# IDNA 2008 deviations are broken
2681+idna2008 = 'xn--knigsgchen-b4a3dun.idna2008.pythontest.net'
2682+server = ThreadedEchoServer(context=server_context, chatty=True)
2683+with server:
2684+with self.assertRaises(UnicodeError):
2685+with context.wrap_socket(socket.socket(),
2686+server_hostname=idna2008) as s:
2687+s.connect((HOST, server.port))
2688+2689+# incorrect hostname should raise an exception
2690+server = ThreadedEchoServer(context=server_context, chatty=True)
2691+with server:
2692+with context.wrap_socket(socket.socket(),
2693+server_hostname="python.example.org") as s:
2694+with self.assertRaises(ssl.CertificateError):
2695+s.connect((HOST, server.port))
2696+26332697def test_wrong_cert(self):
26342698"""Connecting when the server rejects the client's certificate
26352699