Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions framework/python/src/common/testreport.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ def to_json(self):
details = test.details
if isinstance(details, str):
details = list(filter(lambda s: s!='', details.split('\n')))
if isinstance(details, list):
details = ' '.join(details)
test_dict = {
'name': test.name,
'description': test.description,
Expand Down
7 changes: 6 additions & 1 deletion framework/python/src/core/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,12 @@ def add_test_result(self, result):
test_result.description = result.description

# Add details to test result
test_result.details = result.details
details = result.details
if isinstance(details, str):
details = list(filter(lambda s: s!='', details.split('\n')))
if isinstance(details, list):
details = ' '.join(details)
test_result.details = details

# Add recommendations if provided
if result.recommendations is not None:
Expand Down
28 changes: 16 additions & 12 deletions modules/test/tls/python/src/tls_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ def _security_tls_v1_2_server(self):
ports_valid = []
ports_invalid = []
result = None
details = ''
details = []
description = ''
if self._device_ipv4_addr is not None:
if self._scan_results is None:
Expand All @@ -389,23 +389,23 @@ def _security_tls_v1_2_server(self):
if port_results is not None:
result = port_results[
0] if result is None else result and port_results[0]
details += port_results[1]
details.extend(port_results[1])
if port_results[0]:
ports_valid.append(port)
else:
ports_invalid.append(port)
elif 'HTTP' in service_type:
# Any non-HTTPS service detetcted is automatically invalid
ports_invalid.append(port)
details += f'\nHTTP service detected on port {port}'
details.append(f'HTTP service detected on port {port}.')
result = False
LOGGER.debug(f'Valid Ports: {ports_valid}')
LOGGER.debug(f'Invalid Ports: {ports_invalid}')
# Determine results and return proper messaging and details
if result is None:
result = 'Feature Not Detected'
description = 'TLS 1.2 certificate could not be validated'
details = 'TLS 1.2 certificate could not be validated'
details.append('TLS 1.2 certificate could not be validated.')
# If TLS 1.2 cert is not valid but TLS 1.3 is valid test is Compliant
elif result and not tls_1_2_results[0] and tls_1_3_results[0]:
ports_csv = ','.join(map(str,ports_valid))
Expand All @@ -421,7 +421,7 @@ def _security_tls_v1_2_server(self):
else:
LOGGER.error('Could not resolve device IP address. Skipping')
description = 'Could not resolve device IP address'
details = 'Could not resolve device IP address'
details.append('Could not resolve device IP address.')
return 'Error', description, details

def _security_tls_v1_3_server(self):
Expand All @@ -431,7 +431,7 @@ def _security_tls_v1_3_server(self):
ports_valid = []
ports_invalid = []
result = None
details = ''
details = []
description = ''
if self._device_ipv4_addr is not None:
if self._scan_results is None:
Expand All @@ -446,15 +446,15 @@ def _security_tls_v1_3_server(self):
if port_results is not None:
result = port_results[
0] if result is None else result and port_results[0]
details += port_results[1]
details.extend(port_results[1])
if port_results[0]:
ports_valid.append(port)
else:
ports_invalid.append(port)
elif 'HTTP' in service_type:
# Any non-HTTPS service detetcted is automatically invalid
ports_invalid.append(port)
details += f'\nHTTP service detected on port {port}'
details.append(f'HTTP service detected on port {port}.')
result = False
LOGGER.debug(f'Valid Ports: {ports_valid}')
LOGGER.debug(f'Invalid Ports: {ports_invalid}')
Expand Down Expand Up @@ -497,8 +497,12 @@ def _security_tls_v1_0_client(self):
else:
result_state = False
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 = list(
set(tls_1_0_valid[3] + tls_1_1_valid[3] + tls_1_2_valid[3] +
tls_1_3_valid[3]))
Expand Down Expand Up @@ -531,11 +535,11 @@ def _validate_tls_client(self,
# Generate results based on the state
result_state = None
result_message = ''
result_details = ''
result_details = []
result_tags = []

if client_results[0] is not None:
result_details = client_results[1]
result_details.append(client_results[1])
if client_results[0]:
result_state = True
result_message = f'TLS {tls_version} client connections valid'
Expand Down
82 changes: 53 additions & 29 deletions modules/test/tls/python/src/tls_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -381,40 +381,64 @@ def get_certificate(self, uri, timeout=10):
LOGGER.error(f'Error fetching certificate from URI: {e}')
return certificate

def process_tls_server_results(self, tls_1_2_results, tls_1_3_results, port):
def process_tls_server_results(self,
tls_1_2_results : list,
tls_1_3_results: list,
port: str) -> tuple[str| None, list]:
results = ''
details = []
positive_1_2 = '' if tls_1_2_results[0] else 'not '
positive_1_3 = '' if tls_1_3_results[0] else 'not '
if tls_1_2_results[0] is None and tls_1_3_results[0] is not None:
# Validate only TLS 1.3 results
description = (f"""TLS 1.3 {'' if tls_1_3_results[0] else 'not '}"""
f"""validated on port {port}: """
f"""{tls_1_3_results[1]}""")
results = tls_1_3_results[0], description
msg = f'TLS 1.3 {positive_1_3}validated on port {port}:'
details.append(msg)
if isinstance(tls_1_3_results[1], list):
details.extend(tls_1_3_results[1])
else:
details.append(tls_1_3_results[1])
results = tls_1_3_results[0], details
elif tls_1_3_results[0] is None and tls_1_2_results[0] is not None:
# Vaidate only TLS 1.2 results
description = (f"""TLS 1.2 {'' if tls_1_2_results[0] else 'not '}"""
f"""validated on port {port}: """
f"""{tls_1_2_results[1]}""")
results = tls_1_2_results[0], description
details.append(f'TLS 1.2 {positive_1_2}validated on port {port}:')
if isinstance(tls_1_2_results[1], list):
details.extend(tls_1_2_results[1])
else:
details.append(tls_1_2_results[1])
results = tls_1_2_results[0], details
elif tls_1_2_results[0] is not None and tls_1_3_results[0] is not None:
# Validate both results
description = (f"""TLS 1.2 {'' if tls_1_2_results[0] else 'not '}"""
f"""validated on port {port}: """
f"""{tls_1_2_results[1]}""")
description += '\n' + (
f"""TLS 1.3 {'' if tls_1_3_results[0] else 'not '}"""
f"""validated on port {port}: """
f"""{tls_1_3_results[1]}""")
results = tls_1_2_results[0] or tls_1_3_results[0], description
details.append(f'TLS 1.2 {positive_1_2}validated on port {port}:')
if isinstance(tls_1_2_results[1], list):
details.extend(tls_1_2_results[1])
else:
details.append(tls_1_2_results[1])
details.append(f'TLS 1.3 {positive_1_3}validated on port {port}:')
if isinstance(tls_1_3_results[1], list):
details.extend(tls_1_3_results[1])
else:
details.append(tls_1_3_results[1])
results = tls_1_2_results[0] or tls_1_3_results[0], details
else:
description = (f"""TLS 1.2 not validated on port {port}: """
f"""{tls_1_2_results[1]}""")
description += '\n' + (f"""TLS 1.3 not validated on port {port}: """
f"""{tls_1_3_results[1]}""")
results = None, description
details.append(f'TLS 1.2 not validated on port {port}:')
if isinstance(tls_1_2_results[1], list):
details.extend(tls_1_2_results[1])
else:
details.append(tls_1_2_results[1])
details.append(f'TLS 1.3 not validated on port {port}:')
if isinstance(tls_1_3_results[1], list):
details.extend(tls_1_3_results[1])
else:
details.append(tls_1_3_results[1])
results = None, details
LOGGER.info('TLS server test results: ' + str(results))
return results

def validate_tls_server(self, host, tls_version, port=443):
def validate_tls_server(self,
host: str,
tls_version: str,
port: int=443
) -> tuple[bool| None, list| str]:
cert_pem = self.get_public_certificate(host=host,
port=port,
validate_cert=False,
Expand Down Expand Up @@ -446,9 +470,9 @@ def validate_tls_server(self, host, tls_version, port=443):

# Check results
cert_valid = tr_valid[0] and key_valid[0] and sig_valid[0]
test_details = tr_valid[1] + '\n' + key_valid[1] + '\n' + sig_valid[1]
details = [tr_valid[1],key_valid[1], sig_valid[1]]
LOGGER.info('Certificate validated: ' + str(cert_valid))
return cert_valid, test_details
return cert_valid, details
else:
LOGGER.info('Failed to resolve public certificate')
return None, 'Failed to resolve public certificate'
Expand Down Expand Up @@ -615,7 +639,7 @@ def process_hello_packets(self,
'Allowing protocol connection, cipher check failure ignored.')
protocol_name = allowed_protocol_client_ips[packet['dst_ip']]
packet['protocol_details'] = (
f'\nAllowing {protocol_name} traffic to {packet["dst_ip"]}')
f'\nAllowing {protocol_name} traffic to {packet["dst_ip"]}') # pylint: disable=W1405
client_hello_results['valid'].append(packet)
else:
# No cipher check for TLS 1.0, 1.1 or TLS 1.3
Expand Down Expand Up @@ -826,7 +850,7 @@ def validate_tls_client(self,
f'\nAllowing non-TLS traffic to private subnet {ip}')
elif ip not in tls_client_ips:
tls_client_valid = False
tls_client_details += f'''\nNon-TLS connection detected to {ip}'''
tls_client_details += f'''Non-TLS connection detected to {ip}\n'''
else:
LOGGER.info(f'''TLS connection detected to {ip}.
Ignoring non-TLS traffic detected to this IP''')
Expand All @@ -838,8 +862,8 @@ def validate_tls_client(self,
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}'''
tls_client_details += f'''Unsupported TLS {version}
connection detected to {ip}\n'''
return tls_client_valid, tls_client_details

def is_ecdh_and_ecdsa(self, ciphers):
Expand Down
Loading