@@ -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" )
108109
109110REMOTE_HOST = "self-signed.pythontest.net"
110111
@@ -1612,7 +1613,6 @@ def test_error_types(self):
16121613
16131614
16141615class SimpleBackgroundTests (unittest .TestCase ):
1615-
16161616 """Tests that connect to a simple server running in the background"""
16171617
16181618 def setUp (self ):
@@ -2630,6 +2630,70 @@ def test_dual_rsa_ecc(self):
26302630 cipher = s .cipher ()[0 ].split ('-' )
26312631 self .assertTrue (cipher [:2 ], ('ECDHE' , 'ECDSA' ))
26322632
2633+ 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+
26332697 def test_wrong_cert (self ):
26342698 """Connecting when the server rejects the client's certificate
26352699
0 commit comments