diff --git a/modules/test/tls/bin/check_cert_chain_signature.sh b/modules/test/tls/bin/check_cert_chain_signature.sh new file mode 100644 index 000000000..9bb62e7b7 --- /dev/null +++ b/modules/test/tls/bin/check_cert_chain_signature.sh @@ -0,0 +1,25 @@ +#!/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. + +INTERMEDIATE=$1 +DEVICE_CERT=$2 + +echo "ROOT: $ROOT_CERT" +echo "DEVICE_CERT: $DEVICE_CERT" + +response=$(openssl verify -untrusted $INTERMEDIATE $DEVICE_CERT) + +echo "$response" \ No newline at end of file diff --git a/modules/test/tls/python/requirements.txt b/modules/test/tls/python/requirements.txt index 719299488..147a3370c 100644 --- a/modules/test/tls/python/requirements.txt +++ b/modules/test/tls/python/requirements.txt @@ -1,4 +1,4 @@ cryptography pyOpenSSL pyshark -cryptography \ No newline at end of file +requests \ No newline at end of file diff --git a/modules/test/tls/python/src/tls_module.py b/modules/test/tls/python/src/tls_module.py index 72a6b1c92..25741c07e 100644 --- a/modules/test/tls/python/src/tls_module.py +++ b/modules/test/tls/python/src/tls_module.py @@ -253,7 +253,7 @@ def _validate_tls_client(self, client_ip, tls_version): client_ip=client_ip, tls_version=tls_version, capture_files=[ - MONITOR_CAPTURE_FILE, STARTUP_CAPTURE_FILE, GATEWAY_CAPTURE_FILE + MONITOR_CAPTURE_FILE, STARTUP_CAPTURE_FILE, TLS_CAPTURE_FILE ]) # Generate results based on the state diff --git a/modules/test/tls/python/src/tls_util.py b/modules/test/tls/python/src/tls_util.py index 3a196d5b8..26355f09a 100644 --- a/modules/test/tls/python/src/tls_util.py +++ b/modules/test/tls/python/src/tls_util.py @@ -20,6 +20,10 @@ import os from common import util import ipaddress +import requests +from cryptography import x509 +from cryptography.hazmat.backends import default_backend +from cryptography.hazmat.primitives import serialization LOG_NAME = 'tls_util' LOGGER = None @@ -39,7 +43,8 @@ def __init__(self, global LOGGER LOGGER = logger self._bin_dir = bin_dir - self._dev_cert_file = cert_out_dir + '/device_cert.crt' + self._cert_out_dir = cert_out_dir + self._dev_cert_file = 'device_cert.crt' self._root_certs_dir = root_certs_dir def get_public_certificate(self, @@ -150,6 +155,46 @@ def verify_public_key(self, public_key): return False, 'Key is not RSA or EC type' def validate_signature(self, host): + # Reconnect to the device but with validate signature option + # set to true which will check for proper cert chains + # within the valid CA root certs stored on the server + if self.validate_trusted_ca_signature(host): + LOGGER.info('Authorized Certificate Authority signature confirmed') + return True, 'Authorized Certificate Authority signature confirmed' + else: + LOGGER.info('Authorized Certificate Authority signature not present') + + device_cert_path = os.path.join(self._cert_out_dir, self._dev_cert_file) + signed, ca_file = self.validate_local_ca_signature( + device_cert_path=device_cert_path) + if signed: + return True, 'Device signed by cert:' + ca_file + return False, 'Device certificate has not been signed' + + def validate_local_ca_signature(self, device_cert_path): + bin_file = self._bin_dir + '/check_cert_signature.sh' + # Get a list of all root certificates + root_certs = os.listdir(self._root_certs_dir) + LOGGER.info('Root Certs Found: ' + str(len(root_certs))) + for root_cert in root_certs: + try: + # Create the file path + root_cert_path = os.path.join(self._root_certs_dir, root_cert) + LOGGER.info('Checking root cert: ' + str(root_cert_path)) + args = f'{root_cert_path} {device_cert_path}' + command = f'{bin_file} {args}' + response = util.run_command(command) + if f'{device_cert_path}: OK' in str(response): + LOGGER.info('Device signed by cert:' + root_cert) + return True, root_cert_path + else: + LOGGER.info('Device not signed by cert: ' + root_cert) + except Exception as e: # pylint: disable=W0718 + LOGGER.error('Failed to check cert:' + root_cert) + LOGGER.error(str(e)) + return False, None + + def validate_trusted_ca_signature(self, host): # Reconnect to the device but with validate signature option # set to true which will check for proper cert chains # within the valid CA root certs stored on the server @@ -163,47 +208,127 @@ def validate_signature(self, host): return True, 'Authorized Certificate Authority signature confirmed' else: LOGGER.info('Authorized Certificate Authority signature not present') - LOGGER.info('Resolving configured root certificates') - bin_file = self._bin_dir + '/check_cert_signature.sh' - # Get a list of all root certificates - root_certs = os.listdir(self._root_certs_dir) - LOGGER.info('Root Certs Found: ' + str(len(root_certs))) - for root_cert in root_certs: - try: - # Create the file path - root_cert_path = os.path.join(self._root_certs_dir, root_cert) - LOGGER.info('Checking root cert: ' + str(root_cert_path)) - args = f'{root_cert_path} {self._dev_cert_file}' - command = f'{bin_file} {args}' - response = util.run_command(command) - if 'device_cert.crt: OK' in str(response): - LOGGER.info('Device signed by cert:' + root_cert) - return True, 'Device signed by cert:' + root_cert - else: - LOGGER.info('Device not signed by cert: ' + root_cert) - except Exception as e: # pylint: disable=W0718 - LOGGER.error('Failed to check cert:' + root_cert) - LOGGER.error(str(e)) - return False, 'Device certificate has not been signed' + LOGGER.info('Checking for authorized CA certificate chain') + device_cert_path = os.path.join(self._cert_out_dir, self._dev_cert_file) + return self.validate_cert_chain(device_cert_path=device_cert_path) + + def validate_cert_chain(self, device_cert_path): + LOGGER.info('Validating certificate chain') + # Load the certificate from the PEM file + with open(device_cert_path, 'rb') as cert_file: + cert_bytes = cert_file.read() + + # Load pem encoding into a certifiate so we can process the contents + certificate = crypto.load_certificate(crypto.FILETYPE_PEM, cert_bytes) + + ca_issuer_cert, cert_file_path = self.get_ca_issuer(certificate) + if ca_issuer_cert is not None and cert_file_path is not None: + LOGGER.info('CA Issuer resolved') + cert_text = crypto.dump_certificate(crypto.FILETYPE_TEXT, + ca_issuer_cert).decode() + LOGGER.info(cert_text) + return self.validate_trusted_ca_signature_chain( + device_cert_path=device_cert_path, + intermediate_cert_path=cert_file_path) + else: + return False + + def validate_trusted_ca_signature_chain(self, device_cert_path, + intermediate_cert_path): + bin_file = self._bin_dir + '/check_cert_chain_signature.sh' + # Combine the device and intermediate certificates + with open(device_cert_path, 'r', encoding='utf-8') as f: + dev_cert = f.read() + with open(intermediate_cert_path, 'r', encoding='utf-8') as f: + inter_cert = f.read() + + combined_cert_name = 'device_cert_full.crt' + combined_cert = dev_cert + inter_cert + combined_cert_path = os.path.join(self._cert_out_dir, + combined_cert_name) + with open(combined_cert_path, 'w', encoding='utf-8') as f: + f.write(combined_cert) + + # Use openssl script to validate the combined certificate + # against the available trusted CA's + args = f'{intermediate_cert_path} {combined_cert_path}' + command = f'{bin_file} {args}' + response = util.run_command(command) + return combined_cert_name +': OK' in str(response) + + def get_ca_issuer(self, certificate): + cert_file_path = None + ca_issuer_cert = None + ca_issuers_uri = self.resolve_ca_issuer(certificate) + if ca_issuers_uri is not None: + ca_issuer_cert = self.get_certificate(ca_issuers_uri) + if ca_issuer_cert is not None: + # Write the intermediate certificate to file + cert_name = ca_issuers_uri.split('/')[-1] + cert_file_path = self.write_cert_to_file(cert_name, ca_issuer_cert) + return ca_issuer_cert, cert_file_path + + def resolve_ca_issuer(self, certificate): + LOGGER.info('Resolving CA Issuer') + # Print the certificate information + cert_text = crypto.dump_certificate(crypto.FILETYPE_TEXT, + certificate).decode() + # Extract 'CA Issuers - URI' field + ca_issuers_uri = None + for line in cert_text.split('\n'): + if 'CA Issuers - URI' in line: + ca_issuers_uri = line.split(':', 1)[1].strip() + break + LOGGER.info(f'CA Issuers resolved: {ca_issuers_uri}') + return ca_issuers_uri + + def get_certificate(self, uri, timeout=10): + LOGGER.info(f'Resolving certificate from {uri}') + certificate = None + try: + # Fetch the certificate file from the URI + response = requests.get(uri, timeout=timeout) + response.raise_for_status() # Raise an error for HTTP errors + + # Load the certificate from the PEM format + certificate_data = response.content + + try: + LOGGER.info('Attempting to resolve certificate in PEM format') + # Load the certificate from the PEM format + certificate = x509.load_pem_x509_certificate(certificate_data, + default_backend()) + LOGGER.info('PEM format certificate resolved') + except ValueError: + # Load the certificate from the DER format + LOGGER.info('Failed to resolve PEM format, attempting DER format') + certificate = x509.load_der_x509_certificate(certificate_data, + default_backend()) + LOGGER.info('DER format certificate resolved.') + except Exception: # pylint: disable=W0718 + LOGGER.error('Failed to load certificate in expected formats') + except requests.exceptions.RequestException as e: + 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): results = '' if tls_1_2_results[0] is None and tls_1_3_results[0] is not None: # Validate only TLS 1.3 results - description = 'TLS 1.3' + (' not' if not tls_1_3_results[ - 0] else '') + ' validated: ' + tls_1_3_results[1] + description = 'TLS 1.3' + (' not' if not tls_1_3_results[0] else + '') + ' validated: ' + tls_1_3_results[1] results = tls_1_3_results[0], description elif tls_1_3_results[0] is None and tls_1_2_results[0] is not None: # Vaidate only TLS 1.2 results - description = 'TLS 1.2' + (' not' if not tls_1_2_results[ - 0] else '') + ' validated: ' + tls_1_2_results[1] + description = 'TLS 1.2' + (' not' if not tls_1_2_results[0] else + '') + ' validated: ' + tls_1_2_results[1] results = tls_1_2_results[0], description elif tls_1_3_results[0] is not None and tls_1_2_results[0] is not None: # Validate both results - description = 'TLS 1.2' + (' not' if not tls_1_2_results[ - 0] else '') + ' validated: ' + tls_1_2_results[1] - description += '\nTLS 1.3' + (' not' if not tls_1_3_results[ - 0] else '') + ' validated: ' + tls_1_3_results[1] + description = 'TLS 1.2' + (' not' if not tls_1_2_results[0] else + '') + ' validated: ' + tls_1_2_results[1] + description += '\nTLS 1.3' + (' not' if not tls_1_3_results[0] else + '') + ' validated: ' + tls_1_3_results[1] results = tls_1_2_results[0] or tls_1_3_results[0], description else: description = f'TLS 1.2 not validated: {tls_1_2_results[1]}' @@ -219,7 +344,7 @@ def validate_tls_server(self, host, tls_version): if cert_pem: # Write pem encoding to a file - self.write_cert_to_file(cert_pem) + self.write_cert_to_file(self._dev_cert_file, cert_pem) # Load pem encoding into a certifiate so we can process the contents public_cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert_pem) @@ -249,9 +374,30 @@ def validate_tls_server(self, host, tls_version): LOGGER.info('Failed to resolve public certificate') return None, 'Failed to resolve public certificate' - def write_cert_to_file(self, pem_cert): - with open(self._dev_cert_file, 'w', encoding='UTF-8') as f: - f.write(pem_cert) + def write_cert_to_file(self, cert_name, cert): + try: + cert_file = os.path.join(self._cert_out_dir, cert_name) + if isinstance(cert, str): + with open(cert_file, 'w', encoding='UTF-8') as f: + f.write(cert) + return cert_file + elif isinstance(cert, bytes): + with open(cert_file, 'wb') as f: + f.write(cert) + return cert_file + elif isinstance(cert, x509.Certificate): + with open(cert_file, 'wb') as f: + # Serialize the certificate to PEM format + certificate_bytes = cert.public_bytes( + encoding=serialization.Encoding.PEM) + f.write(certificate_bytes) + return cert_file + else: + LOGGER.error(f'Cannot write certificate file, ' + f'unsupported content type: {type(cert)}') + except Exception as e: # pylint: disable=W0718 + LOGGER.error(f'Failed to write certificate to file: {e}') + return None def get_ciphers(self, capture_file, dst_ip, dst_port): bin_file = self._bin_dir + '/get_ciphers.sh' @@ -537,8 +683,8 @@ def validate_tls_client(self, client_ip, tls_version, capture_files): if len(unsupported_tls_ips) > 0: tls_client_valid = False for ip, tls_versions in unsupported_tls_ips.items(): - for tls_version in tls_versions: - tls_client_details += f'''\nUnsupported TLS {tls_version} + for version in tls_versions: + tls_client_details += f'''\nUnsupported TLS {version} connection detected to {ip}''' return tls_client_valid, tls_client_details diff --git a/testing/unit/tls/CertAuth/TestRun_CA_Root.key b/testing/unit/tls/CertAuth/TestRun_CA_Root.key new file mode 100644 index 000000000..47abe7908 --- /dev/null +++ b/testing/unit/tls/CertAuth/TestRun_CA_Root.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAwAcDvl19KuhNYsrIkiQcaPlyCwcYNtBzE3TBnOCncreYJtZn +5FyAS9VzRkTxDS6Ff08tCthJ5nsVS5ZVPNu4X+ZG9vWEUs1m+cEHdbaXsWdgZ49x +U2/15mnHo/DqOFhfz8SmdZpGA5kKe+4etcyaW6KFml9wHY2KZqyokMY1ehAMcpGM +1S16rnmHnK2tyAM27ro7x0CcMSq0G24SWlEK7WGOQindwY6gFND16rpR43xj8Tmr +vkAPs5BrALvw2bkXcZO1Tjex9wke8sGVet7pfP91VA5UGD0pDqtoQaOdCsyDVyeA +RZdFe6tN0bt3T0cbLKqedkM4PAYIBbincabnAwIDAQABAoIBAQCoVD3S3Q8A0twr +UslZWjBRUQDIa/Ks8jM+BeZGx6PhatEEkoRF6VRJpZXELmEEBhjeDaDVVd4KHTEA +roqPq6fG4QyqJXRWRVoUa0JHzMTSrWUTwuk7k/SBg46Oxnv64nUyoxasFo1zT++h +zY28Hdvdoezt8uVL8qw07vtg1W9BTFIsMFSJTwere8OZwBWMpb8Vfh94hkCZV77E +K+vdQNRAArrMTeDGO27T7u5Qrgv9sA7a9/jUSDwchrVLLP4WVVyHeJ2uvB865NQm +8o7+H6LGbvdWedeXoN9Yc5QUtbUyrh3EcdV0M5TlBk8Z/fUT8zHdxQI+RMgfz+E/ +pbV8yuF5AoGBAPx7RvB9XEHqRGQvsDqVnxkKkDDE/Bq0OIHLWF5CajLnnhEtM+oJ +sNZnxmRM5VK8X+O5s/1X1Gp9wcgf9+lZxTy27TKM/Gbgaq2aDYeUzUpO6OFuCcps +25GMzrFQRb1gB2dlqhmk7t0L362L6OMpFqSq9htpIkhu/NowqZ6e1jr3AoGBAMK0 +EYv6L+RqBKIRCg4WqesxXsJXBRg2wY/XxCyOF8rJ3U3FYnsKl+pcKMIJ3V8IL4NB +furxv/nNSPrgyowk1Olj+B6cWDxrMQSWOdT5HbB/CO38bUGlvyFntaHMF5Zu8MuG +i2p1ragm80D7SgU5SqAqyffWEZMfzKohDJrzdYVVAoGBAN1MpHI4PvwbfVSfJAVF +jcziIF5O2nYBjyHc/Ripd/IkZ7zAdSdm1RQoo5DYgYySRi4RYDznley9S3PA6Ygk +QigkYiWTw8vcWkTNqZw0Bfhiz+Z/j59Y6N9bnvN125rQp8yuJHkTwrYHKUgxQLCT +HCC7JLoD3aPFfGU2kAXTTQ0jAoGAbh9AiWYw7kTUaAGxKTTCWEbtLIfhVsephLzp +tLWNWWIBLDqGr8bXE3OajdzceyJ7FQbXTPT8usHUFClOBiPS1Ep5jH6rHUkXSVva +S822cBv5pfkOpoGjb7ZjsaZodOo8gTCQ696xIJkfHlLCk9/KiHqLDwThnc/vhw34 +Pi+S+Z0CgYEAo/rlxKuUryz96By9UKHNVZxKJhQ9bAyaQLtLHru72kNr8tCZqShF +iB3cuU+fQE1rcxsIqhOiRUdDy8vRFQdcR5XmESU0XvpxIEWlTCS96A2zl5J1OEVD +Sz/EsFII2P1Corpfsv6BI8zV4Q5/IligHzAI7+Bg6LkuYW93e8hX4bE= +-----END RSA PRIVATE KEY----- diff --git a/testing/unit/tls/CertAuth/Testrun_CA_Root.crt b/testing/unit/tls/CertAuth/Testrun_CA_Root.crt new file mode 100644 index 000000000..24f5bbe78 --- /dev/null +++ b/testing/unit/tls/CertAuth/Testrun_CA_Root.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkTCCAnkCFEVPbtILjbdASrq6LFIB3o2rIIDhMA0GCSqGSIb3DQEBCwUAMIGE +MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMTW91 +bnRhaW5WaWV3MRAwDgYDVQQKDAdUZXN0cnVuMRYwFAYDVQQLDA1RdWFsaWZpY2F0 +aW9uMR8wHQYDVQQDDBZUZXN0cnVuIFJTQSBTaWduaW5nIENBMB4XDTI0MDMyMDIw +MzUwNVoXDTM0MDMyMDIwMzUwNVowgYQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApD +YWxpZm9ybmlhMRUwEwYDVQQHDAxNb3VudGFpblZpZXcxEDAOBgNVBAoMB1Rlc3Ry +dW4xFjAUBgNVBAsMDVF1YWxpZmljYXRpb24xHzAdBgNVBAMMFlRlc3RydW4gUlNB +IFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDABwO+ +XX0q6E1iysiSJBxo+XILBxg20HMTdMGc4Kdyt5gm1mfkXIBL1XNGRPENLoV/Ty0K +2EnmexVLllU827hf5kb29YRSzWb5wQd1tpexZ2Bnj3FTb/Xmacej8Oo4WF/PxKZ1 +mkYDmQp77h61zJpbooWaX3AdjYpmrKiQxjV6EAxykYzVLXqueYecra3IAzbuujvH +QJwxKrQbbhJaUQrtYY5CKd3BjqAU0PXqulHjfGPxOau+QA+zkGsAu/DZuRdxk7VO +N7H3CR7ywZV63ul8/3VUDlQYPSkOq2hBo50KzINXJ4BFl0V7q03Ru3dPRxssqp52 +Qzg8BggFuKdxpucDAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAInXBKcbZI5kKl6m +2IVGWWW0SPye/4uLwtLUJtHGAAxeISjwdiiebVqcwZTHoJ4qnPKd3OMdGFvEWMPi +vI1I/j4JFraD2Q885MhitVkmx59OCLNSR6QGtVqu6E73KADL92KZTE7Gdb2DtqpX +zf2mz8MukSeMI7NZI7hp599DAj50N4mnQZPDJfuE+jTBjuSh7oay1x1m6N1eZZRT +lFMWH2fXjlknpCpIVAcFYo3dEZsGl04z/NiQZrODBlt6CxheGwdbOXy/wPulkZ9R +v9A7sLrK9rDih2qZGjWpbexTrlFlvC4z2UN/gh6P3IR8QuUv75MjPqQmQ9/9SV0+ +UrVwBdw= +-----END CERTIFICATE----- diff --git a/testing/unit/tls/CertAuth/Testrun_CA_Root.csr b/testing/unit/tls/CertAuth/Testrun_CA_Root.csr new file mode 100644 index 000000000..57b7a133c --- /dev/null +++ b/testing/unit/tls/CertAuth/Testrun_CA_Root.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICyjCCAbICAQAwgYQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlh +MRUwEwYDVQQHDAxNb3VudGFpblZpZXcxEDAOBgNVBAoMB1Rlc3RydW4xFjAUBgNV +BAsMDVF1YWxpZmljYXRpb24xHzAdBgNVBAMMFlRlc3RydW4gUlNBIFNpZ25pbmcg +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDABwO+XX0q6E1iysiS +JBxo+XILBxg20HMTdMGc4Kdyt5gm1mfkXIBL1XNGRPENLoV/Ty0K2EnmexVLllU8 +27hf5kb29YRSzWb5wQd1tpexZ2Bnj3FTb/Xmacej8Oo4WF/PxKZ1mkYDmQp77h61 +zJpbooWaX3AdjYpmrKiQxjV6EAxykYzVLXqueYecra3IAzbuujvHQJwxKrQbbhJa +UQrtYY5CKd3BjqAU0PXqulHjfGPxOau+QA+zkGsAu/DZuRdxk7VON7H3CR7ywZV6 +3ul8/3VUDlQYPSkOq2hBo50KzINXJ4BFl0V7q03Ru3dPRxssqp52Qzg8BggFuKdx +pucDAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAZBPnCRmf8mmQr26XJWOri/EU +B+PXPQ1CZInULKAC2g+Eyz279Bx/73kQ/+G++4p2XTiHzLH6V3d0sQzTmNKm7fz9 +jGuHSLkRYlo983dlTmnJTKdE+Z9heMbzIYuusbgt8SshHQejUxLpZ7muB+Kcg5wE +andVgm4RY8sz9/Hwk1GRaMFjEeeOcN3S6ZAs086BWfsG/2rJbntPabA9GDNvdfqJ +pp8opOB7p0Uxfy3eYEYNWdEp4s2JwaEoAWDFI2gHeawIbJ/cldY5YOg7AHY9nl8I +XcdcV1mreAlrrZhODqg0EatUokgAyR1KDPIt4q6ME5nqjEjLaE3+dy7kGgbYWg== +-----END CERTIFICATE REQUEST----- diff --git a/testing/unit/tls/CertAuth/Testrun_CA_Root.srl b/testing/unit/tls/CertAuth/Testrun_CA_Root.srl new file mode 100644 index 000000000..4a41a67ef --- /dev/null +++ b/testing/unit/tls/CertAuth/Testrun_CA_Root.srl @@ -0,0 +1 @@ +31B6EB0B91479F0EC0DFC4D82787EB2736DF6908 diff --git a/testing/unit/tls/CertAuth/device_cert_local.crt b/testing/unit/tls/CertAuth/device_cert_local.crt new file mode 100644 index 000000000..594bc2154 --- /dev/null +++ b/testing/unit/tls/CertAuth/device_cert_local.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDizCCAnMCFDG26wuRR58OwN/E2CeH6yc232kIMA0GCSqGSIb3DQEBCwUAMIGE +MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMTW91 +bnRhaW5WaWV3MRAwDgYDVQQKDAdUZXN0cnVuMRYwFAYDVQQLDA1RdWFsaWZpY2F0 +aW9uMR8wHQYDVQQDDBZUZXN0cnVuIFJTQSBTaWduaW5nIENBMB4XDTI0MDMyMDIw +MzYxMFoXDTI5MDMyMDIwMzYxMFowfzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh +bGlmb3JuaWExFTATBgNVBAcMDE1vdW50YWluVmlldzEQMA4GA1UECgwHVGVzdHJ1 +bjEWMBQGA1UECwwNUXVhbGlmaWNhdGlvbjEaMBgGA1UEAwwRZGV2aWNlX2NlcnRf +bG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJepNW0Aag19mp +a0DwbTupjsQPuQPxhXQ+0fEHNHycuPxW7MDlpeTfVC1tPlBu/X6uK3yCYco1YDEv +tTXYBELjnHUynnCh/ZKcoGMBO+wo3q/ppU2PC8E9wKwH0R070OzKj0U2LR2wHiLN +x4HpUAbrP/aH7qS9tNswqL/oE+dsPzpa2JY3a8dpUHa/x7iVmasasLrteht3Iz84 +9QLki9O1vUGA5jTKx9CAymIZGFf19gJ3qiqIPNvY6a6cv5ACykTYOTn/X3LOK8Zu +Vv7/8M5z8Uf/t4bVK5wyIo+KBG7L1tpYjuGLrAOqOauNgsrUD2DQbsNds4Evjpt9 +dItalZtjAgMBAAEwDQYJKoZIhvcNAQELBQADggEBALkVmv0pwISSckgbCJ9Y16iu +I/qzNUmrBX/O36pXFDYj++YDWQyAXxrFK2mb8+wE5VjtnW+XIYQ5HMD65xaajqjC +14Rq9n7nSH1WvXBRVyOZLO/iXabofqpNZq/8t8I6Gwr7nDLui8g41Aa6UCzqO+vu +ud07PUDj3TwFcE3YBU9oT9Cxbu9dgFWEu53hO2+Wef9V5MYAOvsiaakUy4sxyEvn +SrRpTR5x25TahIM9AfuDIBAeQGsw0q0Pl10JY4n+Z+rFvc6yvuzsmZCzqZiQGiC7 +jkgjxxuR2aKopXoC1sKZ5NhueNkXQjnYwebQp+gkoDamoEIUHMVjCm1bvOu9M/Q= +-----END CERTIFICATE----- diff --git a/testing/unit/tls/CertAuth/device_cert_local.csr b/testing/unit/tls/CertAuth/device_cert_local.csr new file mode 100644 index 000000000..77830e716 --- /dev/null +++ b/testing/unit/tls/CertAuth/device_cert_local.csr @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICxDCCAawCAQAwfzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx +FTATBgNVBAcMDE1vdW50YWluVmlldzEQMA4GA1UECgwHVGVzdHJ1bjEWMBQGA1UE +CwwNUXVhbGlmaWNhdGlvbjEaMBgGA1UEAwwRZGV2aWNlX2NlcnRfbG9jYWwwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJepNW0Aag19mpa0DwbTupjsQP +uQPxhXQ+0fEHNHycuPxW7MDlpeTfVC1tPlBu/X6uK3yCYco1YDEvtTXYBELjnHUy +nnCh/ZKcoGMBO+wo3q/ppU2PC8E9wKwH0R070OzKj0U2LR2wHiLNx4HpUAbrP/aH +7qS9tNswqL/oE+dsPzpa2JY3a8dpUHa/x7iVmasasLrteht3Iz849QLki9O1vUGA +5jTKx9CAymIZGFf19gJ3qiqIPNvY6a6cv5ACykTYOTn/X3LOK8ZuVv7/8M5z8Uf/ +t4bVK5wyIo+KBG7L1tpYjuGLrAOqOauNgsrUD2DQbsNds4Evjpt9dItalZtjAgMB +AAGgADANBgkqhkiG9w0BAQsFAAOCAQEAilL337tVPh+cZl2jY5FCeNRBJ8thfgfZ +95qcQsV0QmZgeDVmYRPl2N23v+lyM0KPDyRVG4MJCMH4SanBWftAjnTe17rroXO4 +/+tfDPpseH5FrwdbrYM6pixqWxhVttWGFkPCg9Yl/wKtSh6+IMN9I5CVFjmIPIVS +0NviJ/H4yuv0gSZ2mXs+fWAC7TpbBlVSU8L4DzdyMJZ+w1xxK8Q4vQ40wQYPjZG5 +5Dfm5MDG+vhO8+9wYW5kUH/bPd4F47j80Sivc6DxxDgtITRbxlV1dwFwagpYRNcx +yOKJyUiL4YH3IRT6VCFJ28TNab3QHFrJyS/MlnEJJOuCBY9GAl6GBg== +-----END CERTIFICATE REQUEST----- diff --git a/testing/unit/tls/CertAuth/device_cert_local.key b/testing/unit/tls/CertAuth/device_cert_local.key new file mode 100644 index 000000000..f4051a82d --- /dev/null +++ b/testing/unit/tls/CertAuth/device_cert_local.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAyXqTVtAGoNfZqWtA8G07qY7ED7kD8YV0PtHxBzR8nLj8VuzA +5aXk31QtbT5Qbv1+rit8gmHKNWAxL7U12ARC45x1Mp5wof2SnKBjATvsKN6v6aVN +jwvBPcCsB9EdO9Dsyo9FNi0dsB4izceB6VAG6z/2h+6kvbTbMKi/6BPnbD86WtiW +N2vHaVB2v8e4lZmrGrC67XobdyM/OPUC5IvTtb1BgOY0ysfQgMpiGRhX9fYCd6oq +iDzb2OmunL+QAspE2Dk5/19yzivGblb+//DOc/FH/7eG1SucMiKPigRuy9baWI7h +i6wDqjmrjYLK1A9g0G7DXbOBL46bfXSLWpWbYwIDAQABAoIBAQCjdZDoE6ntAHIU +43EyHk0TSUKDxwUOA8nF1aoIwGqA9Au1sirlpevDzJV2VeIHyh3mzF0dopzdJQeC +vy/J69sgsqTaxnR22DUEYZMxQx5cIh7yHiyIa28B3Lk1NlDTYLNbu1TZmUzGwAxY +iw447bZPUft/WPvK9VoHZkEb1lohFNIsiOu09uNRly5K6Xk0vPx2eoWPzkMf9mqU +OWnZGvUiNF5pJgdgWd/R6hbhNcKZQ5PXYVQcD3NOiy261JPG6eVhsRhP9b/oxPZi +zeyuKHdmW5D5HZbtol1lxOoFliZveMDAgkIewlB0sjF8OYCIlp/k+2WSJRyrdqMt +Md2sDeSxAoGBAO2uOvwTKJthSQO7Lcl41Q1siU+s8zB90R4Zrx9YtWAx5b1dxMI+ +hgfGrp5mak+pXOEau/27Ob7RM2bxswRjbqQJWz3KYgSCbBiGDd6c+OgP/AQHrGXz +yknUjyvs4LQGAh3KIOzS/6IUEZmd4fWJU+FKovFbCAIK6TYmaVv1y7iFAoGBANkC +CJgeuPpSVmR1LkkPeAHvfD60V3z3LPdxUPjYG+hYEY9M1XffBDPijYEQtW3FFN0s +BrQqX0fBlnZ6ITUVr8nZ16sQVv7QErCJjxFnGAkjqryJVxN16x/ZPHSAZQva2yiJ +D59XZ17T4ODcthADGkncALZlL5mGck7u2PuAMjzHAoGAIlZVdy1dZHU9kyhriPvH +69SOUdBuocbLe0nCnwi1y1vqEN2HG3jk7CKr/35URYX2QR8XoaR2xzZ58plgf3XN ++izP3bFrT7N34mMbhdmvq/cDNaHWKjR6OQhYVsQ2AkwL6jnVX+FrxQKZOFQy3MIm +OBoMSEoachEZeBU8i2iLMfECgYBV1xwXMG/zdQZ/jmrUs63A9j6rfyLsZ8n9x3FE +Phgr/EpV6Qq39BvxejiHSVi7Jy5tnrC4K9qsw8ME8qKYIQ/8RJOvMzN2cFA0TPWu +6Jz1YIp1Mc6kAA0V+BSV8QQHgHcYvb7URPq65A0cZbIO+2s2tDQD8lq13BzzZD+o +nLlCmQKBgQDUEc6dKO8IYuGFX+l9qDW5oAliKPePWI2Jaj3miu2Vo8ha1l1Hmii3 +6Gh6Bv+b6MCo5m1DNOZIQxXnZmxU0XvCdOJ8NNMOV5gzaPu2X3vqeoZX77k3YVLH +E9Cfy6qJZlZD9CiLiENUfU+iE/oB83pPm5mdgopEQYujljddPMNiaQ== +-----END RSA PRIVATE KEY----- diff --git a/testing/unit/tls/CertAuth/generateCA.sh b/testing/unit/tls/CertAuth/generateCA.sh new file mode 100644 index 000000000..51b54d44c --- /dev/null +++ b/testing/unit/tls/CertAuth/generateCA.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +#Generate new unencrypted private key +openssl genrsa -out Testrun_CA_Root.key 2048 + +#Generate a new csr. +openssl req -new -key Testrun_CA_Root.key -out Testrun_CA_Root.csr -subj "/C=US/ST=California/L=MountainView/O=Testrun/OU=Qualification/CN=Testrun RSA Signing CA" + +#Generate and self sign the CA cert +openssl x509 -req -days 3652 -in Testrun_CA_Root.csr -signkey Testrun_CA_Root.key -sha256 -out Testrun_CA_Root.crt + +#Copy the generated cirt to the local root_certs directory +cp Testrun_CA_Root.crt ../root_certs \ No newline at end of file diff --git a/testing/unit/tls/CertAuth/generateLocalCert.sh b/testing/unit/tls/CertAuth/generateLocalCert.sh new file mode 100644 index 000000000..a3c340445 --- /dev/null +++ b/testing/unit/tls/CertAuth/generateLocalCert.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +# Helper script to generate the local certificate +# used for unit testing. This script should be run +# directly from the directory where it lives for +# proper CA certificate resolving during signing process + +CA_ROOT_CERT_NAME="Testrun_CA_Root" +CA_ROOT_DIR="." +CA_ROOT_KEY=$CA_ROOT_DIR/$CA_ROOT_CERT_NAME.key +CA_ROOT_CERT=$CA_ROOT_DIR/$CA_ROOT_CERT_NAME.crt + + +CERT_NAME="device_cert_local" + +#Generate the private key +openssl genrsa -out $CERT_NAME.key 2048 + +#Generate the CSR +openssl req -new -key $CERT_NAME.key -out $CERT_NAME.csr -subj "/C=US/ST=California/L=MountainView/O=Testrun/OU=Qualification/CN=$CERT_NAME" + +#Generate and sign the certificate with the local CA +openssl x509 -req -days 1826 -in $CERT_NAME.csr -CA $CA_ROOT_CERT -CAkey $CA_ROOT_KEY -CAcreateserial -out $CERT_NAME.crt + +cp $CERT_NAME.crt ../certs \ No newline at end of file diff --git a/testing/unit/tls/certs/_.google.com.crt b/testing/unit/tls/certs/_.google.com.crt new file mode 100644 index 000000000..8c5519fa3 --- /dev/null +++ b/testing/unit/tls/certs/_.google.com.crt @@ -0,0 +1,79 @@ +-----BEGIN CERTIFICATE----- +MIIOXTCCDUWgAwIBAgIRAJF3iEqsDpoECedLdRgGyygwDQYJKoZIhvcNAQELBQAw +RjELMAkGA1UEBhMCVVMxIjAgBgNVBAoTGUdvb2dsZSBUcnVzdCBTZXJ2aWNlcyBM +TEMxEzARBgNVBAMTCkdUUyBDQSAxQzMwHhcNMjQwMjE5MDgwMzU0WhcNMjQwNTEz +MDgwMzUzWjAXMRUwEwYDVQQDDAwqLmdvb2dsZS5jb20wWTATBgcqhkjOPQIBBggq +hkjOPQMBBwNCAAQ7UkR1HmtagYbBBsPVqVik2xZO85oyD4jqvtxb2zKUdBCN3n+E +YFxtMs4KiRDvMzp3C/xWfNaMoF3X7/sDUm3ro4IMPjCCDDowDgYDVR0PAQH/BAQD +AgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYE +FO620PFJar/4etLB8PcVeSgTJybuMB8GA1UdIwQYMBaAFIp0f6+Fze6VzT2c0OJG +FPNxNR0nMGoGCCsGAQUFBwEBBF4wXDAnBggrBgEFBQcwAYYbaHR0cDovL29jc3Au +cGtpLmdvb2cvZ3RzMWMzMDEGCCsGAQUFBzAChiVodHRwOi8vcGtpLmdvb2cvcmVw +by9jZXJ0cy9ndHMxYzMuZGVyMIIJ7wYDVR0RBIIJ5jCCCeKCDCouZ29vZ2xlLmNv +bYIWKi5hcHBlbmdpbmUuZ29vZ2xlLmNvbYIJKi5iZG4uZGV2ghUqLm9yaWdpbi10 +ZXN0LmJkbi5kZXaCEiouY2xvdWQuZ29vZ2xlLmNvbYIYKi5jcm93ZHNvdXJjZS5n +b29nbGUuY29tghgqLmRhdGFjb21wdXRlLmdvb2dsZS5jb22CCyouZ29vZ2xlLmNh +ggsqLmdvb2dsZS5jbIIOKi5nb29nbGUuY28uaW6CDiouZ29vZ2xlLmNvLmpwgg4q +Lmdvb2dsZS5jby51a4IPKi5nb29nbGUuY29tLmFygg8qLmdvb2dsZS5jb20uYXWC +DyouZ29vZ2xlLmNvbS5icoIPKi5nb29nbGUuY29tLmNvgg8qLmdvb2dsZS5jb20u +bXiCDyouZ29vZ2xlLmNvbS50coIPKi5nb29nbGUuY29tLnZuggsqLmdvb2dsZS5k +ZYILKi5nb29nbGUuZXOCCyouZ29vZ2xlLmZyggsqLmdvb2dsZS5odYILKi5nb29n +bGUuaXSCCyouZ29vZ2xlLm5sggsqLmdvb2dsZS5wbIILKi5nb29nbGUucHSCDyou +Z29vZ2xlYXBpcy5jboIRKi5nb29nbGV2aWRlby5jb22CDCouZ3N0YXRpYy5jboIQ +Ki5nc3RhdGljLWNuLmNvbYIPZ29vZ2xlY25hcHBzLmNughEqLmdvb2dsZWNuYXBw +cy5jboIRZ29vZ2xlYXBwcy1jbi5jb22CEyouZ29vZ2xlYXBwcy1jbi5jb22CDGdr +ZWNuYXBwcy5jboIOKi5na2VjbmFwcHMuY26CEmdvb2dsZWRvd25sb2Fkcy5jboIU +Ki5nb29nbGVkb3dubG9hZHMuY26CEHJlY2FwdGNoYS5uZXQuY26CEioucmVjYXB0 +Y2hhLm5ldC5jboIQcmVjYXB0Y2hhLWNuLm5ldIISKi5yZWNhcHRjaGEtY24ubmV0 +ggt3aWRldmluZS5jboINKi53aWRldmluZS5jboIRYW1wcHJvamVjdC5vcmcuY26C +EyouYW1wcHJvamVjdC5vcmcuY26CEWFtcHByb2plY3QubmV0LmNughMqLmFtcHBy +b2plY3QubmV0LmNughdnb29nbGUtYW5hbHl0aWNzLWNuLmNvbYIZKi5nb29nbGUt +YW5hbHl0aWNzLWNuLmNvbYIXZ29vZ2xlYWRzZXJ2aWNlcy1jbi5jb22CGSouZ29v +Z2xlYWRzZXJ2aWNlcy1jbi5jb22CEWdvb2dsZXZhZHMtY24uY29tghMqLmdvb2ds +ZXZhZHMtY24uY29tghFnb29nbGVhcGlzLWNuLmNvbYITKi5nb29nbGVhcGlzLWNu +LmNvbYIVZ29vZ2xlb3B0aW1pemUtY24uY29tghcqLmdvb2dsZW9wdGltaXplLWNu +LmNvbYISZG91YmxlY2xpY2stY24ubmV0ghQqLmRvdWJsZWNsaWNrLWNuLm5ldIIY +Ki5mbHMuZG91YmxlY2xpY2stY24ubmV0ghYqLmcuZG91YmxlY2xpY2stY24ubmV0 +gg5kb3VibGVjbGljay5jboIQKi5kb3VibGVjbGljay5jboIUKi5mbHMuZG91Ymxl +Y2xpY2suY26CEiouZy5kb3VibGVjbGljay5jboIRZGFydHNlYXJjaC1jbi5uZXSC +EyouZGFydHNlYXJjaC1jbi5uZXSCHWdvb2dsZXRyYXZlbGFkc2VydmljZXMtY24u +Y29tgh8qLmdvb2dsZXRyYXZlbGFkc2VydmljZXMtY24uY29tghhnb29nbGV0YWdz +ZXJ2aWNlcy1jbi5jb22CGiouZ29vZ2xldGFnc2VydmljZXMtY24uY29tghdnb29n +bGV0YWdtYW5hZ2VyLWNuLmNvbYIZKi5nb29nbGV0YWdtYW5hZ2VyLWNuLmNvbYIY +Z29vZ2xlc3luZGljYXRpb24tY24uY29tghoqLmdvb2dsZXN5bmRpY2F0aW9uLWNu +LmNvbYIkKi5zYWZlZnJhbWUuZ29vZ2xlc3luZGljYXRpb24tY24uY29tghZhcHAt +bWVhc3VyZW1lbnQtY24uY29tghgqLmFwcC1tZWFzdXJlbWVudC1jbi5jb22CC2d2 +dDEtY24uY29tgg0qLmd2dDEtY24uY29tggtndnQyLWNuLmNvbYINKi5ndnQyLWNu +LmNvbYILMm1kbi1jbi5uZXSCDSouMm1kbi1jbi5uZXSCFGdvb2dsZWZsaWdodHMt +Y24ubmV0ghYqLmdvb2dsZWZsaWdodHMtY24ubmV0ggxhZG1vYi1jbi5jb22CDiou +YWRtb2ItY24uY29tghRnb29nbGVzYW5kYm94LWNuLmNvbYIWKi5nb29nbGVzYW5k +Ym94LWNuLmNvbYIeKi5zYWZlbnVwLmdvb2dsZXNhbmRib3gtY24uY29tgg0qLmdz +dGF0aWMuY29tghQqLm1ldHJpYy5nc3RhdGljLmNvbYIKKi5ndnQxLmNvbYIRKi5n +Y3BjZG4uZ3Z0MS5jb22CCiouZ3Z0Mi5jb22CDiouZ2NwLmd2dDIuY29tghAqLnVy +bC5nb29nbGUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tggsqLnl0aW1nLmNv +bYILYW5kcm9pZC5jb22CDSouYW5kcm9pZC5jb22CEyouZmxhc2guYW5kcm9pZC5j +b22CBGcuY26CBiouZy5jboIEZy5jb4IGKi5nLmNvggZnb28uZ2yCCnd3dy5nb28u +Z2yCFGdvb2dsZS1hbmFseXRpY3MuY29tghYqLmdvb2dsZS1hbmFseXRpY3MuY29t +ggpnb29nbGUuY29tghJnb29nbGVjb21tZXJjZS5jb22CFCouZ29vZ2xlY29tbWVy +Y2UuY29tgghnZ3BodC5jboIKKi5nZ3BodC5jboIKdXJjaGluLmNvbYIMKi51cmNo +aW4uY29tggh5b3V0dS5iZYILeW91dHViZS5jb22CDSoueW91dHViZS5jb22CFHlv +dXR1YmVlZHVjYXRpb24uY29tghYqLnlvdXR1YmVlZHVjYXRpb24uY29tgg95b3V0 +dWJla2lkcy5jb22CESoueW91dHViZWtpZHMuY29tggV5dC5iZYIHKi55dC5iZYIa +YW5kcm9pZC5jbGllbnRzLmdvb2dsZS5jb22CG2RldmVsb3Blci5hbmRyb2lkLmdv +b2dsZS5jboIcZGV2ZWxvcGVycy5hbmRyb2lkLmdvb2dsZS5jboIYc291cmNlLmFu +ZHJvaWQuZ29vZ2xlLmNughpkZXZlbG9wZXIuY2hyb21lLmdvb2dsZS5jboIYd2Vi +LmRldmVsb3BlcnMuZ29vZ2xlLmNuMCEGA1UdIAQaMBgwCAYGZ4EMAQIBMAwGCisG +AQQB1nkCBQMwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybHMucGtpLmdvb2cv +Z3RzMWMzL2ZWSnhiVi1LdG1rLmNybDCCAQMGCisGAQQB1nkCBAIEgfQEgfEA7wB1 +ADtTd3U+LbmAToswWwb+QDtn2E/D9Me9AA0tcm/h+tQXAAABjcCbl6wAAAQDAEYw +RAIgSsPqmrwU1+TmKxlq0lWFp8HhAWMNr8TpdCsZZ2hIZIQCIHHVd134qMevyD/v +xTWo8mVLjIJIbBUcO8Lm0alcvvkXAHYAdv+IPwq2+5VRwmHM9Ye6NLSkzbsp3GhC +Cp/mZ0xaOnQAAAGNwJuV/QAABAMARzBFAiA90a0s0Fw86i60HTH7XDtVIHnOE9sr +iosICjMRaNAzHgIhANdDshIUQaZkQM2lWPLTvmT3DKZqVMFnA5Aq425HslpPMA0G +CSqGSIb3DQEBCwUAA4IBAQBAjDmy7+UAyQqr2eYerPnwfAaSkD+3kcrbCW0Z656D +rejG3DE2yJ3q/Ao8OqZfg5hC/YpOaMvZMTwvdmLb6urWpgGdgEGVaWW+SHGrckVJ +scLqOVJ1ceXWMhMnp5QHtIhMHsBVwKPT+QM058b6oro2xamIACbAGC6eaem/TF0e +05holHHlBFPZk94PdLfB9f+nzobuWk6K+IaNihsCSgea5C31W1eWW9sE9Z9i3UXa +jbkTdgNtgRKT5HOoz4V+VPeR4uR/VBrQLrx1FsdICP6fCzG4lj1k9dJl3BLRk4xk +RJvLoyFyoRJMiqSpMcxNg7YTgK1ttUUj5BWT6rofaTxp +-----END CERTIFICATE----- diff --git a/testing/unit/tls/certs/device_cert_local.crt b/testing/unit/tls/certs/device_cert_local.crt new file mode 100644 index 000000000..594bc2154 --- /dev/null +++ b/testing/unit/tls/certs/device_cert_local.crt @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDizCCAnMCFDG26wuRR58OwN/E2CeH6yc232kIMA0GCSqGSIb3DQEBCwUAMIGE +MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMTW91 +bnRhaW5WaWV3MRAwDgYDVQQKDAdUZXN0cnVuMRYwFAYDVQQLDA1RdWFsaWZpY2F0 +aW9uMR8wHQYDVQQDDBZUZXN0cnVuIFJTQSBTaWduaW5nIENBMB4XDTI0MDMyMDIw +MzYxMFoXDTI5MDMyMDIwMzYxMFowfzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNh +bGlmb3JuaWExFTATBgNVBAcMDE1vdW50YWluVmlldzEQMA4GA1UECgwHVGVzdHJ1 +bjEWMBQGA1UECwwNUXVhbGlmaWNhdGlvbjEaMBgGA1UEAwwRZGV2aWNlX2NlcnRf +bG9jYWwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJepNW0Aag19mp +a0DwbTupjsQPuQPxhXQ+0fEHNHycuPxW7MDlpeTfVC1tPlBu/X6uK3yCYco1YDEv +tTXYBELjnHUynnCh/ZKcoGMBO+wo3q/ppU2PC8E9wKwH0R070OzKj0U2LR2wHiLN +x4HpUAbrP/aH7qS9tNswqL/oE+dsPzpa2JY3a8dpUHa/x7iVmasasLrteht3Iz84 +9QLki9O1vUGA5jTKx9CAymIZGFf19gJ3qiqIPNvY6a6cv5ACykTYOTn/X3LOK8Zu +Vv7/8M5z8Uf/t4bVK5wyIo+KBG7L1tpYjuGLrAOqOauNgsrUD2DQbsNds4Evjpt9 +dItalZtjAgMBAAEwDQYJKoZIhvcNAQELBQADggEBALkVmv0pwISSckgbCJ9Y16iu +I/qzNUmrBX/O36pXFDYj++YDWQyAXxrFK2mb8+wE5VjtnW+XIYQ5HMD65xaajqjC +14Rq9n7nSH1WvXBRVyOZLO/iXabofqpNZq/8t8I6Gwr7nDLui8g41Aa6UCzqO+vu +ud07PUDj3TwFcE3YBU9oT9Cxbu9dgFWEu53hO2+Wef9V5MYAOvsiaakUy4sxyEvn +SrRpTR5x25TahIM9AfuDIBAeQGsw0q0Pl10JY4n+Z+rFvc6yvuzsmZCzqZiQGiC7 +jkgjxxuR2aKopXoC1sKZ5NhueNkXQjnYwebQp+gkoDamoEIUHMVjCm1bvOu9M/Q= +-----END CERTIFICATE----- diff --git a/testing/unit/tls/root_certs/Testrun_CA_Root.crt b/testing/unit/tls/root_certs/Testrun_CA_Root.crt new file mode 100644 index 000000000..24f5bbe78 --- /dev/null +++ b/testing/unit/tls/root_certs/Testrun_CA_Root.crt @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkTCCAnkCFEVPbtILjbdASrq6LFIB3o2rIIDhMA0GCSqGSIb3DQEBCwUAMIGE +MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEVMBMGA1UEBwwMTW91 +bnRhaW5WaWV3MRAwDgYDVQQKDAdUZXN0cnVuMRYwFAYDVQQLDA1RdWFsaWZpY2F0 +aW9uMR8wHQYDVQQDDBZUZXN0cnVuIFJTQSBTaWduaW5nIENBMB4XDTI0MDMyMDIw +MzUwNVoXDTM0MDMyMDIwMzUwNVowgYQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApD +YWxpZm9ybmlhMRUwEwYDVQQHDAxNb3VudGFpblZpZXcxEDAOBgNVBAoMB1Rlc3Ry +dW4xFjAUBgNVBAsMDVF1YWxpZmljYXRpb24xHzAdBgNVBAMMFlRlc3RydW4gUlNB +IFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDABwO+ +XX0q6E1iysiSJBxo+XILBxg20HMTdMGc4Kdyt5gm1mfkXIBL1XNGRPENLoV/Ty0K +2EnmexVLllU827hf5kb29YRSzWb5wQd1tpexZ2Bnj3FTb/Xmacej8Oo4WF/PxKZ1 +mkYDmQp77h61zJpbooWaX3AdjYpmrKiQxjV6EAxykYzVLXqueYecra3IAzbuujvH +QJwxKrQbbhJaUQrtYY5CKd3BjqAU0PXqulHjfGPxOau+QA+zkGsAu/DZuRdxk7VO +N7H3CR7ywZV63ul8/3VUDlQYPSkOq2hBo50KzINXJ4BFl0V7q03Ru3dPRxssqp52 +Qzg8BggFuKdxpucDAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAInXBKcbZI5kKl6m +2IVGWWW0SPye/4uLwtLUJtHGAAxeISjwdiiebVqcwZTHoJ4qnPKd3OMdGFvEWMPi +vI1I/j4JFraD2Q885MhitVkmx59OCLNSR6QGtVqu6E73KADL92KZTE7Gdb2DtqpX +zf2mz8MukSeMI7NZI7hp599DAj50N4mnQZPDJfuE+jTBjuSh7oay1x1m6N1eZZRT +lFMWH2fXjlknpCpIVAcFYo3dEZsGl04z/NiQZrODBlt6CxheGwdbOXy/wPulkZ9R +v9A7sLrK9rDih2qZGjWpbexTrlFlvC4z2UN/gh6P3IR8QuUv75MjPqQmQ9/9SV0+ +UrVwBdw= +-----END CERTIFICATE----- diff --git a/testing/unit/tls/tls_module_test.py b/testing/unit/tls/tls_module_test.py index 86870e46a..fb06b0eb1 100644 --- a/testing/unit/tls/tls_module_test.py +++ b/testing/unit/tls/tls_module_test.py @@ -30,6 +30,8 @@ OUTPUT_DIR = os.path.join(TEST_FILES_DIR,'output/') REPORTS_DIR = os.path.join(TEST_FILES_DIR,'reports/') CAPTURES_DIR = os.path.join(TEST_FILES_DIR,'captures/') +CERT_DIR = os.path.join(TEST_FILES_DIR,'certs/') +ROOT_CERTS_DIR = os.path.join(TEST_FILES_DIR,'root_certs') LOCAL_REPORT = os.path.join(REPORTS_DIR,'tls_report_local.md') LOCAL_REPORT_EXT = os.path.join(REPORTS_DIR,'tls_report_ext_local.md') @@ -49,7 +51,7 @@ def setUpClass(cls): TLS_UTIL = TLSUtil(log, bin_dir='modules/test/tls/bin', cert_out_dir=OUTPUT_DIR, - root_certs_dir='local/root_certs') + root_certs_dir=ROOT_CERTS_DIR) # Test 1.2 server when only 1.2 connection is established def security_tls_v1_2_server_test(self): @@ -439,6 +441,18 @@ def get_interface_ip(self, interface_name): print(f'Error: {e}') return None + def tls_module_trusted_ca_cert_chain_test(self): + print('\ntls_module_trusted_ca_cert_chain_test') + cert_path = os.path.join(CERT_DIR,'_.google.com.crt') + cert_valid = TLS_UTIL.validate_cert_chain(device_cert_path=cert_path) + self.assertEqual(cert_valid, True) + + def tls_module_local_ca_cert_test(self): + print('\ntls_module_trusted_ca_cert_chain_test') + cert_path = os.path.join(CERT_DIR,'device_cert_local.crt') + cert_valid = TLS_UTIL.validate_local_ca_signature(device_cert_path=cert_path) + self.assertEqual(cert_valid[0], True) + if __name__ == '__main__': suite = unittest.TestSuite() suite.addTest(TLSModuleTest('client_hello_packets_test')) @@ -471,5 +485,9 @@ def get_interface_ip(self, interface_name): suite.addTest(TLSModuleTest('tls_module_report_ext_test')) suite.addTest(TLSModuleTest('tls_module_report_no_cert_test')) + # Test signature validation methods + suite.addTest(TLSModuleTest('tls_module_trusted_ca_cert_chain_test')) + suite.addTest(TLSModuleTest('tls_module_local_ca_cert_test')) + runner = unittest.TextTestRunner() runner.run(suite)