示例#1
0
    def process_task(self, server_info, scan_command):
        # type: (ServerConnectivityInfo, CertificateInfoScanCommand) -> CertificateInfoScanResult
        final_trust_store_list = list(TrustStoresRepository.get_all())
        if scan_command.custom_ca_file:
            if not os.path.isfile(scan_command.custom_ca_file):
                raise ValueError(
                    'Could not open supplied CA file at "{}"'.format(
                        scan_command.custom_ca_file))
            final_trust_store_list.append(
                TrustStore(scan_command.custom_ca_file, 'Custom --ca_file',
                           'N/A'))

        # Workaround for https://github.com/pyca/cryptography/issues/3495
        default_backend()

        thread_pool = ThreadPool()
        for trust_store in final_trust_store_list:
            # Try to connect with each trust store
            thread_pool.add_job((self._get_and_verify_certificate_chain,
                                 (server_info, trust_store)))

        # Start processing the jobs; one thread per trust
        thread_pool.start(len(final_trust_store_list))

        # Store the results as they come
        certificate_chain = []
        path_validation_result_list = []
        path_validation_error_list = []
        ocsp_response = None

        for (job, result) in thread_pool.get_result():
            (_, (_, trust_store)) = job
            certificate_chain, validation_result, ocsp_response = result
            # Store the returned verify string for each trust store
            path_validation_result_list.append(
                PathValidationResult(trust_store, validation_result))

        # Store thread pool errors
        last_exception = None
        for (job, exception) in thread_pool.get_error():
            (_, (_, trust_store)) = job
            path_validation_error_list.append(
                PathValidationError(trust_store, exception))
            last_exception = exception

        thread_pool.join()

        if len(path_validation_error_list) == len(final_trust_store_list):
            # All connections failed unexpectedly; raise an exception instead of returning a result
            raise last_exception

        # All done
        return CertificateInfoScanResult(server_info, scan_command,
                                         certificate_chain,
                                         path_validation_result_list,
                                         path_validation_error_list,
                                         ocsp_response)
