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: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ error
pylint.out
__pycache__/
build/
testing/unit_test/temp
testing/unit_test/temp/
4 changes: 4 additions & 0 deletions framework/python/src/test_orc/test_orchestrator.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
RUNTIME_DIR = "runtime/test"
TEST_MODULES_DIR = "modules/test"
MODULE_CONFIG = "conf/module_config.json"
DEVICE_ROOT_CERTS = "local/root_certs"


class TestOrchestrator:
Expand Down Expand Up @@ -61,6 +62,9 @@ def start(self):
os.makedirs(RUNTIME_DIR, exist_ok=True)
util.run_command(f"chown -R {self._host_user} {RUNTIME_DIR}")

# Setup the root_certs folder
os.makedirs(DEVICE_ROOT_CERTS, exist_ok=True)

self._load_test_modules()
self.build_test_modules()

Expand Down
6 changes: 3 additions & 3 deletions local/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
system.json
devices
root_certs
system.json
devices
root_certs
4 changes: 4 additions & 0 deletions modules/test/base/base.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ FROM ubuntu:jammy

ARG MODULE_NAME=base
ARG MODULE_DIR=modules/test/$MODULE_NAME
ARG COMMON_DIR=framework/python/src/common

# Install common software
RUN apt-get update && apt-get install -y net-tools iputils-ping tcpdump iproute2 jq python3 python3-pip dos2unix nmap --fix-missing

# Install common python modules
COPY $COMMON_DIR/ /testrun/python/src/common

# Setup the base python requirements
COPY $MODULE_DIR/python /testrun/python

Expand Down
3 changes: 2 additions & 1 deletion modules/test/base/python/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
grpcio
grpcio-tools
grpcio-tools
netifaces
5 changes: 4 additions & 1 deletion modules/test/base/python/src/test_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ def run_tests(self):
if isinstance(result, bool):
test['result'] = 'compliant' if result else 'non-compliant'
else:
test['result'] = 'compliant' if result[0] else 'non-compliant'
if result[0] is None:
test['result'] = 'skipped'
else:
test['result'] = 'compliant' if result[0] else 'non-compliant'
test['result_details'] = result[1]
else:
test['result'] = 'skipped'
Expand Down
2 changes: 1 addition & 1 deletion modules/test/conn/python/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
scapy
pyOpenSSL
11 changes: 11 additions & 0 deletions modules/test/tls/bin/check_cert_signature.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

ROOT_CERT=$1
DEVICE_CERT=$2

echo "ROOT: $ROOT_CERT"
echo "DEVICE_CERT: $DEVICE_CERT"

response=$(openssl verify -CAfile $ROOT_CERT $DEVICE_CERT)

echo "$response"
10 changes: 10 additions & 0 deletions modules/test/tls/bin/get_ciphers.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

CAPTURE_FILE=$1
DST_IP=$2
DST_PORT=$3

TSHARK_FILTER="ssl.handshake.ciphersuites and ip.dst==$DST_IP and tcp.dstport==$DST_PORT"
response=$(tshark -r $CAPTURE_FILE -Y "$TSHARK_FILTER" -Vx | grep 'Cipher Suite:' | awk '{$1=$1};1' | sed 's/Cipher Suite: //')

echo "$response"
19 changes: 19 additions & 0 deletions modules/test/tls/bin/get_client_hello_packets.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

CAPTURE_FILE=$1
SRC_IP=$2
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
TSHARK_FILTER=$TSHARK_FILTER "and ssl.handshake.version==0x0303"
elif [ $TLS_VERSION == '1.2' ];then
TSHARK_FILTER=$TSHARK_FILTER "and ssl.handshake.version==0x0304"
fi

response=$(tshark -r $CAPTURE_FILE $TSHARK_OUTPUT $TSHARK_FILTER)

echo "$response"

19 changes: 19 additions & 0 deletions modules/test/tls/bin/get_handshake_complete.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

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"

