From b730fdc5c27ce327031e603eb5bac578791ccb1d Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Tue, 17 Sep 2024 09:42:32 -0600 Subject: [PATCH 1/7] Add TLS 1.0 client test --- modules/test/tls/conf/module_config.json | 9 +++++++++ modules/test/tls/python/src/tls_module.py | 10 ++++++++++ modules/test/tls/python/src/tls_util.py | 19 +++++++++++-------- resources/test_packs/qualification.json | 4 ++++ 4 files changed, 34 insertions(+), 8 deletions(-) diff --git a/modules/test/tls/conf/module_config.json b/modules/test/tls/conf/module_config.json index c0f25f8a7..933efd3ad 100644 --- a/modules/test/tls/conf/module_config.json +++ b/modules/test/tls/conf/module_config.json @@ -12,6 +12,15 @@ "timeout": 300 }, "tests":[ + { + "name": "security.tls.v1_0_client", + "test_description": "Device uses TLS with connection to an external service on port 443 (or any other port which could be running the webserver-HTTPS)", + "expected_behavior": "The packet indicates a TLS connection with at least TLS 1.0 and support", + "recommendations": [ + "Disable connections to unsecure services", + "Ensure any URLs connected to are secure (https)" + ] + }, { "name": "security.tls.v1_2_server", "test_description": "Check the device web server TLS 1.2 & certificate is valid", diff --git a/modules/test/tls/python/src/tls_module.py b/modules/test/tls/python/src/tls_module.py index 08469f32e..bdc73a3fa 100644 --- a/modules/test/tls/python/src/tls_module.py +++ b/modules/test/tls/python/src/tls_module.py @@ -271,6 +271,16 @@ def _security_tls_v1_3_server(self): LOGGER.error('Could not resolve device IP address') return 'Error', 'Could not resolve device IP address' + def _security_tls_v1_0_client(self): + LOGGER.info('Running security.tls.v1_0_client') + self._resolve_device_ip() + # If the ipv4 address wasn't resolved yet, try again + if self._device_ipv4_addr is not None: + return self._validate_tls_client(self._device_ipv4_addr, '1.0') + else: + LOGGER.error('Could not resolve device IP address. Skipping') + return 'Error', 'Could not resolve device IP address' + def _security_tls_v1_2_client(self): LOGGER.info('Running security.tls.v1_2_client') self._resolve_device_ip() diff --git a/modules/test/tls/python/src/tls_util.py b/modules/test/tls/python/src/tls_util.py index e71a56c7c..a70215361 100644 --- a/modules/test/tls/python/src/tls_util.py +++ b/modules/test/tls/python/src/tls_util.py @@ -551,7 +551,7 @@ def process_hello_packets(self, f'\nAllowing {protocol_name} traffic to {packet["dst_ip"]}') client_hello_results['valid'].append(packet) else: - # No cipher check for TLS 1.3 + # No cipher check for TLS 1.0, 1.1 or TLS 1.3 client_hello_results['valid'] = hello_packets return client_hello_results @@ -760,13 +760,16 @@ def validate_tls_client(self, client_ip, tls_version, capture_files): LOGGER.info(f'''TLS connection detected to {ip}. Ignoring non-TLS traffic detected to this IP''') - unsupported_tls_ips = self.get_unsupported_tls_ips(client_ip, capture_files) - if len(unsupported_tls_ips) > 0: - tls_client_valid = False - for ip, tls_versions in unsupported_tls_ips.items(): - for version in tls_versions: - tls_client_details += f'''\nUnsupported TLS {version} - connection detected to {ip}''' + if tls_version == '1.2' || tls_version == '1.3': + # Only check TLS 1.0 and 1.1 as unsupported if we're validating + # higher TLS versions + unsupported_tls_ips = self.get_unsupported_tls_ips(client_ip, capture_files) + if len(unsupported_tls_ips) > 0: + tls_client_valid = False + for ip, tls_versions in unsupported_tls_ips.items(): + for version in tls_versions: + tls_client_details += f'''\nUnsupported TLS {version} + connection detected to {ip}''' return tls_client_valid, tls_client_details def is_ecdh_and_ecdsa(self, ciphers): diff --git a/resources/test_packs/qualification.json b/resources/test_packs/qualification.json index f7c63ee8f..967370b4a 100644 --- a/resources/test_packs/qualification.json +++ b/resources/test_packs/qualification.json @@ -153,6 +153,10 @@ "name": "ntp.network.ntp_server", "required_result": "Required" }, + { + "name": "security.tls.v1_0_client", + "required_result": "Informational" + }, { "name": "security.tls.v1_2_server", "required_result": "Required if Applicable" From 15f6ec5e45f68825c72c85032435536006be85e7 Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Tue, 17 Sep 2024 13:20:49 -0600 Subject: [PATCH 2/7] Update tls 1.0 test to account for higher versions Add tls 1.0 and 1.1 versions to binaries --- .../test/tls/bin/get_client_hello_packets.sh | 12 +++- .../test/tls/bin/get_handshake_complete.sh | 72 ++++++++++--------- modules/test/tls/python/src/tls_module.py | 26 +++++-- modules/test/tls/python/src/tls_util.py | 66 +++++++---------- modules/ws/conf/mosquitto.conf | 2 +- 5 files changed, 98 insertions(+), 80 deletions(-) diff --git a/modules/test/tls/bin/get_client_hello_packets.sh b/modules/test/tls/bin/get_client_hello_packets.sh index d563d11f2..317657187 100755 --- a/modules/test/tls/bin/get_client_hello_packets.sh +++ b/modules/test/tls/bin/get_client_hello_packets.sh @@ -21,13 +21,21 @@ TLS_VERSION="$3" TSHARK_OUTPUT="-T json -e ip.src -e tcp.dstport -e ip.dst" TSHARK_FILTER="ssl.handshake.type==1 and ip.src==$SRC_IP" -if [[ $TLS_VERSION == '1.2' || -z $TLS_VERSION ]];then +if [[ $TLS_VERSION == '1.0' ]]; then + TSHARK_FILTER="$TSHARK_FILTER and ssl.handshake.version==0x0301" +elif [[ $TLS_VERSION == '1.1' ]]; then + TSHARK_FILTER="$TSHARK_FILTER and ssl.handshake.version==0x0302" +elif [[ $TLS_VERSION == '1.2' || -z $TLS_VERSION ]]; then TSHARK_FILTER="$TSHARK_FILTER and ssl.handshake.version==0x0303" -elif [ $TLS_VERSION == '1.3' ];then +elif [[ $TLS_VERSION == '1.3' ]]; then TSHARK_FILTER="$TSHARK_FILTER and (ssl.handshake.version==0x0304 or tls.handshake.extensions.supported_version==0x0304)" +else + echo "Unsupported TLS version: $TLS_VERSION" + exit 1 fi response=$(tshark -r "$CAPTURE_FILE" $TSHARK_OUTPUT $TSHARK_FILTER) echo "$response" + \ No newline at end of file diff --git a/modules/test/tls/bin/get_handshake_complete.sh b/modules/test/tls/bin/get_handshake_complete.sh index 9bf9c525d..b36997f6d 100755 --- a/modules/test/tls/bin/get_handshake_complete.sh +++ b/modules/test/tls/bin/get_handshake_complete.sh @@ -1,33 +1,39 @@ -#!/bin/bash - -# Copyright 2023 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -CAPTURE_FILE="$1" -SRC_IP="$2" -DST_IP="$3" -TLS_VERSION="$4" - -TSHARK_FILTER="ip.src==$SRC_IP and ip.dst==$DST_IP " - -if [[ $TLS_VERSION == '1.2' || -z $TLS_VERSION ]];then - TSHARK_FILTER=$TSHARK_FILTER " and ssl.handshake.type==2 and tls.handshake.type==14 " -elif [ $TLS_VERSION == '1.2' ];then - TSHARK_FILTER=$TSHARK_FILTER "and ssl.handshake.type==2 and tls.handshake.extensions.supported_version==0x0304" -fi - -response=$(tshark -r "$CAPTURE_FILE" $TSHARK_FILTER) - -echo "$response" - \ No newline at end of file +#!/bin/bash + +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +CAPTURE_FILE="$1" +SRC_IP="$2" +DST_IP="$3" +TLS_VERSION="$4" + +TSHARK_FILTER="ip.src==$SRC_IP and ip.dst==$DST_IP" + +if [[ $TLS_VERSION == '1.0' ]]; then + TSHARK_FILTER=$TSHARK_FILTER "and ssl.handshake.type==2 and tls.handshake.type==14" +elif [[ $TLS_VERSION == '1.1' ]]; then + TSHARK_FILTER=$TSHARK_FILTER "and ssl.handshake.type==2 and tls.handshake.type==14" +elif [[ $TLS_VERSION == '1.2' || -z $TLS_VERSION ]]; then + TSHARK_FILTER=$TSHARK_FILTER "and ssl.handshake.type==2 and tls.handshake.type==14" +elif [[ $TLS_VERSION == '1.3' ]]; then + TSHARK_FILTER=$TSHARK_FILTER "and ssl.handshake.type==2 and tls.handshake.extensions.supported_version==0x0304" +else + echo "Unsupported TLS version: $TLS_VERSION" + exit 1 +fi + +response=$(tshark -r "$CAPTURE_FILE" $TSHARK_FILTER) + +echo "$response" diff --git a/modules/test/tls/python/src/tls_module.py b/modules/test/tls/python/src/tls_module.py index bdc73a3fa..15859af3e 100644 --- a/modules/test/tls/python/src/tls_module.py +++ b/modules/test/tls/python/src/tls_module.py @@ -276,7 +276,22 @@ def _security_tls_v1_0_client(self): self._resolve_device_ip() # If the ipv4 address wasn't resolved yet, try again if self._device_ipv4_addr is not None: - return self._validate_tls_client(self._device_ipv4_addr, '1.0') + tls_1_0_valid = self._validate_tls_client(self._device_ipv4_addr, '1.0') + tls_1_1_valid = self._validate_tls_client(self._device_ipv4_addr, '1.1') + tls_1_2_valid = self._validate_tls_client(self._device_ipv4_addr, '1.2') + tls_1_3_valid = self._validate_tls_client(self._device_ipv4_addr, '1.3') + result_state = tls_1_0_valid[0] or tls_1_1_valid[0] or tls_1_2_valid[0] or tls_1_3_valid[0] + if result_state: + result_message = 'TLS 1.0 or higher detected' + else: + result_message = 'TLS 1.0 or higher was not detected' + result_details = tls_1_0_valid[2] + tls_1_1_valid[2] + tls_1_2_valid[2] + tls_1_3_valid[2] + result_tags = [] + result_tags.extend(tls_1_0_valid[3]) + result_tags.extend(tls_1_1_valid[3]) + result_tags.extend(tls_1_2_valid[3]) + result_tags.extend(tls_1_3_valid[3]) + return result_state, result_message, result_details, result_tags else: LOGGER.error('Could not resolve device IP address. Skipping') return 'Error', 'Could not resolve device IP address' @@ -286,7 +301,7 @@ def _security_tls_v1_2_client(self): self._resolve_device_ip() # If the ipv4 address wasn't resolved yet, try again if self._device_ipv4_addr is not None: - return self._validate_tls_client(self._device_ipv4_addr, '1.2') + return self._validate_tls_client(self._device_ipv4_addr, '1.2', unsupported_versions=['1.0','1.1']) else: LOGGER.error('Could not resolve device IP address. Skipping') return 'Error', 'Could not resolve device IP address' @@ -296,18 +311,19 @@ def _security_tls_v1_3_client(self): self._resolve_device_ip() # If the ipv4 address wasn't resolved yet, try again if self._device_ipv4_addr is not None: - return self._validate_tls_client(self._device_ipv4_addr, '1.3') + return self._validate_tls_client(self._device_ipv4_addr, '1.3', unsupported_versions=['1.0','1.1']) else: LOGGER.error('Could not resolve device IP address. Skipping') return 'Error', 'Could not resolve device IP address' - def _validate_tls_client(self, client_ip, tls_version): + def _validate_tls_client(self, client_ip, tls_version, unsupported_versions=[]): client_results = self._tls_util.validate_tls_client( client_ip=client_ip, tls_version=tls_version, capture_files=[ MONITOR_CAPTURE_FILE, STARTUP_CAPTURE_FILE, TLS_CAPTURE_FILE - ]) + ], + unsupported_versions=unsupported_versions) # Generate results based on the state result_state = None diff --git a/modules/test/tls/python/src/tls_util.py b/modules/test/tls/python/src/tls_util.py index a70215361..507b0cd36 100644 --- a/modules/test/tls/python/src/tls_util.py +++ b/modules/test/tls/python/src/tls_util.py @@ -589,36 +589,27 @@ def get_non_tls_client_connection_ips(self, client_ip, capture_files): # we will assume any local connections using the same IP subnet as our # local network are approved and only connections to IP addresses outside # our network will be flagged. - def get_unsupported_tls_ips(self, client_ip, capture_files): + def get_unsupported_tls_ips(self, client_ip, capture_files,unsupported_versions=[]): LOGGER.info('Checking client for unsupported TLS client connections') - tls_1_0_packets = self.get_tls_packets(capture_files, client_ip, '1.0') - tls_1_1_packets = self.get_tls_packets(capture_files, client_ip, '1.1') - unsupported_tls_dst_ips = {} - if len(tls_1_0_packets) > 0: - for packet in tls_1_0_packets: - dst_ip = packet['dst_ip'] - tls_version = '1.0' - if dst_ip not in unsupported_tls_dst_ips: - LOGGER.info(f'''Unsupported TLS {tls_version} - connections detected to {dst_ip}''') - unsupported_tls_dst_ips[dst_ip] = [tls_version] - - if len(tls_1_1_packets) > 0: - for packet in tls_1_1_packets: - dst_ip = packet['dst_ip'] - tls_version = '1.1' - # Check if the IP is already in the dictionary - if dst_ip in unsupported_tls_dst_ips: - # If the IP is already present, append the new TLS version to the - # list - unsupported_tls_dst_ips[dst_ip].append(tls_version) - else: - # If the IP is not present, create a new list with the current - # TLS version - LOGGER.info(f'''Unsupported TLS {tls_version} connections detected - to {dst_ip}''') - unsupported_tls_dst_ips[dst_ip] = [tls_version] + for unsupported_version in unsupported_versions: + tls_packets = self.get_tls_packets(capture_files, client_ip, '1.0') + if len(tls_packets) > 0: + for packet in tls_packets: + dst_ip = packet['dst_ip'] + tls_version = unsupported_version + if dst_ip not in unsupported_tls_dst_ips: + # If the IP is already present, append the new TLS version to the + # list + LOGGER.info(f'''Unsupported TLS {tls_version} + connections detected to {dst_ip}''') + unsupported_tls_dst_ips[dst_ip] = [tls_version] + else: + # If the IP is not present, create a new list with the current + # TLS version + LOGGER.info(f'''Unsupported TLS {tls_version} connections detected + to {dst_ip}''') + unsupported_tls_dst_ips[dst_ip] = [tls_version] return unsupported_tls_dst_ips # Check if the device has made any outbound connections that use any @@ -657,7 +648,7 @@ def is_private_ip(self, ip): return True return False - def validate_tls_client(self, client_ip, tls_version, capture_files): + def validate_tls_client(self, client_ip, tls_version, capture_files, unsupported_versions=[]): LOGGER.info('Validating client for TLS: ' + tls_version) hello_packets = self.get_hello_packets(capture_files, client_ip, tls_version) @@ -760,16 +751,13 @@ def validate_tls_client(self, client_ip, tls_version, capture_files): LOGGER.info(f'''TLS connection detected to {ip}. Ignoring non-TLS traffic detected to this IP''') - if tls_version == '1.2' || tls_version == '1.3': - # Only check TLS 1.0 and 1.1 as unsupported if we're validating - # higher TLS versions - unsupported_tls_ips = self.get_unsupported_tls_ips(client_ip, capture_files) - if len(unsupported_tls_ips) > 0: - tls_client_valid = False - for ip, tls_versions in unsupported_tls_ips.items(): - for version in tls_versions: - tls_client_details += f'''\nUnsupported TLS {version} - connection detected to {ip}''' + unsupported_tls_ips = self.get_unsupported_tls_ips(client_ip, capture_files, unsupported_versions) + if len(unsupported_tls_ips) > 0: + tls_client_valid = False + for ip, tls_versions in unsupported_tls_ips.items(): + for version in tls_versions: + tls_client_details += f'''\nUnsupported TLS {version} + connection detected to {ip}''' return tls_client_valid, tls_client_details def is_ecdh_and_ecdsa(self, ciphers): diff --git a/modules/ws/conf/mosquitto.conf b/modules/ws/conf/mosquitto.conf index 9027ba814..195079a57 100644 --- a/modules/ws/conf/mosquitto.conf +++ b/modules/ws/conf/mosquitto.conf @@ -3,7 +3,7 @@ log_dest stdout log_type all log_timestamp true -connection_messages true +connection_messages false ## MQTT Listener From f87938501395a79f2763cd1b4c5712990bba3f4f Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Tue, 17 Sep 2024 13:28:51 -0600 Subject: [PATCH 3/7] pylint --- modules/test/tls/python/src/tls_module.py | 30 ++++++++----- modules/test/tls/python/src/tls_util.py | 51 +++++++++++++---------- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/modules/test/tls/python/src/tls_module.py b/modules/test/tls/python/src/tls_module.py index 15859af3e..cb96d1b1d 100644 --- a/modules/test/tls/python/src/tls_module.py +++ b/modules/test/tls/python/src/tls_module.py @@ -26,6 +26,7 @@ GATEWAY_CAPTURE_FILE = '/runtime/network/gateway.pcap' LOGGER = None + class TLSModule(TestModule): """The TLS testing module.""" @@ -234,8 +235,8 @@ def _security_tls_v1_2_server(self): self._device_ipv4_addr, tls_version='1.2') tls_1_3_results = self._tls_util.validate_tls_server( self._device_ipv4_addr, tls_version='1.3') - results = self._tls_util.process_tls_server_results(tls_1_2_results, - tls_1_3_results) + results = self._tls_util.process_tls_server_results( + tls_1_2_results, tls_1_3_results) # Determine results and return proper messaging and details description = '' if results[0] is None: @@ -244,7 +245,7 @@ def _security_tls_v1_2_server(self): description = 'TLS 1.2 certificate is valid' else: description = 'TLS 1.2 certificate is invalid' - return results[0], description,results[1] + return results[0], description, results[1] else: LOGGER.error('Could not resolve device IP address. Skipping') @@ -256,7 +257,7 @@ def _security_tls_v1_3_server(self): # If the ipv4 address wasn't resolved yet, try again if self._device_ipv4_addr is not None: results = self._tls_util.validate_tls_server(self._device_ipv4_addr, - tls_version='1.3') + tls_version='1.3') # Determine results and return proper messaging and details description = '' if results[0] is None: @@ -265,7 +266,7 @@ def _security_tls_v1_3_server(self): description = 'TLS 1.3 certificate is valid' else: description = 'TLS 1.3 certificate is invalid' - return results[0], description,results[1] + return results[0], description, results[1] else: LOGGER.error('Could not resolve device IP address') @@ -280,12 +281,14 @@ def _security_tls_v1_0_client(self): tls_1_1_valid = self._validate_tls_client(self._device_ipv4_addr, '1.1') tls_1_2_valid = self._validate_tls_client(self._device_ipv4_addr, '1.2') tls_1_3_valid = self._validate_tls_client(self._device_ipv4_addr, '1.3') - result_state = tls_1_0_valid[0] or tls_1_1_valid[0] or tls_1_2_valid[0] or tls_1_3_valid[0] + result_state = tls_1_0_valid[0] or tls_1_1_valid[0] or tls_1_2_valid[ + 0] or tls_1_3_valid[0] if result_state: result_message = 'TLS 1.0 or higher detected' else: result_message = 'TLS 1.0 or higher was not detected' - result_details = tls_1_0_valid[2] + tls_1_1_valid[2] + tls_1_2_valid[2] + tls_1_3_valid[2] + result_details = tls_1_0_valid[2] + tls_1_1_valid[2] + tls_1_2_valid[ + 2] + tls_1_3_valid[2] result_tags = [] result_tags.extend(tls_1_0_valid[3]) result_tags.extend(tls_1_1_valid[3]) @@ -301,7 +304,9 @@ def _security_tls_v1_2_client(self): self._resolve_device_ip() # If the ipv4 address wasn't resolved yet, try again if self._device_ipv4_addr is not None: - return self._validate_tls_client(self._device_ipv4_addr, '1.2', unsupported_versions=['1.0','1.1']) + return self._validate_tls_client(self._device_ipv4_addr, + '1.2', + unsupported_versions=['1.0', '1.1']) else: LOGGER.error('Could not resolve device IP address. Skipping') return 'Error', 'Could not resolve device IP address' @@ -311,12 +316,17 @@ def _security_tls_v1_3_client(self): self._resolve_device_ip() # If the ipv4 address wasn't resolved yet, try again if self._device_ipv4_addr is not None: - return self._validate_tls_client(self._device_ipv4_addr, '1.3', unsupported_versions=['1.0','1.1']) + return self._validate_tls_client(self._device_ipv4_addr, + '1.3', + unsupported_versions=['1.0', '1.1']) else: LOGGER.error('Could not resolve device IP address. Skipping') return 'Error', 'Could not resolve device IP address' - def _validate_tls_client(self, client_ip, tls_version, unsupported_versions=[]): + def _validate_tls_client(self, + client_ip, + tls_version, + unsupported_versions=None): client_results = self._tls_util.validate_tls_client( client_ip=client_ip, tls_version=tls_version, diff --git a/modules/test/tls/python/src/tls_util.py b/modules/test/tls/python/src/tls_util.py index 507b0cd36..db3ff9123 100644 --- a/modules/test/tls/python/src/tls_util.py +++ b/modules/test/tls/python/src/tls_util.py @@ -589,27 +589,31 @@ def get_non_tls_client_connection_ips(self, client_ip, capture_files): # we will assume any local connections using the same IP subnet as our # local network are approved and only connections to IP addresses outside # our network will be flagged. - def get_unsupported_tls_ips(self, client_ip, capture_files,unsupported_versions=[]): + def get_unsupported_tls_ips(self, + client_ip, + capture_files, + unsupported_versions=None): LOGGER.info('Checking client for unsupported TLS client connections') unsupported_tls_dst_ips = {} - for unsupported_version in unsupported_versions: - tls_packets = self.get_tls_packets(capture_files, client_ip, '1.0') - if len(tls_packets) > 0: - for packet in tls_packets: - dst_ip = packet['dst_ip'] - tls_version = unsupported_version - if dst_ip not in unsupported_tls_dst_ips: - # If the IP is already present, append the new TLS version to the - # list - LOGGER.info(f'''Unsupported TLS {tls_version} - connections detected to {dst_ip}''') - unsupported_tls_dst_ips[dst_ip] = [tls_version] - else: - # If the IP is not present, create a new list with the current - # TLS version - LOGGER.info(f'''Unsupported TLS {tls_version} connections detected - to {dst_ip}''') - unsupported_tls_dst_ips[dst_ip] = [tls_version] + if unsupported_versions is not None: + for unsupported_version in unsupported_versions: + tls_packets = self.get_tls_packets(capture_files, client_ip, '1.0') + if len(tls_packets) > 0: + for packet in tls_packets: + dst_ip = packet['dst_ip'] + tls_version = unsupported_version + if dst_ip not in unsupported_tls_dst_ips: + # If the IP is already present, append the new TLS version to the + # list + LOGGER.info(f'''Unsupported TLS {tls_version} + connections detected to {dst_ip}''') + unsupported_tls_dst_ips[dst_ip] = [tls_version] + else: + # If the IP is not present, create a new list with the current + # TLS version + LOGGER.info(f'''Unsupported TLS {tls_version} connections detected + to {dst_ip}''') + unsupported_tls_dst_ips[dst_ip] = [tls_version] return unsupported_tls_dst_ips # Check if the device has made any outbound connections that use any @@ -648,7 +652,11 @@ def is_private_ip(self, ip): return True return False - def validate_tls_client(self, client_ip, tls_version, capture_files, unsupported_versions=[]): + def validate_tls_client(self, + client_ip, + tls_version, + capture_files, + unsupported_versions=None): LOGGER.info('Validating client for TLS: ' + tls_version) hello_packets = self.get_hello_packets(capture_files, client_ip, tls_version) @@ -751,7 +759,8 @@ def validate_tls_client(self, client_ip, tls_version, capture_files, unsupported LOGGER.info(f'''TLS connection detected to {ip}. Ignoring non-TLS traffic detected to this IP''') - unsupported_tls_ips = self.get_unsupported_tls_ips(client_ip, capture_files, unsupported_versions) + unsupported_tls_ips = self.get_unsupported_tls_ips(client_ip, capture_files, + unsupported_versions) if len(unsupported_tls_ips) > 0: tls_client_valid = False for ip, tls_versions in unsupported_tls_ips.items(): From d12d8a0628e0a5446bba40fba8ef9060a3661386 Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Tue, 17 Sep 2024 15:34:03 -0600 Subject: [PATCH 4/7] Fix final result calculation --- modules/test/tls/python/src/tls_module.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/modules/test/tls/python/src/tls_module.py b/modules/test/tls/python/src/tls_module.py index cb96d1b1d..2d29b89a3 100644 --- a/modules/test/tls/python/src/tls_module.py +++ b/modules/test/tls/python/src/tls_module.py @@ -281,8 +281,19 @@ def _security_tls_v1_0_client(self): tls_1_1_valid = self._validate_tls_client(self._device_ipv4_addr, '1.1') tls_1_2_valid = self._validate_tls_client(self._device_ipv4_addr, '1.2') tls_1_3_valid = self._validate_tls_client(self._device_ipv4_addr, '1.3') - result_state = tls_1_0_valid[0] or tls_1_1_valid[0] or tls_1_2_valid[ - 0] or tls_1_3_valid[0] + states = [tls_1_0_valid[0], tls_1_1_valid[0], tls_1_2_valid[0], tls_1_3_valid[0]] + if any(state is True for state in states): + # If any state is True, return True + result_state = True + elif all(state == "Feature not Detected" for state in states): + # If all states are "Feature not Detected", return "Feature not Detected" + result_state = "Feature not Detected" + elif all(state == "Error" for state in states): + # If all states are "Error", return "Error" + result_state = "Error" + else: + result_state = False + LOGGER.info(f'Result State: {result_state}') if result_state: result_message = 'TLS 1.0 or higher detected' else: From c709914b9180e85b032f6a039bee808778e1be92 Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Tue, 17 Sep 2024 15:39:32 -0600 Subject: [PATCH 5/7] pylint --- modules/test/tls/python/src/tls_module.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/test/tls/python/src/tls_module.py b/modules/test/tls/python/src/tls_module.py index 2d29b89a3..2c76b92c8 100644 --- a/modules/test/tls/python/src/tls_module.py +++ b/modules/test/tls/python/src/tls_module.py @@ -281,16 +281,18 @@ def _security_tls_v1_0_client(self): tls_1_1_valid = self._validate_tls_client(self._device_ipv4_addr, '1.1') tls_1_2_valid = self._validate_tls_client(self._device_ipv4_addr, '1.2') tls_1_3_valid = self._validate_tls_client(self._device_ipv4_addr, '1.3') - states = [tls_1_0_valid[0], tls_1_1_valid[0], tls_1_2_valid[0], tls_1_3_valid[0]] + states = [ + tls_1_0_valid[0], tls_1_1_valid[0], tls_1_2_valid[0], tls_1_3_valid[0] + ] if any(state is True for state in states): # If any state is True, return True result_state = True - elif all(state == "Feature not Detected" for state in states): - # If all states are "Feature not Detected", return "Feature not Detected" - result_state = "Feature not Detected" - elif all(state == "Error" for state in states): - # If all states are "Error", return "Error" - result_state = "Error" + elif all(state == 'Feature not Detected' for state in states): + # If all states are "Feature not Detected" + result_state = 'Feature not Detected' + elif all(state == 'Error' for state in states): + # If all states are "Error" + result_state = 'Error' else: result_state = False LOGGER.info(f'Result State: {result_state}') From 67a949cdb507677a3a743f432fd84918032bc466 Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Mon, 23 Sep 2024 09:04:53 -0600 Subject: [PATCH 6/7] Prevent duplicate tags --- modules/test/tls/python/src/tls_module.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/modules/test/tls/python/src/tls_module.py b/modules/test/tls/python/src/tls_module.py index 2c76b92c8..e1b097a74 100644 --- a/modules/test/tls/python/src/tls_module.py +++ b/modules/test/tls/python/src/tls_module.py @@ -302,11 +302,9 @@ def _security_tls_v1_0_client(self): result_message = 'TLS 1.0 or higher was not detected' result_details = tls_1_0_valid[2] + tls_1_1_valid[2] + tls_1_2_valid[ 2] + tls_1_3_valid[2] - result_tags = [] - result_tags.extend(tls_1_0_valid[3]) - result_tags.extend(tls_1_1_valid[3]) - result_tags.extend(tls_1_2_valid[3]) - result_tags.extend(tls_1_3_valid[3]) + result_tags = list( + set(tls_1_0_valid[3] + tls_1_1_valid[3] + tls_1_2_valid[3] + + tls_1_3_valid[3])) return result_state, result_message, result_details, result_tags else: LOGGER.error('Could not resolve device IP address. Skipping') From 82886cff6fc980d2bd51a4fed2fbd1ae81c6be14 Mon Sep 17 00:00:00 2001 From: jhughesbiot Date: Mon, 30 Sep 2024 16:44:41 -0600 Subject: [PATCH 7/7] Fix feature not detected result --- modules/test/tls/python/src/tls_module.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/modules/test/tls/python/src/tls_module.py b/modules/test/tls/python/src/tls_module.py index 9a368ca84..186766b17 100644 --- a/modules/test/tls/python/src/tls_module.py +++ b/modules/test/tls/python/src/tls_module.py @@ -287,18 +287,17 @@ def _security_tls_v1_0_client(self): if any(state is True for state in states): # If any state is True, return True result_state = True - elif all(state == 'Feature not Detected' for state in states): + result_message = 'TLS 1.0 or higher detected' + elif all(state == 'Feature Not Detected' for state in states): # If all states are "Feature not Detected" - result_state = 'Feature not Detected' + result_state = 'Feature Not Detected' + result_message = tls_1_0_valid[1] elif all(state == 'Error' for state in states): # If all states are "Error" result_state = 'Error' + result_message = '' else: result_state = False - LOGGER.info(f'Result State: {result_state}') - if result_state: - result_message = 'TLS 1.0 or higher detected' - else: result_message = 'TLS 1.0 or higher was not detected' result_details = tls_1_0_valid[2] + tls_1_1_valid[2] + tls_1_2_valid[ 2] + tls_1_3_valid[2]