示例#2
0
    def process_task(self, server_info, command, options_dict=None):

        if command == 'certinfo_basic':
            result_class = CertInfoBasicResult
        elif command == 'certinfo_full':
            result_class = CertInfoFullResult
        else:
            raise ValueError("PluginCertInfo: Unknown command.")

        final_trust_store_list = list(DEFAULT_TRUST_STORE_LIST)
        if options_dict and 'ca_file' in options_dict.keys():
            final_trust_store_list.append(
                TrustStore(options_dict['ca_file'], 'Custom --ca_file', 'N/A'))

        thread_pool = ThreadPool()
        for trust_store in final_trust_store_list:
            # Try to connect with each trust store
            thread_pool.add_job(
                (self._get_certificate_chain, (server_info, trust_store)))

        # Start processing the jobs; one thread per trust
        thread_pool.start(len(final_trust_store_list))

        # Store the results as they come
        certificate_chain = []
        path_validation_result_list = []
        path_validation_error_list = []
        ocsp_response = None

        for (job, result) in thread_pool.get_result():
            (_, (_, trust_store)) = job
            certificate_chain, validation_result, ocsp_response = result
            # Store the returned verify string for each trust store
            path_validation_result_list.append(
                PathValidationResult(trust_store, validation_result))

        # Store thread pool errors
        last_exception = None
        for (job, exception) in thread_pool.get_error():
            (_, (_, trust_store)) = job
            path_validation_error_list.append(
                PathValidationError(trust_store, exception))
            last_exception = exception

        thread_pool.join()

        if len(path_validation_error_list) == len(final_trust_store_list):
            # All connections failed unexpectedly; raise an exception instead of returning a result
            raise RuntimeError(
                'Could not connect to the server; last error: {}'.format(
                    last_exception))

        # All done
        return result_class(server_info, command, options_dict,
                            certificate_chain, path_validation_result_list,
                            path_validation_error_list, ocsp_response)
    def process_task(self,
                     server_connectivity_info,
                     plugin_command,
                     options_dict=None):
        ssl_version = self.SSL_VERSIONS_MAPPING[plugin_command]

        # Get the list of available cipher suites for the given ssl version
        ssl_client = SslClient(ssl_version=ssl_version)
        ssl_client.set_cipher_list('ALL:COMPLEMENTOFALL')
        cipher_list = ssl_client.get_cipher_list()

        # Scan for every available cipher suite
        thread_pool = ThreadPool()
        for cipher in cipher_list:
            thread_pool.add_job(
                (self._test_cipher_suite, (server_connectivity_info,
                                           ssl_version, cipher)))

        # Start processing the jobs; One thread per cipher
        thread_pool.start(nb_threads=min(len(cipher_list), self.MAX_THREADS))

        accepted_cipher_list = []
        rejected_cipher_list = []
        errored_cipher_list = []

        # Store the results as they come
        for completed_job in thread_pool.get_result():
            (job, cipher_result) = completed_job
            if isinstance(cipher_result, AcceptedCipherSuite):
                accepted_cipher_list.append(cipher_result)
            elif isinstance(cipher_result, RejectedCipherSuite):
                rejected_cipher_list.append(cipher_result)
            elif isinstance(cipher_result, ErroredCipherSuite):
                errored_cipher_list.append(cipher_result)
            else:
                raise ValueError('Unexpected result')

        # Store thread pool errors; only something completely unexpected would trigger an error
        for failed_job in thread_pool.get_error():
            (_, exception) = failed_job
            raise exception

        thread_pool.join()

        # Test for the cipher suite preference
        preferred_cipher = self._get_preferred_cipher_suite(
            server_connectivity_info, ssl_version, accepted_cipher_list)

        # Generate the results
        plugin_result = OpenSSLCipherSuitesResult(server_connectivity_info,
                                                  plugin_command, options_dict,
                                                  preferred_cipher,
                                                  accepted_cipher_list,
                                                  rejected_cipher_list,
                                                  errored_cipher_list)
        return plugin_result
    def process_task(self,
                     server_connectivity_info,
                     plugin_command,
                     option_dict=None):
        if option_dict and 'verbose' in option_dict.keys():
            verbose_mode = option_dict['verbose']
        else:
            verbose_mode = False
        ssl3_support = self.test_SSLv3_support(server_connectivity_info)
        support_vulnerable_ciphers = None
        if ssl3_support:
            cipher_list = self.get_ssl3_cipher_list()
            thread_pool = ThreadPool()
            for cipher in cipher_list:
                thread_pool.add_job((self._test_ciphersuite,
                                     (server_connectivity_info, cipher)))
            thread_pool.start(
                nb_threads=min(len(cipher_list), self.MAX_THREADS))

            accept_ciphers = []
            reject_ciphers = []
            if verbose_mode:
                print '  VERBOSE MODE PRINT'
                print '  ------------------'
            for completed_job in thread_pool.get_result():
                (job, cipher_result) = completed_job
                if isinstance(cipher_result, AcceptCipher):
                    accept_ciphers.append(cipher_result)
                elif isinstance(cipher_result, RejectCipher):
                    reject_ciphers.append(cipher_result)
                else:
                    raise ValueError("Unexpected result")
                if verbose_mode:
                    cipher_result.print_cipher()

            if verbose_mode:
                print '  ----------------------'
                print '  END VERBOSE MODE PRINT'
                print '  ----------------------'

            for error_job in thread_pool.get_error():
                (_, exception) = error_job
                raise exception

            thread_pool.join()
            support_vulnerable_ciphers = self.get_vulnerable_ciphers(
                accept_ciphers)

        is_vulnerable = ssl3_support and (
            support_vulnerable_ciphers is not None
            or len(support_vulnerable_ciphers) > 0)

        return POODLEVulnerabilityTesterResult(server_connectivity_info,
                                               plugin_command, option_dict,
                                               ssl3_support, is_vulnerable,
                                               support_vulnerable_ciphers)
