def _get_preferred_cipher_suite(
            cls,
            server_connectivity_info: ServerConnectivityInfo,
            ssl_version: OpenSslVersionEnum,
            accepted_cipher_list: List['AcceptedCipherSuite']
    ) -> Optional['AcceptedCipherSuite']:
        """Try to detect the server's preferred cipher suite among all cipher suites supported by SSLyze.
        """
        if len(accepted_cipher_list) < 2:
            return None

        accepted_cipher_names = [cipher.openssl_name for cipher in accepted_cipher_list]
        should_use_legacy_openssl = None

        # For TLS 1.2, we need to figure whether the modern or legacy OpenSSL should be used to connect
        if ssl_version == OpenSslVersionEnum.TLSV1_2:
            should_use_legacy_openssl = True
            # If there are more than two modern-supported cipher suites, use the modern OpenSSL
            for cipher_name in accepted_cipher_names:
                modern_supported_cipher_count = 0
                if not WorkaroundForTls12ForCipherSuites.requires_legacy_openssl(cipher_name):
                    modern_supported_cipher_count += 1

                if modern_supported_cipher_count > 1:
                    should_use_legacy_openssl = False
                    break

        first_cipher_str = ', '.join(accepted_cipher_names)
        # Swap the first two ciphers in the list to see if the server always picks the client's first cipher
        second_cipher_str = ', '.join([accepted_cipher_names[1], accepted_cipher_names[0]] + accepted_cipher_names[2:])

        try:
            first_cipher = cls._get_selected_cipher_suite(
                server_connectivity_info, ssl_version, first_cipher_str, should_use_legacy_openssl
            )
            second_cipher = cls._get_selected_cipher_suite(
                server_connectivity_info, ssl_version, second_cipher_str, should_use_legacy_openssl
            )
        except (SslHandshakeRejected, ConnectionError):
            # Could not complete a handshake
            return None

        if first_cipher.name == second_cipher.name:
            # The server has its own preference for picking a cipher suite
            return first_cipher
        else:
            # The server has no preferred cipher suite as it follows the client's preference for picking a cipher suite
            return None
def _get_preferred_cipher_suite ( cls , server_connectivity_info : ServerConnectivityInfo , ssl_version : OpenSslVersionEnum , accepted_cipher_list : List [ 'AcceptedCipherSuite' ] ) -> Optional [ 'AcceptedCipherSuite' ] : if len ( accepted_cipher_list ) < 2 : return None accepted_cipher_names = [ cipher . openssl_name for cipher in accepted_cipher_list ] should_use_legacy_openssl = None if ssl_version == OpenSslVersionEnum . TLSV1_2 : should_use_legacy_openssl = True for cipher_name in accepted_cipher_names : modern_supported_cipher_count = 0 if not WorkaroundForTls12ForCipherSuites . requires_legacy_openssl ( cipher_name ) : modern_supported_cipher_count += 1 if modern_supported_cipher_count > 1 : should_use_legacy_openssl = False break first_cipher_str = ', ' . join ( accepted_cipher_names ) second_cipher_str = ', ' . join ( [ accepted_cipher_names [ 1 ] , accepted_cipher_names [ 0 ] ] + accepted_cipher_names [ 2 : ] ) try : first_cipher = cls . _get_selected_cipher_suite ( server_connectivity_info , ssl_version , first_cipher_str , should_use_legacy_openssl ) second_cipher = cls . _get_selected_cipher_suite ( server_connectivity_info , ssl_version , second_cipher_str , should_use_legacy_openssl ) except ( SslHandshakeRejected , ConnectionError ) : return None if first_cipher . name == second_cipher . name : return first_cipher else : return None
Try to detect the server's preferred cipher suite among all cipher suites supported by SSLyze.