@@ -263,7 +263,9 @@ def utc_offset(): #NOTE: ignore issues like #1647654
263263
264264def test_wrap_socket (sock , * ,
265265 cert_reqs = ssl .CERT_NONE , ca_certs = None ,
266- ciphers = None , certfile = None , keyfile = None ,
266+ ciphers = None , ciphersuites = None ,
267+ min_version = None , max_version = None ,
268+ certfile = None , keyfile = None ,
267269 ** kwargs ):
268270 if not kwargs .get ("server_side" ):
269271 kwargs ["server_hostname" ] = SIGNED_CERTFILE_HOSTNAME
@@ -280,6 +282,12 @@ def test_wrap_socket(sock, *,
280282 context .load_cert_chain (certfile , keyfile )
281283 if ciphers is not None :
282284 context .set_ciphers (ciphers )
285+ if ciphersuites is not None :
286+ context .set_ciphersuites (ciphersuites )
287+ if min_version is not None :
288+ context .minimum_version = min_version
289+ if max_version is not None :
290+ context .maximum_version = max_version
283291 return context .wrap_socket (sock , ** kwargs )
284292
285293
@@ -2238,6 +2246,68 @@ def test_transport_eof(self):
22382246 self .assertRaises (ssl .SSLEOFError , sslobj .read )
22392247
22402248
2249+ @unittest .skipUnless (has_tls_version ('TLSv1_3' ), "TLS 1.3 is not available" )
2250+ class SimpleBackgroundTestsTLS_1_3 (unittest .TestCase ):
2251+ """Tests that connect to a simple server running in the background."""
2252+
2253+ def setUp (self ):
2254+ server_ctx = ssl .SSLContext (ssl .PROTOCOL_TLS_SERVER )
2255+ ciphers = [cipher ['name' ] for cipher in server_ctx .get_ciphers ()
2256+ if cipher ['protocol' ] == 'TLSv1.3' ]
2257+
2258+ if not ciphers :
2259+ self .skipTest ("No cipher supports TLSv1.3" )
2260+
2261+ self .matching_cipher = ciphers [0 ]
2262+ # Some tests need at least two ciphers, and are responsible
2263+ # to skip themselves if matching_cipher == mismatched_cipher.
2264+ self .mismatched_cipher = ciphers [- 1 ]
2265+
2266+ server_ctx .set_ciphersuites (self .matching_cipher )
2267+ server_ctx .load_cert_chain (SIGNED_CERTFILE )
2268+ server = ThreadedEchoServer (context = server_ctx )
2269+ self .enterContext (server )
2270+ self .server_addr = (HOST , server .port )
2271+
2272+ def test_ciphersuites (self ):
2273+ # Test unrecognized TLS 1.3 cipher suite name
2274+ with (
2275+ socket .socket (socket .AF_INET ) as sock ,
2276+ self .assertRaisesRegex (ssl .SSLError ,
2277+ "No cipher suite can be selected" )
2278+ ):
2279+ test_wrap_socket (sock , cert_reqs = ssl .CERT_NONE ,
2280+ ciphersuites = "XXX" ,
2281+ min_version = ssl .TLSVersion .TLSv1_3 )
2282+
2283+ # Test successful TLS 1.3 handshake
2284+ with test_wrap_socket (socket .socket (socket .AF_INET ),
2285+ cert_reqs = ssl .CERT_NONE ,
2286+ ciphersuites = self .matching_cipher ,
2287+ min_version = ssl .TLSVersion .TLSv1_3 ) as s :
2288+ s .connect (self .server_addr )
2289+ self .assertEqual (s .cipher ()[0 ], self .matching_cipher )
2290+
2291+ def test_ciphersuite_downgrade (self ):
2292+ with test_wrap_socket (socket .socket (socket .AF_INET ),
2293+ cert_reqs = ssl .CERT_NONE ,
2294+ ciphersuites = self .matching_cipher ,
2295+ min_version = ssl .TLSVersion .TLSv1_2 ,
2296+ max_version = ssl .TLSVersion .TLSv1_2 ) as s :
2297+ s .connect (self .server_addr )
2298+ self .assertEqual (s .cipher ()[1 ], 'TLSv1.2' )
2299+
2300+ def test_ciphersuite_mismatch (self ):
2301+ if self .matching_cipher == self .mismatched_cipher :
2302+ self .skipTest ("Multiple TLS 1.3 ciphers are not available" )
2303+
2304+ with test_wrap_socket (socket .socket (socket .AF_INET ),
2305+ cert_reqs = ssl .CERT_NONE ,
2306+ ciphersuites = self .mismatched_cipher ,
2307+ min_version = ssl .TLSVersion .TLSv1_3 ) as s :
2308+ self .assertRaises (ssl .SSLError , s .connect , self .server_addr )
2309+
2310+
22412311@support .requires_resource ('network' )
22422312class NetworkedTests (unittest .TestCase ):
22432313
0 commit comments