示例#5
0
    def _run_oracle_over_threads(
        cls,
        server_info: ServerConnectivityInfo,
        ssl_version_to_use: OpenSslVersionEnum,
        cipher_string: str,
        rsa_modulus: int,
        rsa_exponent: int,
        should_complete_handshake: bool,
    ) -> RobotScanResultEnum:
        # Use threads to speed things up
        thread_pool = ThreadPool()

        for payload_enum in RobotPmsPaddingPayloadEnum:
            # Run each payload three times to ensure the results are consistent
            for _ in range(3):
                thread_pool.add_job((
                    cls._send_robot_payload,
                    [
                        server_info,
                        ssl_version_to_use,
                        cipher_string,
                        payload_enum,
                        should_complete_handshake,
                        rsa_modulus,
                        rsa_exponent,
                    ],
                ))

        # Use one thread per check
        thread_pool.start(nb_threads=len(RobotPmsPaddingPayloadEnum))

        # Store the results - two attempts per ROBOT payload
        payload_responses: Dict[RobotPmsPaddingPayloadEnum, List[str]] = {
            RobotPmsPaddingPayloadEnum.VALID: [],
            RobotPmsPaddingPayloadEnum.WRONG_FIRST_TWO_BYTES: [],
            RobotPmsPaddingPayloadEnum.WRONG_POSITION_00: [],
            RobotPmsPaddingPayloadEnum.NO_00_IN_THE_MIDDLE: [],
            RobotPmsPaddingPayloadEnum.WRONG_VERSION_NUMBER: [],
        }

        for completed_job in thread_pool.get_result():
            (job, (payload_enum, server_response)) = completed_job
            payload_responses[payload_enum].append(server_response)

        for failed_job in thread_pool.get_error():
            # Should never happen when running the Robot check as we catch all exceptions in the handshake
            (_, exception) = failed_job
            raise exception

        thread_pool.join()
        return RobotServerResponsesAnalyzer(
            payload_responses).compute_result_enum()
示例#6
0
    def create_thread_pool_for_protocol_tls(self, server_connectivity_info):
        """ Creates and returns instance of ThreadPool class. Adds into ThreadPool new jobs for each cipher suite, which is available for protocol TLS 1.1 and TLS 1.2
    
            Args:
            server_connectivity_info (ServerConnectivityInfo): contains information for connection on server.
        """
        thread_pool = ThreadPool()
        protocols = ['TLSv1.1', 'TLSv1.2']
        cipher_list = []
        for protocol in protocols:
            if self.test_protocol_support(server_connectivity_info, protocol):
                cipher_list = self.get_cipher_list(protocol)
                for cipher in cipher_list:
                    thread_pool.add_job(
                        (self._test_ciphersuite, (server_connectivity_info,
                                                  protocol, cipher)))

        return (thread_pool, min(self.MAX_THREADS, len(cipher)))
示例#7
0
    def create_thread_pool_for_protocol_dtls(self, server_connectivity_info,
                                             port):
        """ Creates and returns instance of ThreadPool class. Adds into ThreadPool new jobs for each cipher suite, which is available for protocol DTLS 1.0 and/or DTLS 1.2

            Args:
            server_connectivity_info (ServerConnectivityInfo): contains information for connection on server
            port (int): contains port number for connecting comunication.
        """
        dtls_protocols = self.get_support_dtls_protocols_by_client()
        thread_pool = ThreadPool()
        cipher_list = []
        for protocol in dtls_protocols:
            if self.test_dtls_protocol_support(server_connectivity_info,
                                               protocol, port):
                cipher_list = self.get_dtls_cipher_list(protocol)
                for cipher in cipher_list:
                    thread_pool.add_job(
                        (self._test_dtls_ciphersuite,
                         (server_connectivity_info, protocol, cipher, port)))

        return (thread_pool, 1)
