def enable_ecdh_cipher_suites(tls_version: TlsVersionEnum, ssl_client: SslClient) -> None: """Set the elliptic curve cipher suites.""" if tls_version == TlsVersionEnum.TLS_1_3: # Cipher suites source: https://tools.ietf.org/html/rfc8446#appendix-B.4 ssl_client.set_ciphersuites( "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:" "TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256") else: # TLSv1.2; cipher suite source: https://www.openssl.org/docs/man1.0.2/man1/ciphers.html ssl_client.set_cipher_list("ECDH")
def get_all_cipher_suites(cls, tls_version: TlsVersionEnum) -> Set[CipherSuite]: """Get the list of cipher suites supported by OpenSSL for the given SSL/TLS version. """ if tls_version in [ TlsVersionEnum.SSL_2_0, TlsVersionEnum.SSL_3_0, TlsVersionEnum.TLS_1_0, TlsVersionEnum.TLS_1_1, ]: openssl_cipher_strings = cls._get_all_cipher_suites_with_legacy_openssl( tls_version) elif tls_version == TlsVersionEnum.TLS_1_2: # For TLS 1.2, we have to use both the legacy and modern OpenSSL to cover all cipher suites cipher_suites_from_legacy_openssl = cls._get_all_cipher_suites_with_legacy_openssl( tls_version) ssl_client_modern = SslClient( ssl_version=OpenSslVersionEnum(tls_version.value)) ssl_client_modern.set_cipher_list("ALL:COMPLEMENTOFALL:-PSK:-SRP") ssl_client_modern.set_ciphersuites( "") # Disable TLS 1.3 cipher suites cipher_suites_from_modern_openssl = set( ssl_client_modern.get_cipher_list()) # Combine the two sets of cipher suites openssl_cipher_strings = cipher_suites_from_legacy_openssl.union( cipher_suites_from_modern_openssl) elif tls_version == TlsVersionEnum.TLS_1_3: ssl_client_modern = SslClient( ssl_version=OpenSslVersionEnum(tls_version.value)) ssl_client_modern.set_cipher_list( "") # Disable NON-TLS-1.3 cipher suites ssl_client_modern.set_ciphersuites( "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:" "TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256" ) # Enable all TLS 1.3 cipher suites openssl_cipher_strings = set(ssl_client_modern.get_cipher_list()) else: raise ValueError("Should never happen") return { CipherSuite.from_openssl(cipher_str, tls_version) for cipher_str in openssl_cipher_strings }
def test_set_ciphersuites(self): # Given an SslClient for TLS 1.3 ssl_client = SslClient( ssl_version=OpenSslVersionEnum.TLSV1_3, ssl_verify=OpenSslVerifyEnum.NONE, ignore_client_authentication_requests=True, ) # With the default list of cipher disabled ssl_client.set_cipher_list("") # When setting a specific TLS 1.3 cipher suite as the list of supported ciphers ssl_client.set_ciphersuites("TLS_CHACHA20_POLY1305_SHA256") # That one cipher suite is the only one enabled ciphers = ssl_client.get_cipher_list() assert ["TLS_CHACHA20_POLY1305_SHA256"] == ciphers
def test_set_ciphersuites(self): # Given an SslClient for TLS 1.3 ssl_client = SslClient( ssl_version=OpenSslVersionEnum.TLSV1_3, ssl_verify=OpenSslVerifyEnum.NONE, ignore_client_authentication_requests=True, ) # With the default list of cipher disabled ssl_client.set_cipher_list('') # When setting a specific TLS 1.3 cipher suite as the list of supported ciphers ssl_client.set_ciphersuites('TLS_CHACHA20_POLY1305_SHA256') # That one cipher suite is the only one enabled ciphers = ssl_client.get_cipher_list() assert ['TLS_CHACHA20_POLY1305_SHA256'] == ciphers
def test_set_ciphersuites(self): # Given a server that supports TLS 1.3 with ModernOpenSslServer() as server: sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(5) sock.connect((server.hostname, server.port)) # And a client that only supports a specific TLS 1.3 cipher suite ssl_client = SslClient( ssl_version=OpenSslVersionEnum.TLSV1_3, underlying_socket=sock, ssl_verify=OpenSslVerifyEnum.NONE, ) ssl_client.set_ciphersuites("TLS_CHACHA20_POLY1305_SHA256") # When doing the TLS 1.3 handshake, it succeeds try: ssl_client.do_handshake() finally: ssl_client.shutdown() # And client's cipher suite was used assert "TLS_CHACHA20_POLY1305_SHA256" == ssl_client.get_current_cipher_name( )
def _parse_all_cipher_suites() -> Dict[TlsVersionEnum, Set[CipherSuite]]: tls_version_to_cipher_suites: Dict[TlsVersionEnum, Set[CipherSuite]] = {} for tls_version in [ TlsVersionEnum.SSL_2_0, TlsVersionEnum.SSL_3_0, TlsVersionEnum.TLS_1_0, TlsVersionEnum.TLS_1_1, ]: openssl_cipher_strings = _parse_all_cipher_suites_with_legacy_openssl(tls_version) tls_version_to_cipher_suites[tls_version] = set() for cipher_suite_openssl_name in openssl_cipher_strings: cipher_suite_rfc_name = _OPENSSL_TO_RFC_NAMES_MAPPING[tls_version][cipher_suite_openssl_name] tls_version_to_cipher_suites[tls_version].add( CipherSuite( name=cipher_suite_rfc_name, openssl_name=cipher_suite_openssl_name, is_anonymous=True if "anon" in cipher_suite_rfc_name else False, key_size=_RFC_NAME_TO_KEY_SIZE_MAPPING[cipher_suite_rfc_name], ) ) # For TLS 1.2, we have to use both the legacy and modern OpenSSL to cover all cipher suites cipher_suites_from_legacy_openssl = _parse_all_cipher_suites_with_legacy_openssl(TlsVersionEnum.TLS_1_2) ssl_client_modern = SslClient(ssl_version=OpenSslVersionEnum(TlsVersionEnum.TLS_1_2.value)) ssl_client_modern.set_cipher_list("ALL:COMPLEMENTOFALL:-PSK:-SRP") ssl_client_modern.set_ciphersuites("") # Disable TLS 1.3 cipher suites cipher_suites_from_modern_openssl = set(ssl_client_modern.get_cipher_list()) # Combine the two sets of cipher suites openssl_cipher_strings = cipher_suites_from_legacy_openssl.union(cipher_suites_from_modern_openssl) tls_version_to_cipher_suites[TlsVersionEnum.TLS_1_2] = set() for cipher_suite_openssl_name in openssl_cipher_strings: cipher_suite_rfc_name = _OPENSSL_TO_RFC_NAMES_MAPPING[TlsVersionEnum.TLS_1_2][cipher_suite_openssl_name] tls_version_to_cipher_suites[TlsVersionEnum.TLS_1_2].add( CipherSuite( name=cipher_suite_rfc_name, openssl_name=cipher_suite_openssl_name, is_anonymous=True if "anon" in cipher_suite_rfc_name else False, key_size=_RFC_NAME_TO_KEY_SIZE_MAPPING[cipher_suite_rfc_name], ) ) # TLS 1.3 ssl_client_modern = SslClient(ssl_version=OpenSslVersionEnum(TlsVersionEnum.TLS_1_3.value)) ssl_client_modern.set_cipher_list("") # Disable NON-TLS-1.3 cipher suites ssl_client_modern.set_ciphersuites( "TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:" "TLS_AES_128_CCM_SHA256:TLS_AES_128_CCM_8_SHA256" ) # Enable all TLS 1.3 cipher suites openssl_cipher_strings = set(ssl_client_modern.get_cipher_list()) tls_version_to_cipher_suites[TlsVersionEnum.TLS_1_3] = { CipherSuite( # For TLS 1.3 OpenSSL started using the official names name=cipher_suite_openssl_name, openssl_name=cipher_suite_openssl_name, is_anonymous=False, key_size=_RFC_NAME_TO_KEY_SIZE_MAPPING[cipher_suite_openssl_name], ) for cipher_suite_openssl_name in openssl_cipher_strings } return tls_version_to_cipher_suites