def test_split_multi(self): conn = SSLv30Connection( protocol_version=flextls.registry.version.SSLv3) assert conn.is_empty() data = server_hello_01 data += server_certificate_01 data += server_key_exchange_01 data += server_hello_done_01 for part in prepare_handshake_data_split(data, 50): conn.decode(part) assert not conn.is_empty() record = conn.pop_record() self._server_hello_01(record) assert not conn.is_empty() record = conn.pop_record() self._server_certificate_01(record) assert not conn.is_empty() record = conn.pop_record() self._server_key_exchange_01(record) assert not conn.is_empty() record = conn.pop_record() assert conn.is_empty() self._server_hello_done_01(record)
def connect_tls(self, protocol_version, stop_condition=None): def _default_stop_condition(record, records): return isinstance(record, Handshake) and \ isinstance(record.payload, ServerHelloDone) if stop_condition is None: stop_condition = _default_stop_condition conn = self._scanner.handler.connect() conn.settimeout(2.0) conn_tls = SSLv30Connection(protocol_version=protocol_version) record_handshake = self.build_tls_client_hello(protocol_version) conn.send_list(conn_tls.encode(record_handshake)) time_start = datetime.now() records = [] run = True while run: tmp_time = datetime.now() - time_start if tmp_time.total_seconds() > 5.0: return records try: data = conn.recv(4096) except ConnectionError: return records except socket.timeout: conn.close() return records try: conn_tls.decode(data) except WrongProtocolVersion: # Send alert and close socket record_alert = Alert() record_alert.level = "fatal" record_alert.description = "protocol_version" conn.send_list(conn_tls.encode(record_alert)) conn.close() return None while not conn_tls.is_empty(): record = conn_tls.pop_record() self.parse_tls_server_records_hooks.call(record) if isinstance(record, Alert): if record.level == 2: return records records.append(record) if stop_condition(record, records): run = False conn.close() return records
def test_single(self): conn = SSLv30Connection( protocol_version=flextls.registry.version.SSLv3) assert conn.is_empty() conn.decode(prepare_handshake_data(client_hello_01)) assert not conn.is_empty() record = conn.pop_record() assert conn.is_empty() self._client_hello_01(record) conn.decode(prepare_handshake_data(client_key_exchange_01)) assert not conn.is_empty() record = conn.pop_record() assert conn.is_empty() self._client_key_exchange_01(record)
def test_single(self): conn = SSLv30Connection( protocol_version=flextls.registry.version.SSLv3) assert conn.is_empty() conn.decode(prepare_handshake_data(server_hello_01)) assert not conn.is_empty() record = conn.pop_record() assert conn.is_empty() self._server_hello_01(record) conn.decode(prepare_handshake_data(server_certificate_01)) assert not conn.is_empty() record = conn.pop_record() assert conn.is_empty() self._server_certificate_01(record) conn.decode(prepare_handshake_data(server_key_exchange_01)) assert not conn.is_empty() record = conn.pop_record() assert conn.is_empty() self._server_key_exchange_01(record) conn.decode(prepare_handshake_data(server_hello_done_01)) assert not conn.is_empty() record = conn.pop_record() assert conn.is_empty() self._server_hello_done_01(record) self._connection_state(conn) # Change Cipher Spec, SSLv3.0, Length 1 data = b"1403000001" # Change Cipher Spec Message data += b"01" conn.decode(binascii.unhexlify(data)) assert not conn.is_empty() record = conn.pop_record() assert conn.is_empty() self._change_cipher_spec(record)
def _scan_elliptic_curves_tls(self, protocol_version, cipher_suites, elliptic_curves, limit=False): """ Scan for supported elliptic curves :param protocol_version: :param cipher_suites: List of cipher suites. :param elliptic_curves: List of elliptic curves :param limit: :return: List of supported elliptic curve IDs """ # Get IDs of allowed cipher suites tmp = [] for cipher_suite in cipher_suites: tmp.append(cipher_suite.id) cipher_suites = tmp tmp = [] for elliptic_curve in elliptic_curves: tmp.append(elliptic_curve.id) elliptic_curves = tmp detected_elliptic_curves = [] count = 0 while True: conn = self._scanner.handler.connect() conn.settimeout(2.0) conn_tls = SSLv30Connection(protocol_version=protocol_version) record_handshake = self._build_tls_base_client_hello( protocol_version, cipher_suites, elliptic_curves=elliptic_curves) conn.send_list(conn_tls.encode(record_handshake)) time_start = datetime.now() server_key_exchange = None while server_key_exchange is None: tmp_time = datetime.now() - time_start if tmp_time.total_seconds() > 5.0: return detected_elliptic_curves try: data = conn.recv(4096) except ConnectionError: return detected_elliptic_curves except socket.timeout: conn.close() return detected_elliptic_curves try: conn_tls.decode(data) except WrongProtocolVersion: # Send alert and close socket record_alert = Alert() record_alert.level = "fatal" record_alert.description = "protocol_version" conn.send_list(conn_tls.encode(record_alert)) conn.close() return detected_elliptic_curves while not conn_tls.is_empty(): record = conn_tls.pop_record() if isinstance(record, Handshake): if isinstance(record.payload, ServerKeyExchange): server_key_exchange = record.payload elif isinstance(record, Alert): if record.level == 2: return detected_elliptic_curves conn.close() # stop if no ServerKeyExchange was sent if server_key_exchange is None: break # try to extract the ec id tmp_ec_id = None if isinstance(server_key_exchange.payload, ServerKeyExchangeECDSA): tmp_params = server_key_exchange.payload.params if isinstance(tmp_params, ServerECDHParamsField): if isinstance(tmp_params.curve_params, ECParametersNamedCurveField): tmp_ec_id = tmp_params.curve_params.namedcurve if tmp_ec_id is None: return detected_elliptic_curves # stop if we get an unexpected ec id if tmp_ec_id not in elliptic_curves: return detected_elliptic_curves detected_elliptic_curves.append(tmp_ec_id) elliptic_curves.remove(tmp_ec_id) count += 1 if limit is not False and limit <= count: break return detected_elliptic_curves
def _scan_tls_cipher_suites(self, protocol_version, cipher_suites, limit=False): kb = self._scanner.get_knowledge_base() # Get IDs of allowed cipher suites tmp = [] for cipher_suite in cipher_suites: tmp.append(cipher_suite.id) cipher_suites = tmp detected_ciphers = [] count = 0 while True: conn = self._scanner.handler.connect() conn.settimeout(2.0) conn_tls = SSLv30Connection(protocol_version=protocol_version) record_handshake = self._build_tls_base_client_hello( protocol_version, cipher_suites) conn.send_list(conn_tls.encode(record_handshake)) time_start = datetime.now() server_hello = None raw_certs = kb.get("server.certificate.raw") while server_hello is None or raw_certs is None: tmp_time = datetime.now() - time_start if tmp_time.total_seconds() > 5.0: return detected_ciphers try: data = conn.recv(4096) except ConnectionError: return detected_ciphers except socket.timeout: conn.close() return detected_ciphers try: conn_tls.decode(data) except WrongProtocolVersion: # Send alert and close socket record_alert = Alert() record_alert.level = "fatal" record_alert.description = "protocol_version" conn.send_list(conn_tls.encode(record_alert)) conn.close() return detected_ciphers while not conn_tls.is_empty(): record = conn_tls.pop_record() if isinstance(record, Handshake): if isinstance(record.payload, ServerHello): server_hello = record.payload elif raw_certs is None and isinstance( record.payload, ServerCertificate): raw_certs = [] for raw_cert in record.payload.certificate_list: raw_certs.append(raw_cert.value) kb.set("server.certificate.raw", raw_certs) elif isinstance(record, Alert): if record.level == 2: return detected_ciphers conn.close() if server_hello is None: break # get compression method if kb.get("server.session.compression") is None: comp_method = flextls.registry.tls.compression_methods.get( server_hello.compression_method) kb.set("server.session.compression", comp_method) for extension in server_hello.extensions: if isinstance(extension.payload, EcPointFormats): tmp_formats = [] for format_id in extension.payload.point_format_list: tmp_format = flextls.registry.ec.point_formats.get( format_id.value) tmp_formats.append(tmp_format) if kb.get("server.ec.point_formats") is None: kb.set("server.ec.point_formats", tmp_formats) detected_ciphers.append(server_hello.cipher_suite) cipher_suites.remove(server_hello.cipher_suite) count = count + 1 if limit is not False and limit <= count: break return detected_ciphers