示例#8
0
    def _run_oracle_over_threads(cls, server_info, cipher_string, rsa_modulus,
                                 rsa_exponent, should_complete_handshake):
        # type: (ServerConnectivityInfo, Text, int, int, bool) -> RobotScanResultEnum
        # Use threads to speed things up
        thread_pool = ThreadPool()

        for payload_enum in RobotPmsPaddingPayloadEnum:
            # Run each payload twice to ensure the results are consistent
            thread_pool.add_job(
                (cls._send_robot_payload,
                 (server_info, cipher_string, payload_enum,
                  should_complete_handshake, rsa_modulus, rsa_exponent)))
            thread_pool.add_job(
                (cls._send_robot_payload,
                 (server_info, cipher_string, payload_enum,
                  should_complete_handshake, rsa_modulus, rsa_exponent)))

        # Use one thread per check
        thread_pool.start(nb_threads=len(RobotPmsPaddingPayloadEnum) * 2)

        # Store the results - two attempts per ROBOT payload
        payload_responses = {
            RobotPmsPaddingPayloadEnum.VALID: [],
            RobotPmsPaddingPayloadEnum.WRONG_FIRST_TWO_BYTES: [],
            RobotPmsPaddingPayloadEnum.WRONG_POSITION_00: [],
            RobotPmsPaddingPayloadEnum.NO_00_IN_THE_MIDDLE: [],
            RobotPmsPaddingPayloadEnum.WRONG_VERSION_NUMBER: [],
        }
        for completed_job in thread_pool.get_result():
            (job, (payload_enum, server_response)) = completed_job
            payload_responses[payload_enum].append(server_response)

        for failed_job in thread_pool.get_error():
            # Should never happen when running the Robot check as we catch all exceptions in the handshake
            (_, exception) = failed_job
            raise exception

        thread_pool.join()
        return RobotServerResponsesAnalyzer(
            payload_responses).compute_result_enum()
    def _test_session_resumption_rate(self, server_info, resumption_attempts_nb):
        """Attempts several session ID resumption with the server."""
        thread_pool = ThreadPool()

        for _ in xrange(resumption_attempts_nb):
            thread_pool.add_job((self._resume_with_session_id, (server_info, )))
        thread_pool.start(nb_threads=min(resumption_attempts_nb, self.MAX_THREADS_NB))

        # Count successful/failed resumptions
        successful_resumptions_nb = 0
        for completed_job in thread_pool.get_result():
            (job, was_resumption_successful) = completed_job
            if was_resumption_successful:
                successful_resumptions_nb += 1

        # Count errors and store error messages
        errored_resumptions_list = []
        for failed_job in thread_pool.get_error():
            (job, exception) = failed_job
            error_msg = '{} - {}'.format(str(exception.__class__.__name__), str(exception))
            errored_resumptions_list.append(error_msg)

        thread_pool.join()
        return successful_resumptions_nb, errored_resumptions_list
    def process_task(
            self, server_connectivity_info: ServerConnectivityInfo,
            scan_command: PluginScanCommand) -> 'CipherSuiteScanResult':
        if not isinstance(scan_command, CipherSuiteScanCommand):
            raise ValueError('Unexpected scan command')

        ssl_version = self.SSL_VERSIONS_MAPPING[scan_command.__class__]
        # Get the list of available cipher suites for the given ssl version
        cipher_list: List[str] = []
        if ssl_version == OpenSslVersionEnum.TLSV1_2:
            # For TLS 1.2, we have to use both the legacy and modern OpenSSL to cover all cipher suites
            ssl_connection_legacy = server_connectivity_info.get_preconfigured_ssl_connection(
                override_ssl_version=ssl_version,
                should_use_legacy_openssl=True)
            ssl_connection_legacy.ssl_client.set_cipher_list(
                'ALL:COMPLEMENTOFALL:-PSK:-SRP')
            cipher_list.extend(
                ssl_connection_legacy.ssl_client.get_cipher_list())

            ssl_connection_modern = server_connectivity_info.get_preconfigured_ssl_connection(
                override_ssl_version=ssl_version,
                should_use_legacy_openssl=False)
            # Disable the TLS 1.3 cipher suites with the new OpenSSL API
            ssl_connection_modern.ssl_client.set_ciphersuites('')
            # Enable all other cipher suites
            ssl_connection_modern.ssl_client.set_cipher_list(
                'ALL:COMPLEMENTOFALL:-PSK:-SRP')
            cipher_list.extend(
                ssl_connection_modern.ssl_client.get_cipher_list())

            # And remove duplicates (ie. supported by both legacy and modern OpenSSL)
            cipher_list = list(set(cipher_list))
        elif ssl_version == OpenSslVersionEnum.TLSV1_3:
            # TLS 1.3 only has 5 cipher suites so we can hardcode them
            cipher_list = [
                'TLS_AES_256_GCM_SHA384',
                'TLS_CHACHA20_POLY1305_SHA256',
                'TLS_AES_128_GCM_SHA256',
                'TLS_AES_128_CCM_8_SHA256',
                'TLS_AES_128_CCM_SHA256',
            ]
        else:
            ssl_connection = server_connectivity_info.get_preconfigured_ssl_connection(
                override_ssl_version=ssl_version)
            # Disable SRP and PSK cipher suites as they need a special setup in the client and are never used
            ssl_connection.ssl_client.set_cipher_list(
                'ALL:COMPLEMENTOFALL:-PSK:-SRP')
            # And remove TLS 1.3 cipher suites
            cipher_list = [
                cipher
                for cipher in ssl_connection.ssl_client.get_cipher_list()
                if 'TLS13' not in cipher
            ]

        # Scan for every available cipher suite
        thread_pool = ThreadPool()
        for cipher in cipher_list:
            thread_pool.add_job(
                (self._test_cipher_suite,
                 [server_connectivity_info, ssl_version, cipher]))

        # Start processing the jobs; One thread per cipher
        thread_pool.start(nb_threads=min(len(cipher_list), self.MAX_THREADS))

        accepted_cipher_list = []
        rejected_cipher_list = []
        errored_cipher_list = []

        # Store the results as they come
        for completed_job in thread_pool.get_result():
            (job, cipher_result) = completed_job
            if isinstance(cipher_result, AcceptedCipherSuite):
                accepted_cipher_list.append(cipher_result)
            elif isinstance(cipher_result, RejectedCipherSuite):
                rejected_cipher_list.append(cipher_result)
            elif isinstance(cipher_result, ErroredCipherSuite):
                errored_cipher_list.append(cipher_result)
            else:
                raise ValueError('Unexpected result')

        # Store thread pool errors; only something completely unexpected would trigger an error
        for failed_job in thread_pool.get_error():
            (_, exception) = failed_job
            raise exception

        thread_pool.join()

        # Test for the cipher suite preference
        preferred_cipher = self._get_preferred_cipher_suite(
            server_connectivity_info, ssl_version, accepted_cipher_list)

        # Generate the results
        plugin_result = CipherSuiteScanResult(server_connectivity_info,
                                              scan_command, preferred_cipher,
                                              accepted_cipher_list,
                                              rejected_cipher_list,
                                              errored_cipher_list)
        return plugin_result
 def __init__(
         self, server_connectivity_testers: List[ServerConnectivityTester]
 ) -> None:
     # Use a thread pool to connect to each server
     self._thread_pool = ThreadPool()
     self._server_connectivity_testers = server_connectivity_testers
    def process_task(self,
                     server_connectivity_info,
                     plugin_command,
                     options_dict=None):
        if options_dict and 'verbose' in options_dict.keys():
            verbose_mode = options_dict['verbose']
        else:
            verbose_mode = False
        test_protocols = {'SSLv3', 'TLSv1'}
        thread_pool = ThreadPool()
        ciphers_list = []
        support_protocol_list = []
        for proto in test_protocols:
            if self.test_protocol_support(PROTOCOL_VERSION[proto],
                                          server_connectivity_info):
                ssl_client = SslClient(ssl_version=PROTOCOL_VERSION[proto])
                ssl_client.set_cipher_list(proto)
                ciphers_list = ssl_client.get_cipher_list()
                for cipher in ciphers_list:
                    thread_pool.add_job((self._test_ciphersuite,
                                         (server_connectivity_info,
                                          PROTOCOL_VERSION[proto], cipher)))
                support_protocol_list.append(proto)
        thread_pool.start(nb_threads=min(len(ciphers_list), self.MAX_THREADS))

        accept_ciphers = []
        reject_ciphers = []
        if verbose_mode:
            print '  VERBOSE MODE PRINT'
            print '  ------------------'

        for completed_job in thread_pool.get_result():
            (job, cipher_result) = completed_job
            if isinstance(cipher_result, AcceptCipher):
                accept_ciphers.append(cipher_result)
            elif isinstance(cipher_result, RejectCipher):
                reject_ciphers.append(cipher_result)
            else:
                raise ValueError("Unexpected result")
            if verbose_mode:
                cipher_result.print_cipher()

        if verbose_mode:
            print '  ----------------------'
            print '  END VERBOSE MODE PRINT'
            print '  ----------------------'

        for error_job in thread_pool.get_error():
            (_, exception) = error_job
            raise exception

        thread_pool.join()

        support_vulnerable_ciphers_set = self.get_vulnerable_ciphers(
            accept_ciphers)
        is_vulnerable = True \
            if len(support_vulnerable_ciphers_set) > 0 \
            else False

        return BEASTVulnerabilityTesterResult(server_connectivity_info,
                                              plugin_command, options_dict,
                                              support_vulnerable_ciphers_set,
                                              is_vulnerable,
                                              support_protocol_list)
