import unittest import ssl # Assuming security.encrypt is accessible in the Python path # If not, adjust the import based on project structure (e.g., using relative imports) try: from security.encrypt import create_tls_context except ImportError: # Handle cases where the module might be run directly or path issues import sys import os # Add the project root to the path if necessary # sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../..'))) # from security.encrypt import create_tls_context # This might require more robust path handling depending on the test runner setup print("Warning: Could not import 'security.encrypt'. Ensure PYTHONPATH is set correctly.") # As a fallback for simple cases, try importing directly if tests are run from root try: from encrypt import create_tls_context except ImportError: raise ImportError("Failed to import create_tls_context from security.encrypt") class TestTlsConfig(unittest.TestCase): def test_client_context_requires_tls1_3(self): """Verify client context minimum version is TLS 1.3""" context = create_tls_context(purpose=ssl.Purpose.CLIENT_AUTH) self.assertEqual(context.minimum_version, ssl.TLSVersion.TLSv1_3, "Client context should require TLS 1.3") # Check that older protocols are implicitly disabled by setting minimum_version self.assertTrue(context.options & ssl.OP_NO_TLSv1_2, "TLS 1.2 should be disabled") self.assertTrue(context.options & ssl.OP_NO_TLSv1_1, "TLS 1.1 should be disabled") self.assertTrue(context.options & ssl.OP_NO_TLSv1, "TLS 1.0 should be disabled") self.assertTrue(context.options & ssl.OP_NO_SSLv3, "SSLv3 should be disabled") def test_server_context_requires_tls1_3(self): """Verify server context minimum version is TLS 1.3""" context = create_tls_context(purpose=ssl.Purpose.SERVER_AUTH) self.assertEqual(context.minimum_version, ssl.TLSVersion.TLSv1_3, "Server context should require TLS 1.3") # Check that older protocols are implicitly disabled by setting minimum_version self.assertTrue(context.options & ssl.OP_NO_TLSv1_2, "TLS 1.2 should be disabled") self.assertTrue(context.options & ssl.OP_NO_TLSv1_1, "TLS 1.1 should be disabled") self.assertTrue(context.options & ssl.OP_NO_TLSv1, "TLS 1.0 should be disabled") self.assertTrue(context.options & ssl.OP_NO_SSLv3, "SSLv3 should be disabled") # --- Negative Test Cases --- def test_server_rejects_tls1_2_client(self): """Verify server context rejects connection attempts using only TLS 1.2""" server_context = create_tls_context(purpose=ssl.Purpose.CLIENT_AUTH) # NOTE: Requires setting up a test server and client socket pair. # The client context should be configured to ONLY allow TLS 1.2: # client_context_tls12 = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) # client_context_tls12.maximum_version = ssl.TLSVersion.TLSv1_2 # client_context_tls12.minimum_version = ssl.TLSVersion.TLSv1_2 # Force TLS 1.2 # ... setup sockets, wrap them, attempt handshake ... with self.assertRaises(ssl.SSLError, msg="Server should reject TLS 1.2 connection"): # Placeholder for actual handshake attempt simulation # e.g., client_socket.do_handshake() # In a real test, replace the following line with actual socket/handshake code raise ssl.SSLError("Simulated handshake failure for TLS 1.2") # Simulate failure def test_client_rejects_tls1_2_server(self): """Verify client context rejects connection attempts to a TLS 1.2 server""" client_context = create_tls_context(purpose=ssl.Purpose.SERVER_AUTH) # NOTE: Requires setting up a test server and client socket pair. # The server context should be configured to ONLY allow TLS 1.2: # server_context_tls12 = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) # server_context_tls12.maximum_version = ssl.TLSVersion.TLSv1_2 # server_context_tls12.minimum_version = ssl.TLSVersion.TLSv1_2 # Force TLS 1.2 # ... setup sockets, wrap them, attempt handshake ... with self.assertRaises(ssl.SSLError, msg="Client should reject connection to TLS 1.2 server"): # Placeholder for actual handshake attempt simulation # e.g., client_socket.do_handshake() # In a real test, replace the following line with actual socket/handshake code raise ssl.SSLError("Simulated handshake failure for TLS 1.2") # Simulate failure # Add similar tests for TLS 1.1, TLS 1.0, SSLv3 if deemed necessary, # although rejecting TLS 1.2 often covers the older ones implicitly. # Add more tests here if specific ciphers, cert loading, or other options were configured # For example: # def test_specific_cipher_suite_enabled(self): # context = create_tls_context() # enabled_ciphers = [cipher['name'] for cipher in context.get_ciphers()] # self.assertIn('EXPECTED-CIPHER-SUITE-NAME', enabled_ciphers) if __name__ == '__main__': unittest.main()