5151CAN_GET_SELECTED_OPENSSL_GROUP = ssl .OPENSSL_VERSION_INFO >= (3 , 2 )
5252CAN_IGNORE_UNKNOWN_OPENSSL_GROUPS = ssl .OPENSSL_VERSION_INFO >= (3 , 3 )
5353CAN_GET_AVAILABLE_OPENSSL_GROUPS = ssl .OPENSSL_VERSION_INFO >= (3 , 5 )
54+ CAN_IGNORE_UNKNOWN_OPENSSL_SIGALGS = ssl .OPENSSL_VERSION_INFO >= (3 , 3 )
55+ CAN_GET_SELECTED_OPENSSL_SIGALG = ssl .OPENSSL_VERSION_INFO >= (3 , 5 )
5456PY_SSL_DEFAULT_CIPHERS = sysconfig .get_config_var ('PY_SSL_DEFAULT_CIPHERS' )
5557
5658PROTOCOL_TO_TLS_VERSION = {}
@@ -294,7 +296,8 @@ def test_wrap_socket(sock, *,
294296USE_SAME_TEST_CONTEXT = False
295297_TEST_CONTEXT = None
296298
297- def testing_context (server_cert = SIGNED_CERTFILE , * , server_chain = True ):
299+ def testing_context (server_cert = SIGNED_CERTFILE , * , server_chain = True ,
300+ client_cert = None ):
298301 """Create context
299302
300303 client_context, server_context, hostname = testing_context()
@@ -321,6 +324,10 @@ def testing_context(server_cert=SIGNED_CERTFILE, *, server_chain=True):
321324 if server_chain :
322325 server_context .load_verify_locations (SIGNING_CA )
323326
327+ if client_cert :
328+ client_context .load_cert_chain (client_cert )
329+ server_context .verify_mode = ssl .CERT_REQUIRED
330+
324331 if USE_SAME_TEST_CONTEXT :
325332 if _TEST_CONTEXT is not None :
326333 _TEST_CONTEXT = client_context , server_context , hostname
@@ -990,6 +997,22 @@ def test_get_groups(self):
990997 self .assertNotIn ('P-256' , ctx .get_groups ())
991998 self .assertIn ('P-256' , ctx .get_groups (include_aliases = True ))
992999
1000+ def test_set_sigalgs (self ):
1001+ ctx = ssl .create_default_context ()
1002+
1003+ self .assertIsNone (ctx .set_client_sigalgs ('rsa_pss_rsae_sha256' ))
1004+ self .assertIsNone (ctx .set_server_sigalgs ('rsa_pss_rsae_sha256' ))
1005+
1006+ self .assertRaises (ssl .SSLError , ctx .set_client_sigalgs ,
1007+ 'rsa_pss_rsae_sha256:foo' )
1008+ self .assertRaises (ssl .SSLError , ctx .set_server_sigalgs ,
1009+ 'rsa_pss_rsae_sha256:foo' )
1010+
1011+ # Ignoring unknown sigalgs is only supported since OpenSSL 3.3.
1012+ if CAN_IGNORE_UNKNOWN_OPENSSL_SIGALGS :
1013+ self .assertIsNone (ctx .set_client_sigalgs ('rsa_pss_rsae_sha256:?foo' ))
1014+ self .assertIsNone (ctx .set_server_sigalgs ('rsa_pss_rsae_sha256:?foo' ))
1015+
9931016 def test_options (self ):
9941017 # Test default SSLContext options
9951018 ctx = ssl .SSLContext (ssl .PROTOCOL_TLS_CLIENT )
@@ -2814,6 +2837,9 @@ def server_params_test(client_context, server_context, indata=b"FOO\n",
28142837 })
28152838 if CAN_GET_SELECTED_OPENSSL_GROUP :
28162839 stats .update ({'group' : s .group ()})
2840+ if CAN_GET_SELECTED_OPENSSL_SIGALG :
2841+ stats .update ({'client_sigalg' : s .client_sigalg ()})
2842+ stats .update ({'server_sigalg' : s .server_sigalg ()})
28172843 s .close ()
28182844 stats ['server_alpn_protocols' ] = server .selected_alpn_protocols
28192845 stats ['server_shared_ciphers' ] = server .shared_ciphers
@@ -4273,6 +4299,63 @@ def test_groups(self):
42734299 chatty = True , connectionchatty = True ,
42744300 sni_name = hostname )
42754301
4302+ def test_client_sigalgs (self ):
4303+ # no mutual auth, so cient_sigalg should be None
4304+ client_context , server_context , hostname = testing_context ()
4305+ stats = server_params_test (client_context , server_context ,
4306+ chatty = True , connectionchatty = True ,
4307+ sni_name = hostname )
4308+ if CAN_GET_SELECTED_OPENSSL_SIGALG :
4309+ self .assertIsNone (stats ['client_sigalg' ])
4310+
4311+ # server auto, client rsa_pss_rsae_sha384
4312+ client_context , server_context , hostname = \
4313+ testing_context (client_cert = SIGNED_CERTFILE )
4314+ client_context .set_client_sigalgs ("rsa_pss_rsae_sha384" )
4315+ stats = server_params_test (client_context , server_context ,
4316+ chatty = True , connectionchatty = True ,
4317+ sni_name = hostname )
4318+ if CAN_GET_SELECTED_OPENSSL_SIGALG :
4319+ self .assertEqual (stats ['client_sigalg' ], "rsa_pss_rsae_sha384" )
4320+
4321+ # server / client sigalg mismatch
4322+ client_context , server_context , hostname = \
4323+ testing_context (client_cert = SIGNED_CERTFILE )
4324+ client_context .set_client_sigalgs ("rsa_pss_rsae_sha256" )
4325+ server_context .set_client_sigalgs ("rsa_pss_rsae_sha384" )
4326+ with self .assertRaises (ssl .SSLError ):
4327+ server_params_test (client_context , server_context ,
4328+ chatty = True , connectionchatty = True ,
4329+ sni_name = hostname )
4330+
4331+ def test_server_sigalgs (self ):
4332+ # server rsa_pss_rsae_sha384, client auto
4333+ client_context , server_context , hostname = testing_context ()
4334+ server_context .set_server_sigalgs ("rsa_pss_rsae_sha384" )
4335+ stats = server_params_test (client_context , server_context ,
4336+ chatty = True , connectionchatty = True ,
4337+ sni_name = hostname )
4338+ if CAN_GET_SELECTED_OPENSSL_SIGALG :
4339+ self .assertEqual (stats ['server_sigalg' ], "rsa_pss_rsae_sha384" )
4340+
4341+ # server auto, client rsa_pss_rsae_sha384
4342+ client_context , server_context , hostname = testing_context ()
4343+ client_context .set_server_sigalgs ("rsa_pss_rsae_sha384" )
4344+ stats = server_params_test (client_context , server_context ,
4345+ chatty = True , connectionchatty = True ,
4346+ sni_name = hostname )
4347+ if CAN_GET_SELECTED_OPENSSL_SIGALG :
4348+ self .assertEqual (stats ['server_sigalg' ], "rsa_pss_rsae_sha384" )
4349+
4350+ # server / client sigalg mismatch
4351+ client_context , server_context , hostname = testing_context ()
4352+ client_context .set_server_sigalgs ("rsa_pss_rsae_sha256" )
4353+ server_context .set_server_sigalgs ("rsa_pss_rsae_sha384" )
4354+ with self .assertRaises (ssl .SSLError ):
4355+ server_params_test (client_context , server_context ,
4356+ chatty = True , connectionchatty = True ,
4357+ sni_name = hostname )
4358+
42764359 def test_selected_alpn_protocol (self ):
42774360 # selected_alpn_protocol() is None unless ALPN is used.
42784361 client_context , server_context , hostname = testing_context ()
0 commit comments