@@ -2862,11 +2862,19 @@ def run(self):
28622862 cert = self .sslconn .getpeercert ()
28632863 self .write (repr (cert ).encode ("us-ascii" ) + b"\n " )
28642864 elif stripped == b'VERIFIEDCHAIN' :
2865- certs = self .sslconn ._sslobj .get_verified_chain ()
2866- self .write (len (certs ).to_bytes (1 , "big" ) + b"\n " )
2865+ try :
2866+ certs = self .sslconn .get_verified_chain ()
2867+ except Exception as e :
2868+ self .write (repr (e ).encode ("us-ascii" ) + b"\n " )
2869+ else :
2870+ self .write (len (certs ).to_bytes (1 , "big" ) + b"\n " )
28672871 elif stripped == b'UNVERIFIEDCHAIN' :
2868- certs = self .sslconn ._sslobj .get_unverified_chain ()
2869- self .write (len (certs ).to_bytes (1 , "big" ) + b"\n " )
2872+ try :
2873+ certs = self .sslconn .get_unverified_chain ()
2874+ except Exception as e :
2875+ self .write (repr (e ).encode ("us-ascii" ) + b"\n " )
2876+ else :
2877+ self .write (len (certs ).to_bytes (1 , "big" ) + b"\n " )
28702878 else :
28712879 if (support .verbose and
28722880 self .server .connectionchatty ):
@@ -5345,6 +5353,66 @@ def test_internal_chain_server(self):
53455353 res = s .recv (1024 )
53465354 self .assertEqual (res , b'\x02 \n ' )
53475355
5356+ def test_internal_chain_server_resumed_session (self ):
5357+ # A session resumed from a ticket stores the client's certificate
5358+ # but not the chain it was sent with.
5359+ for version in ssl .TLSVersion .TLSv1_2 , ssl .TLSVersion .TLSv1_3 :
5360+ if not has_tls_version (version ):
5361+ continue
5362+ with self .subTest (version = version .name ):
5363+ self .check_chain_server_resumed_session (version )
5364+
5365+ def check_chain_server_resumed_session (self , version ):
5366+ client_context , server_context , hostname = testing_context ()
5367+ client_context .load_cert_chain (SIGNED_CERTFILE )
5368+ server_context .verify_mode = ssl .CERT_REQUIRED
5369+ client_context .minimum_version = version
5370+ client_context .maximum_version = version
5371+
5372+ server = ThreadedEchoServer (context = server_context , chatty = False )
5373+ with server :
5374+ with client_context .wrap_socket (
5375+ socket .socket (),
5376+ server_hostname = hostname
5377+ ) as s :
5378+ s .connect ((HOST , server .port ))
5379+ s .write (b'UNVERIFIEDCHAIN\n ' )
5380+ res = s .recv (1024 )
5381+ self .assertEqual (res , b'\x02 \n ' )
5382+ # TLS 1.3 sends the ticket after the handshake, so only
5383+ # get the session once data was received.
5384+ session = s .session
5385+ self .assertTrue (session .has_ticket )
5386+ with client_context .wrap_socket (
5387+ socket .socket (),
5388+ server_hostname = hostname ,
5389+ session = session
5390+ ) as s :
5391+ s .connect ((HOST , server .port ))
5392+ self .assertTrue (s .session_reused )
5393+ s .write (b'UNVERIFIEDCHAIN\n ' )
5394+ res = s .recv (1024 )
5395+ self .assertEqual (res , b'\x01 \n ' )
5396+ # The verified chain is not stored with the session at all.
5397+ s .write (b'VERIFIEDCHAIN\n ' )
5398+ res = s .recv (1024 )
5399+ self .assertEqual (res , b'\x00 \n ' )
5400+
5401+ def test_internal_chain_server_no_client_cert (self ):
5402+ client_context , server_context , hostname = testing_context ()
5403+ server_context .verify_mode = ssl .CERT_OPTIONAL
5404+
5405+ server = ThreadedEchoServer (context = server_context , chatty = False )
5406+ with server :
5407+ with client_context .wrap_socket (
5408+ socket .socket (),
5409+ server_hostname = hostname
5410+ ) as s :
5411+ s .connect ((HOST , server .port ))
5412+ s .write (b'UNVERIFIEDCHAIN\n ' )
5413+ res = s .recv (1024 )
5414+ self .assertEqual (res , b'\x00 \n ' )
5415+
53485416
53495417class TestSSLDebug (unittest .TestCase ):
53505418
0 commit comments