56 changes: 56 additions & 0 deletions modules/test/tls/bin/start_test_module
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/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.

# An example startup script that does the bare minimum to start
# a test module via a pyhon script. Each test module should include a
# start_test_module file that overwrites this one to boot all of its
# specific requirements to run.

# Define where the python source files are located
PYTHON_SRC_DIR=/testrun/python/src

# Fetch module name
MODULE_NAME=$1

# Default interface should be veth0 for all containers
DEFAULT_IFACE=veth0

# Allow a user to define an interface by passing it into this script
DEFINED_IFACE=$2

# Select which interace to use
if [[ -z $DEFINED_IFACE || "$DEFINED_IFACE" == "null" ]]
then
echo "No interface defined, defaulting to veth0"
INTF=$DEFAULT_IFACE
else
INTF=$DEFINED_IFACE
fi

# Create and set permissions on the log files
LOG_FILE=/runtime/output/$MODULE_NAME.log
RESULT_FILE=/runtime/output/$MODULE_NAME-result.json
touch $LOG_FILE
touch $RESULT_FILE
chown $HOST_USER $LOG_FILE
chown $HOST_USER $RESULT_FILE

# Run the python scrip that will execute the tests for this module
# -u flag allows python print statements
# to be logged by docker by running unbuffered
python3 -u $PYTHON_SRC_DIR/run.py "-m $MODULE_NAME"

echo Module has finished
37 changes: 37 additions & 0 deletions modules/test/tls/conf/module_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"config": {
"meta": {
"name": "tls",
"display_name": "TLS",
"description": "TLS tests"
},
"network": true,
"docker": {
"depends_on": "base",
"enable_container": true,
"timeout": 300
},
"tests":[
{
"name": "security.tls.v1_2_server",
"description": "Check the device web server TLS 1.2 & certificate is valid",
"expected_behavior": "TLS 1.2 certificate is issued to the web browser client when accessed"
},
{
"name": "security.tls.v1_3_server",
"description": "Check the device web server TLS 1.3 & certificate is valid",
"expected_behavior": "TLS 1.3 certificate is issued to the web browser client when accessed"
},
{
"name": "security.tls.v1_2_client",
"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.2 and support for ECDH and ECDSA ciphers"
},
{
"name": "security.tls.v1_3_client",
"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.3"
}
]
}
}
2 changes: 2 additions & 0 deletions modules/test/tls/python/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cryptography
pyOpenSSL
68 changes: 68 additions & 0 deletions modules/test/tls/python/src/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# 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.
"""Run Baseline module"""
import argparse
import signal
import sys
import logger

from tls_module import TLSModule

LOGGER = logger.get_logger('test_module')
RUNTIME = 1500


class TLSModuleRunner:
"""An example runner class for test modules."""

def __init__(self, module):

signal.signal(signal.SIGINT, self._handler)
signal.signal(signal.SIGTERM, self._handler)
signal.signal(signal.SIGABRT, self._handler)
signal.signal(signal.SIGQUIT, self._handler)

LOGGER.info('Starting TLS Module')

self._test_module = TLSModule(module)
self._test_module.run_tests()

def _handler(self, signum):
LOGGER.debug('SigtermEnum: ' + str(signal.SIGTERM))
LOGGER.debug('Exit signal received: ' + str(signum))
if signum in (2, signal.SIGTERM):
LOGGER.info('Exit signal received. Stopping test module...')
LOGGER.info('Test module stopped')
sys.exit(1)


def run():
parser = argparse.ArgumentParser(
description='Security Module Help',
formatter_class=argparse.ArgumentDefaultsHelpFormatter)

parser.add_argument(
'-m',
'--module',
help='Define the module name to be used to create the log file')

args = parser.parse_args()

# For some reason passing in the args from bash adds an extra
# space before the argument so we'll just strip out extra space
TLSModuleRunner(args.module.strip())


if __name__ == '__main__':
run()
Loading