示例#13
0
 def __init__(self, tentative_server_info_list):
     # type: (List[ServerConnectivityInfo]) -> None
     # Use a thread pool to connect to each server
     self._thread_pool = ThreadPool()
     self._server_info_list = tentative_server_info_list
示例#14
0
    def process_task(self, server_connectivity_info, scan_command):
        # type: (ServerConnectivityInfo, CipherSuiteScanCommand) -> CipherSuiteScanResult
        ssl_version = self.SSL_VERSIONS_MAPPING[scan_command.__class__]

        # Get the list of available cipher suites for the given ssl version
        if ssl_version == OpenSslVersionEnum.TLSV1_2:
            # For TLS 1.2, we have to use both the legacy and modern OpenSSL to cover all cipher suites
            cipher_list = []
            ssl_connection = server_connectivity_info.get_preconfigured_ssl_connection(
                override_ssl_version=ssl_version,
                should_use_legacy_openssl=True)
            ssl_connection.ssl_client.set_cipher_list(
                'ALL:COMPLEMENTOFALL:-PSK:-SRP')
            cipher_list.extend(ssl_connection.ssl_client.get_cipher_list())

            ssl_connection = server_connectivity_info.get_preconfigured_ssl_connection(
                override_ssl_version=ssl_version,
                should_use_legacy_openssl=False)
            ssl_connection.ssl_client.set_cipher_list(
                'ALL:COMPLEMENTOFALL:-PSK:-SRP')
            cipher_list.extend(ssl_connection.ssl_client.get_cipher_list())

            # Lastly we have to remove TLS 1.3 cipher suites
            cipher_list = [
                cipher
                for cipher in ssl_connection.ssl_client.get_cipher_list()
                if 'TLS13' not in cipher
            ]

            # And remove duplicates (ie. supported by both legacy and modern OpenSSL)
            cipher_list = set(cipher_list)
        elif ssl_version == OpenSslVersionEnum.TLSV1_3:
            # For TLS 1.3 we need to manually pick the cipher suites as there is no OpenSSL cipher string to select them
            ssl_connection = server_connectivity_info.get_preconfigured_ssl_connection(
                override_ssl_version=ssl_version)
            cipher_list = [
                cipher
                for cipher in ssl_connection.ssl_client.get_cipher_list()
                if 'TLS13' in cipher
            ]
        else:
            ssl_connection = server_connectivity_info.get_preconfigured_ssl_connection(
                override_ssl_version=ssl_version)
            # Disable SRP and PSK cipher suites as they need a special setup in the client and are never used
            ssl_connection.ssl_client.set_cipher_list(
                'ALL:COMPLEMENTOFALL:-PSK:-SRP')
            # And remove TLS 1.3 cipher suites
            cipher_list = [
                cipher
                for cipher in ssl_connection.ssl_client.get_cipher_list()
                if 'TLS13' not in cipher
            ]

        # Scan for every available cipher suite
        thread_pool = ThreadPool()
        for cipher in cipher_list:
            thread_pool.add_job(
                (self._test_cipher_suite, (server_connectivity_info,
                                           ssl_version, cipher)))

        # Start processing the jobs; One thread per cipher
        thread_pool.start(nb_threads=min(len(cipher_list), self.MAX_THREADS))

        accepted_cipher_list = []
        rejected_cipher_list = []
        errored_cipher_list = []

        # Store the results as they come
        for completed_job in thread_pool.get_result():
            (job, cipher_result) = completed_job
            if isinstance(cipher_result, AcceptedCipherSuite):
                accepted_cipher_list.append(cipher_result)
            elif isinstance(cipher_result, RejectedCipherSuite):
                rejected_cipher_list.append(cipher_result)
            elif isinstance(cipher_result, ErroredCipherSuite):
                errored_cipher_list.append(cipher_result)
            else:
                raise ValueError('Unexpected result')

        # Store thread pool errors; only something completely unexpected would trigger an error
        for failed_job in thread_pool.get_error():
            (_, exception) = failed_job
            raise exception

        thread_pool.join()

        # Test for the cipher suite preference
        preferred_cipher = self._get_preferred_cipher_suite(
            server_connectivity_info, ssl_version, accepted_cipher_list)

        # Generate the results
        plugin_result = CipherSuiteScanResult(server_connectivity_info,
                                              scan_command, preferred_cipher,
                                              accepted_cipher_list,
                                              rejected_cipher_list,
                                              errored_cipher_list)
        return plugin_result