@@ -3017,11 +3017,19 @@ def run(self):
30173017 cert = self .sslconn .getpeercert ()
30183018 self .write (repr (cert ).encode ("us-ascii" ) + b"\n " )
30193019 elif stripped == b'VERIFIEDCHAIN' :
3020- certs = self .sslconn ._sslobj .get_verified_chain ()
3021- self .write (len (certs ).to_bytes (1 , "big" ) + b"\n " )
3020+ try :
3021+ certs = self .sslconn .get_verified_chain ()
3022+ except Exception as e :
3023+ self .write (repr (e ).encode ("us-ascii" ) + b"\n " )
3024+ else :
3025+ self .write (len (certs ).to_bytes (1 , "big" ) + b"\n " )
30223026 elif stripped == b'UNVERIFIEDCHAIN' :
3023- certs = self .sslconn ._sslobj .get_unverified_chain ()
3024- self .write (len (certs ).to_bytes (1 , "big" ) + b"\n " )
3027+ try :
3028+ certs = self .sslconn .get_unverified_chain ()
3029+ except Exception as e :
3030+ self .write (repr (e ).encode ("us-ascii" ) + b"\n " )
3031+ else :
3032+ self .write (len (certs ).to_bytes (1 , "big" ) + b"\n " )
30253033 else :
30263034 if (support .verbose and
30273035 self .server .connectionchatty ):
@@ -5701,6 +5709,66 @@ def test_internal_chain_server(self):
57015709 res = s .recv (1024 )
57025710 self .assertEqual (res , b'\x02 \n ' )
57035711
5712+ def test_internal_chain_server_resumed_session (self ):
5713+ # A session resumed from a ticket stores the client's certificate
5714+ # but not the chain it was sent with.
5715+ for version in ssl .TLSVersion .TLSv1_2 , ssl .TLSVersion .TLSv1_3 :
5716+ if not has_tls_version (version ):
5717+ continue
5718+ with self .subTest (version = version .name ):
5719+ self .check_chain_server_resumed_session (version )
5720+
5721+ def check_chain_server_resumed_session (self , version ):
5722+ client_context , server_context , hostname = testing_context ()
5723+ client_context .load_cert_chain (SIGNED_CERTFILE )
5724+ server_context .verify_mode = ssl .CERT_REQUIRED
5725+ client_context .minimum_version = version
5726+ client_context .maximum_version = version
5727+
5728+ server = ThreadedEchoServer (context = server_context , chatty = False )
5729+ with server :
5730+ with client_context .wrap_socket (
5731+ socket .socket (),
5732+ server_hostname = hostname
5733+ ) as s :
5734+ s .connect ((HOST , server .port ))
5735+ s .write (b'UNVERIFIEDCHAIN\n ' )
5736+ res = s .recv (1024 )
5737+ self .assertEqual (res , b'\x02 \n ' )
5738+ # TLS 1.3 sends the ticket after the handshake, so only
5739+ # get the session once data was received.
5740+ session = s .session
5741+ self .assertTrue (session .has_ticket )
5742+ with client_context .wrap_socket (
5743+ socket .socket (),
5744+ server_hostname = hostname ,
5745+ session = session
5746+ ) as s :
5747+ s .connect ((HOST , server .port ))
5748+ self .assertTrue (s .session_reused )
5749+ s .write (b'UNVERIFIEDCHAIN\n ' )
5750+ res = s .recv (1024 )
5751+ self .assertEqual (res , b'\x01 \n ' )
5752+ # The verified chain is not stored with the session at all.
5753+ s .write (b'VERIFIEDCHAIN\n ' )
5754+ res = s .recv (1024 )
5755+ self .assertEqual (res , b'\x00 \n ' )
5756+
5757+ def test_internal_chain_server_no_client_cert (self ):
5758+ client_context , server_context , hostname = testing_context ()
5759+ server_context .verify_mode = ssl .CERT_OPTIONAL
5760+
5761+ server = ThreadedEchoServer (context = server_context , chatty = False )
5762+ with server :
5763+ with client_context .wrap_socket (
5764+ socket .socket (),
5765+ server_hostname = hostname
5766+ ) as s :
5767+ s .connect ((HOST , server .port ))
5768+ s .write (b'UNVERIFIEDCHAIN\n ' )
5769+ res = s .recv (1024 )
5770+ self .assertEqual (res , b'\x00 \n ' )
5771+
57045772
57055773class TestSSLDebug (unittest .TestCase ):
57065774
0 commit comments