From e5c37bded5570186aa72571f5f514f272e33face Mon Sep 17 00:00:00 2001 From: "Henry D. Case" Date: Wed, 21 Mar 2018 10:05:19 +0000 Subject: [PATCH] Testing rework Goal of this PR is to rework testing script so that actual testing is easy to extend and perform during development cycle. * For interoperability testing I use python script and test framework, instead of complicated bsah scripts. Script itself is not yet perfect but it makes it much easier to extend tests and work with them during development time * Makefile has been extended and now includes all steps needed to build the library and run tests. It's now possible to run any kind of tests without exporting environment variables. Thanks to this change it is stupid-easy to run any kind of tests. * There are 3 kinds of tests implemented in the library - unittests, interoperability tests and bogo. Travis has been changed and now dashbord will show only results for those 3 targets. --- .travis.yml | 34 +---- README.md | 68 ++++++--- _dev/Makefile | 76 ++++++++-- _dev/bogo.sh | 7 - _dev/go.sh | 2 + _dev/interop.sh | 71 --------- _dev/interop_test_runner | 243 +++++++++++++++++++++++++++++++ _dev/tris-localserver/Dockerfile | 1 - _dev/tris-localserver/start.sh | 4 - _dev/tris-testclient/build.sh | 5 - 10 files changed, 366 insertions(+), 145 deletions(-) delete mode 100755 _dev/bogo.sh delete mode 100755 _dev/interop.sh create mode 100755 _dev/interop_test_runner delete mode 100755 _dev/tris-testclient/build.sh diff --git a/.travis.yml b/.travis.yml index 1c54a1d..2adca68 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,39 +8,15 @@ go: - 1.10.x env: - # CLIAUTH is used for client authentication testing. If string contains letter: - # - "C" - tris client will be tested against $SERVER - # - "S" - tris server will be tested against $CLIENT - # - none of them, client authentication is not tested - - MODE=interop CLIENT=boring SERVER=boring CLIAUTH=NONE # Without client authentication - - MODE=interop CLIENT=boring SERVER=boring CLIAUTH=SC # Client authentication - - MODE=interop CLIENT=tstclnt SERVER=tstclnt - - MODE=interop CLIENT=picotls ZRTT=1 -# - MODE=interop CLIENT=mint # does not support draft 22 - - MODE=bogo - - MODE=gotest - - MODE=interop CLIENT=tstclnt ZRTT=1 - - MODE=interop CLIENT=boring REVISION=origin/master - - MODE=interop CLIENT=tstclnt REVISION=default ZRTT=1 + - TEST_SUITE=test-unit + - TEST_SUITE=test-bogo + - TEST_SUITE=test-interop matrix: fast_finish: true - allow_failures: - - env: MODE=interop CLIENT=boring REVISION=origin/master - - env: MODE=interop CLIENT=tstclnt REVISION=default ZRTT=1 install: - - if [ "$MODE" = "interop" ]; then ./_dev/tris-localserver/start.sh -d && docker ps -a; fi - - if [ "$MODE" = "interop" ]; then ./_dev/interop.sh INSTALL $CLIENT $REVISION; fi - - if [ -n "$SERVER" -a "$CLIENT" != "$SERVER" ]; then ./_dev/interop.sh INSTALL $SERVER $REVISION; fi - - if [ -n "$SERVER" ]; then ./_dev/interop.sh INSTALL-CLIENT; fi + - sudo pip install docker script: - - if [ "$MODE" = "interop" ]; then ./_dev/interop.sh RUN $CLIENT $CLIAUTH; fi - - if [ "$MODE" = "interop" ] && [ "$ZRTT" = "1" ]; then ./_dev/interop.sh 0-RTT $CLIENT; fi - - if [ -n "$SERVER" ]; then ./_dev/interop.sh RUN-CLIENT $SERVER $CLIAUTH; fi - - if [ "$MODE" = "gotest" ]; then ./_dev/go.sh test -race crypto/tls; fi - - if [ "$MODE" = "bogo" ]; then ./_dev/bogo.sh; fi - -after_script: - - if [ "$MODE" = "interop" ]; then docker ps -a; docker logs tris-localserver; fi + - make -f _dev/Makefile build-all && make -f _dev/Makefile "$TEST_SUITE" diff --git a/README.md b/README.md index ca686c0..e632a6c 100644 --- a/README.md +++ b/README.md @@ -20,47 +20,77 @@ tls-tris shouldn't be used as an external package. It is also impossible to ven as `crypto/tls` because stdlib packages would import the standard one and mismatch. So, to build with tls-tris, you need to use a custom GOROOT. + A script is provided that will take care of it for you: `./_dev/go.sh`. Just use that instead of the `go` tool. -The script also transparently fetches the custom Cloudflare Go 1.9 compiler with the required backports. +The script also transparently fetches the custom Cloudflare Go 1.10 compiler with the required backports. -``` -./_dev/go.sh build ./_dev/tris-localserver -TLSDEBUG=error ./tris-localserver -b 127.0.0.1:4443 -``` +## Development -## Debugging +### Dependencies -When the environment variable `TLSDEBUG` is set to `error`, Tris will print a hexdump of the Client Hello and a stack trace if an handshake error occurs. If the value is `short`, only the error and the first meaningful stack frame are printed. +Copy paste line bellow to install all required dependencies: -## Building Caddy +* ArchLinux: +``` +pacman -S go docker gcc git make patch python2 python-docker rsync +``` +* Debian: ``` -./_dev/go.sh build github.com/mholt/caddy +apt-get install build-essential docker go patch python python-pip rsync +pip install setuptools +pip install docker ``` -*Note: to get Caddy to use TLS 1.3 you'll have to apply the patch at `_dev/caddy/caddy.patch`.* +Similar dependencies can be found on any UNIX based system/distribution. + +### Building -## Testing with BoringSSL/NSS/Mint/... +There are number of things that need to be setup before running tests. Most important step is to copy ``go env GOROOT`` directory to ``_dev`` and swap TLS implementation and recompile GO. Then for testing we use go implementation from ``_dev/GOROOT``. ``` -./_dev/tris-localserver/start.sh --rm +make -f _dev/Makefile build-all ``` +### Testing + +We run 3 kinds of test:. + +* Unit testing:
``make -f _dev/Makefile test-unit`` +* Testing against BoringSSL test suite:
``make -f _dev/Makefile test-bogo`` +* Compatibility testing (see below):
``make -f _dev/Makefile test-compat`` + +To run all the tests in one go use: ``` -docker build -t tls-tris:boring _dev/boring -docker run -i --rm tls-tris:boring $(docker inspect -f '{{ .NetworkSettings.IPAddress }}' tris-localserver):443 +make -f _dev/Makefile test ``` +### Testing interoperability with 3rd party libraries + +In order to ensure compatibility we are testing our implementation against BoringSSL, NSS and PicoTLS. + +Makefile has a specific target for testing interoperability with external libraries. Following command can be used in order to run such test: + ``` -docker build -t tls-tris:tstclnt _dev/tstclnt -docker run -i --rm tls-tris:tstclnt $(docker inspect -f '{{ .NetworkSettings.IPAddress }}' tris-localserver):443 +make -f _dev/Makefile test-interop ``` +The makefile target is just a wrapper and it executes ``_dev/interop_test_runner`` script written in python. The script implements interoperability tests using ``python unittest`` framework. + +Script can be started from command line directly. For example: + ``` -docker build -t tls-tris:mint _dev/mint -docker run -i --rm tls-tris:mint $(docker inspect -f '{{ .NetworkSettings.IPAddress }}' tris-localserver):443 +> ./interop_test_runner -v InteropServer_NSS.test_zero_rtt +test_zero_rtt (__main__.InteropServer_NSS) ... ok + +---------------------------------------------------------------------- +Ran 1 test in 8.765s + +OK ``` -To build a specific revision, use `--build-arg REVISION=abcdef1234`. +### Debugging + +When the environment variable `TLSDEBUG` is set to `error`, Tris will print a hexdump of the Client Hello and a stack trace if an handshake error occurs. If the value is `short`, only the error and the first meaningful stack frame are printed. diff --git a/_dev/Makefile b/_dev/Makefile index 82d5a8f..4dbc266 100644 --- a/_dev/Makefile +++ b/_dev/Makefile @@ -7,6 +7,7 @@ BUILD_DIR ?= $(PRJ_DIR)/_dev/GOROOT # Compiler GO ?= go +DOCKER ?= docker # Build environment OS ?= $(shell $(GO) env GOHOSTOS) @@ -18,12 +19,18 @@ GOROOT_LOCAL = $(BUILD_DIR)/$(OS_ARCH) # Flag indicates wheter invoke "go install -race std". Supported only on amd64 with CGO enabled INSTALL_RACE:= $(words $(filter $(ARCH)_$(shell go env CGO_ENABLED), amd64_1)) -# TODO: I'm not sure why we would remove it at the end -# but I comment this code as tls.a is exactly what -# I try to build here -#GOROOT: GOROOT/$(OS_ARCH)/.ok_$(VER_OS_ARCH) -# rm -f GOROOT/$(OS_ARCH)/pkg/*/crypto/tls.a +# Test targets used for compatibility testing +TARGET_TEST_COMPAT=boring picotls tstclnt +# Some target-specific constants +BORINGSSL_REVISION=1530ef3e +BOGO_DOCKER_TRIS_LOCATION=/go/src/github.com/cloudflare/tls-tris + +############### +# +# Build targets +# +############################## $(BUILD_DIR)/$(OS_ARCH)/.ok_$(VER_OS_ARCH): clean # Create clean directory structure @@ -36,7 +43,7 @@ $(BUILD_DIR)/$(OS_ARCH)/.ok_$(VER_OS_ARCH): clean # Swap TLS implementation rm -r $(GOROOT_LOCAL)/src/crypto/tls/* - rsync -a $(PRJ_DIR)/ $(GOROOT_LOCAL)/src/crypto/tls/ --exclude=$(lastword $(subst /, ,$(DEV_DIR))) + rsync -rltgoD $(PRJ_DIR)/ $(GOROOT_LOCAL)/src/crypto/tls/ --exclude=$(lastword $(subst /, ,$(DEV_DIR))) # Apply additional patches for p in $(wildcard $(DEV_DIR)/patches/*); do patch -d "$(GOROOT_LOCAL)" -p1 < "$$p"; done @@ -48,11 +55,62 @@ ifeq ($(INSTALL_RACE),1) endif @touch "$@" +build-test-%: $(BUILD_DIR)/$(OS_ARCH)/.ok_$(VER_OS_ARCH) + $(DOCKER) build $(BUILDARG) -t tls-tris:$* $(DEV_DIR)/$* + $(DOCKER) build $(BUILDARG) -t $(*)-localserver $(DEV_DIR)/$* + +build-all: \ + build-test-tris-client \ + build-test-tris-server \ + build-test-bogo \ + $(addprefix build-test-,$(TARGET_TEST_COMPAT)) + +# Builds TRIS client +build-test-tris-client: $(BUILD_DIR)/$(OS_ARCH)/.ok_$(VER_OS_ARCH) + cd $(DEV_DIR)/tris-testclient; CGO_ENABLED=0 GOROOT="$(GOROOT_LOCAL)" $(GO) build -v -i . + $(DOCKER) build -t tris-testclient $(DEV_DIR)/tris-testclient + +# Builds TRIS server +build-test-tris-server: $(BUILD_DIR)/$(OS_ARCH)/.ok_$(VER_OS_ARCH) + cd $(DEV_DIR)/tris-localserver; CGO_ENABLED=0 GOROOT="$(GOROOT_LOCAL)" $(GO) build -v -i . + $(DOCKER) build -t tris-localserver $(DEV_DIR)/tris-localserver + +# BoringSSL specific stuff +build-test-boring: BUILDARG=--build-arg REVISION=$(BORINGSSL_REVISION) + +# TODO: This probably doesn't work +build-caddy: $(BUILD_DIR)/$(OS_ARCH)/.ok_$(VER_OS_ARCH) + CGO_ENABLED=0 GOROOT="$(GOROOT_LOCAL)" $(GO) build github.com/mholt/caddy + +############### +# +# Test targets +# +############################## +test: \ + test-unit \ + test-bogo \ + test-interop + +test-unit: $(BUILD_DIR)/$(OS_ARCH)/.ok_$(VER_OS_ARCH) + GOROOT="$(GOROOT_LOCAL)" $(GO) test -race crypto/tls + +test-bogo: + $(DOCKER) run --rm -v $(PRJ_DIR):$(BOGO_DOCKER_TRIS_LOCATION) tls-tris:bogo + +test-interop: + $(DEV_DIR)/interop_test_runner -v + +############### +# +# Utils +# +############################## clean: rm -rf $(BUILD_DIR)/$(OS_ARCH) -clean-all: +clean-all: clean rm -rf $(BUILD_DIR) -# PHONY targets -.PHONY: $(BUILD_DIR) clean + +.PHONY: $(BUILD_DIR) clean build build-test test test-unit test-bogo test-compat diff --git a/_dev/bogo.sh b/_dev/bogo.sh deleted file mode 100755 index 1175e6d..0000000 --- a/_dev/bogo.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash -set -xeuo pipefail - -BASEDIR=$(cd "$(dirname "$0")" && pwd) - -docker build -t tls-tris:bogo _dev/bogo -docker run --rm -v $BASEDIR/..:/go/src/github.com/cloudflare/tls-tris tls-tris:bogo diff --git a/_dev/go.sh b/_dev/go.sh index c396d3f..91403a3 100755 --- a/_dev/go.sh +++ b/_dev/go.sh @@ -1,4 +1,6 @@ #!/usr/bin/env bash +# +# THIS FILE IS ONLY USED BY _dev/bogo. It will be removed in future set -e BASEDIR=$(cd "$(dirname "$0")" && pwd) diff --git a/_dev/interop.sh b/_dev/interop.sh deleted file mode 100755 index a4f8f90..0000000 --- a/_dev/interop.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/usr/bin/env bash -set -xeo pipefail - -if [ "$1" = "INSTALL" ]; then - # INSTALL [] - if [ -n "${3:-}" ]; then - REVISION="--build-arg REVISION=$3" - else - REVISION="" - fi - docker build $REVISION -t tls-tris:$2 _dev/$2 - -elif [ "$1" = "RUN" ]; then - # RUN - IP=$(docker inspect -f '{{ .NetworkSettings.IPAddress }}' tris-localserver) - - docker run --rm tls-tris:$2 $IP:1443 | tee output.txt # RSA - grep "Hello TLS 1.3" output.txt | grep -v "resumed" | grep -v "0-RTT" - grep "Hello TLS 1.3" output.txt | grep "resumed" | grep -v "0-RTT" - - docker run --rm tls-tris:$2 $IP:2443 | tee output.txt # ECDSA - grep "Hello TLS 1.3" output.txt | grep -v "resumed" | grep -v "0-RTT" - grep "Hello TLS 1.3" output.txt | grep "resumed" | grep -v "0-RTT" - - if [[ $3 =~ .*S.* ]]; then - # Client auth - tris is a server - docker run --rm tls-tris:$2 $IP:6443 -key client_rsa.key -cert client_rsa.crt -debug 2>&1 | tee output.txt - grep "send_client_certificate_verify" output.txt # Checks if client cert was requested and sent - grep "Hello TLS 1.3" output.txt | grep "resumed" | grep -v "0-RTT" - fi - -elif [ "$1" = "0-RTT" ]; then - # 0-RTT - IP=$(docker inspect -f '{{ .NetworkSettings.IPAddress }}' tris-localserver) - - docker run --rm tls-tris:$2 $IP:3443 | tee output.txt # rejecting 0-RTT - grep "Hello TLS 1.3" output.txt | grep "resumed" | grep -v "0-RTT" - - docker run --rm tls-tris:$2 $IP:4443 | tee output.txt # accepting 0-RTT - grep "Hello TLS 1.3" output.txt | grep "resumed" | grep "0-RTT" - - docker run --rm tls-tris:$2 $IP:5443 | tee output.txt # confirming 0-RTT - grep "Hello TLS 1.3" output.txt | grep "resumed" | grep "0-RTT confirmed" - -elif [ "$1" = "INSTALL-CLIENT" ]; then - cd "$(dirname "$0")/tris-testclient" - ./build.sh - -elif [ "$1" = "RUN-CLIENT" ]; then - # RUN-CLIENT - cd "$(dirname "$0")/tris-testclient" - - SERVERNAME="$2-localserver" - docker run --rm --detach --name "$SERVERNAME" \ - --entrypoint /server.sh \ - --expose 1443 --expose 2443 --expose 6443 \ - tls-tris:$2 - IP=$(docker inspect -f '{{ .NetworkSettings.IPAddress }}' "$SERVERNAME") - # Obtain information and stop server on exit - trap 'docker ps -a; docker logs "$SERVERNAME"; docker kill "$SERVERNAME"' EXIT - - # RSA - docker run --rm tris-testclient -ecdsa=false $IP:1443 - # ECDSA - docker run --rm tris-testclient -rsa=false $IP:2443 - - # Test client authentication if requested (tris is a client) - [[ $3 =~ .*C.* ]] && docker run --rm tris-testclient -rsa=false -cliauth $IP:6443; true - - # TODO maybe check server logs for expected output? -fi diff --git a/_dev/interop_test_runner b/_dev/interop_test_runner new file mode 100755 index 0000000..6f6880b --- /dev/null +++ b/_dev/interop_test_runner @@ -0,0 +1,243 @@ +#!/usr/bin/env python2 + +import docker +import unittest +import re +import time + +# Regex patterns used for testing + +# Checks if TLS 1.3 was negotiated +RE_PATTERN_HELLO_TLS_13_NORESUME = "^.*Hello TLS 1.3 \(draft .*\) _o/$|^.*Hello TLS 1.3 _o/$" +# Checks if TLS 1.3 was resumed +RE_PATTERN_HELLO_TLS_13_RESUME = "Hello TLS 1.3 \(draft .*\) \[resumed\] _o/" +# Checks if 0-RTT was used and NOT confirmed +RE_PATTERN_HELLO_0RTT = "^.*Hello TLS 1.3 .*\[resumed\] \[0-RTT\] _o/$" +# Checks if 0-RTT was used and confirmed +RE_PATTERN_HELLO_0RTT_CONFIRMED = "^.*Hello TLS 1.3 .*\[resumed\] \[0-RTT confirmed\] _o/$" + +class Docker(object): + ''' Utility class used for starting/stoping servers and clients during tests''' + def __init__(self): + self.d = docker.from_env() + + def get_ip(self, server): + tris_localserver_container = self.d.containers.get(server) + return tris_localserver_container.attrs['NetworkSettings']['IPAddress'] + + def run_client(self, image_name, cmd): + ''' Runs client and returns tuple (status_code, logs) ''' + c = self.d.containers.create(image=image_name, command=cmd) + c.start() + res = c.wait() + ret = c.logs() + c.remove() + return (res['StatusCode'], ret) + + def run_server(self, image_name, cmd=None, ports=None, entrypoint=None): + ''' Starts server and returns docker container ''' + c = self.d.containers.create(image=image_name, detach=True, command=cmd, ports=ports, entrypoint=entrypoint) + c.start() + # TODO: maybe can be done better? + time.sleep(3) + return c + +class RegexSelfTest(unittest.TestCase): + ''' Ensures that those regexe's actually work ''' + + LINE_HELLO_TLS ="\nsomestuff\nHello TLS 1.3 _o/\nsomestuff" + LINE_HELLO_DRAFT_TLS="\nsomestuff\nHello TLS 1.3 (draft 22) _o/\nsomestuff" + + LINE_HELLO_RESUMED ="\nsomestuff\nHello TLS 1.3 (draft 22) [resumed] _o/\nsomestuff" + LINE_HELLO_MIXED ="\nsomestuff\nHello TLS 1.3 (draft 22) _o/\nHello TLS 1.3 (draft 22) [resumed] _o/\nsomestuff" + LINE_HELLO_TLS_12 ="\nsomestuff\nHello TLS 1.2 (draft 22) [resumed] _o/\nsomestuff" + LINE_HELLO_TLS_13_0RTT="\nsomestuff\nHello TLS 1.3 (draft 22) [resumed] [0-RTT] _o/\nsomestuff" + LINE_HELLO_TLS_13_0RTT_CONFIRMED="\nsomestuff\nHello TLS 1.3 (draft 22) [resumed] [0-RTT confirmed] _o/\nsomestuff" + + def test_regexes(self): + self.assertIsNotNone( + re.search(RE_PATTERN_HELLO_TLS_13_NORESUME, RegexSelfTest.LINE_HELLO_TLS, re.MULTILINE)) + self.assertIsNotNone( + re.search(RE_PATTERN_HELLO_TLS_13_NORESUME, RegexSelfTest.LINE_HELLO_DRAFT_TLS, re.MULTILINE)) + self.assertIsNotNone( + re.search(RE_PATTERN_HELLO_TLS_13_RESUME, RegexSelfTest.LINE_HELLO_RESUMED, re.MULTILINE)) + self.assertIsNotNone( + re.search(RE_PATTERN_HELLO_0RTT, RegexSelfTest.LINE_HELLO_TLS_13_0RTT, re.MULTILINE)) + self.assertIsNotNone( + re.search(RE_PATTERN_HELLO_0RTT_CONFIRMED, RegexSelfTest.LINE_HELLO_TLS_13_0RTT_CONFIRMED, re.MULTILINE)) + + # negative cases + + # expects 1.3, but 1.2 received + self.assertIsNone( + re.search(RE_PATTERN_HELLO_TLS_13_NORESUME, RegexSelfTest.LINE_HELLO_TLS_12, re.MULTILINE)) + # expects 0-RTT + self.assertIsNone( + re.search(RE_PATTERN_HELLO_TLS_13_RESUME, RegexSelfTest.LINE_HELLO_TLS_13_0RTT, re.MULTILINE)) + # expectes 0-RTT confirmed + self.assertIsNone( + re.search(RE_PATTERN_HELLO_0RTT, RegexSelfTest.LINE_HELLO_TLS_13_0RTT_CONFIRMED, re.MULTILINE)) + # expects resume without 0-RTT + self.assertIsNone( + re.search(RE_PATTERN_HELLO_TLS_13_RESUME, RegexSelfTest.LINE_HELLO_TLS_13_0RTT, re.MULTILINE)) + + +class InteropServer(object): + ''' Instantiates TRIS as a server ''' + + TRIS_SERVER_NAME = "tris-localserver" + + @classmethod + def setUpClass(self): + self.d = Docker() + self.server = self.d.run_server(self.TRIS_SERVER_NAME) + + @classmethod + def tearDownClass(self): + self.server.kill() + self.server.remove() + + @property + def server_ip(self): + return self.d.get_ip(self.server.name) + +# Mixins for testing server functionality + +class ServerNominalMixin(object): + ''' Nominal tests for TLS 1.3 - client tries to perform handshake with server ''' + def test_rsa(self): + res = self.d.run_client(self.CLIENT_NAME, self.server_ip+":"+'1443') + self.assertTrue(res[0] == 0) + # Check there was TLS hello without resume + self.assertIsNotNone( + re.search(RE_PATTERN_HELLO_TLS_13_NORESUME, res[1], re.MULTILINE)) + # Check there was TLS hello with resume + self.assertIsNotNone( + re.search(RE_PATTERN_HELLO_TLS_13_RESUME, res[1], re.MULTILINE)) + + def test_ecdsa(self): + res = self.d.run_client(self.CLIENT_NAME, self.server_ip+":"+'2443') + self.assertTrue(res[0] == 0) + # Check there was TLS hello without resume + self.assertIsNotNone( + re.search(RE_PATTERN_HELLO_TLS_13_NORESUME, res[1], re.MULTILINE)) + # Check there was TLS hello with resume + self.assertIsNotNone( + re.search(RE_PATTERN_HELLO_TLS_13_RESUME, res[1], re.MULTILINE)) + +class ServerClientAuthMixin(object): + ''' Client authentication testing ''' + def test_client_auth(self): + args = ''.join([self.server_ip+':6443',' -key client_rsa.key -cert client_rsa.crt -debug']) + res = self.d.run_client(self.CLIENT_NAME, args) + self.assertEqual(res[0], 0) + # Check there was TLS hello without resume + self.assertIsNotNone( + re.search(RE_PATTERN_HELLO_TLS_13_NORESUME, res[1], re.MULTILINE)) + # Check there was TLS hello with resume + self.assertIsNotNone( + re.search(RE_PATTERN_HELLO_TLS_13_RESUME, res[1], re.MULTILINE)) + +class ClientNominalMixin(object): + + def test_rsa(self): + res = self.d.run_client(self.CLIENT_NAME, '-rsa=false '+self.server_ip+":2443") + self.assertEqual(res[0], 0) + + def test_ecdsa(self): + res = self.d.run_client(self.CLIENT_NAME, '-ecdsa=false '+self.server_ip+":1443") + self.assertEqual(res[0], 0) + +class ClientClientAuthMixin(object): + ''' Client authentication testing - tris on client side ''' + + def test_client_auth(self): + res = self.d.run_client('tris-testclient', '-rsa=false -cliauth '+self.server_ip+":6443") + self.assertTrue(res[0] == 0) + +class ServerZeroRttMixin(object): + ''' Zero RTT testing ''' + + def test_zero_rtt(self): + # rejecting 0-RTT + res = self.d.run_client(self.CLIENT_NAME, self.server_ip+":3443") + self.assertEqual(res[0], 0) + self.assertIsNotNone( + re.search(RE_PATTERN_HELLO_TLS_13_RESUME, res[1], re.MULTILINE)) + self.assertIsNone( + re.search(RE_PATTERN_HELLO_0RTT, res[1], re.MULTILINE)) + + # accepting 0-RTT + res = self.d.run_client(self.CLIENT_NAME, self.server_ip+":4443") + self.assertEqual(res[0], 0) + self.assertIsNotNone( + re.search(RE_PATTERN_HELLO_0RTT, res[1], re.MULTILINE)) + + # confirming 0-RTT + res = self.d.run_client(self.CLIENT_NAME, self.server_ip+":5443") + self.assertEqual(res[0], 0) + self.assertIsNotNone( + re.search(RE_PATTERN_HELLO_0RTT_CONFIRMED, res[1], re.MULTILINE)) + +class InteropClient(object): + ''' Instantiates TRIS as a client ''' + + CLIENT_NAME = "tris-testclient" + + @classmethod + def setUpClass(self): + self.d = Docker() + self.server = self.d.run_server( + self.SERVER_NAME, + ports={'1443/tcp': 1443, '2443/tcp': 2443, '6443/tcp': 6443}, + entrypoint="/server.sh") + + @classmethod + def tearDownClass(self): + self.server.kill() + self.server.remove() + + @property + def server_ip(self): + return self.d.get_ip(self.server.name) + +# Actual test definition + +# TRIS as a server +class InteropServer_BoringSSL( + InteropServer, + ServerNominalMixin, + ServerClientAuthMixin, + unittest.TestCase + ): CLIENT_NAME = "tls-tris:boring" + +class InteropServer_PicoTLS( + InteropServer, + ServerNominalMixin, + ServerZeroRttMixin, + unittest.TestCase + ): CLIENT_NAME = "tls-tris:picotls" + +class InteropServer_NSS( + InteropServer, + ServerNominalMixin, + ServerZeroRttMixin, + unittest.TestCase + ): CLIENT_NAME = "tls-tris:tstclnt" + +# TRIS as a client +class InteropClient_BoringSSL( + InteropClient, + ClientNominalMixin, + ClientClientAuthMixin, + unittest.TestCase + ): SERVER_NAME = "boring-localserver" + +class InteropClient_NSS( + InteropClient, + ClientNominalMixin, + unittest.TestCase + ): SERVER_NAME = "tstclnt-localserver" + +if __name__ == '__main__': + unittest.main() diff --git a/_dev/tris-localserver/Dockerfile b/_dev/tris-localserver/Dockerfile index 1fb06c3..aa23784 100644 --- a/_dev/tris-localserver/Dockerfile +++ b/_dev/tris-localserver/Dockerfile @@ -9,7 +9,6 @@ EXPOSE 4443 EXPOSE 5443 EXPOSE 6443 -# GOOS=linux ../go.sh build -v -i . ADD tris-localserver / ADD runner.sh / diff --git a/_dev/tris-localserver/start.sh b/_dev/tris-localserver/start.sh index edd54f3..4e31048 100755 --- a/_dev/tris-localserver/start.sh +++ b/_dev/tris-localserver/start.sh @@ -1,9 +1,5 @@ #! /bin/sh set -e -cd "$(dirname $0)" - -CGO_ENABLED=0 GOOS=linux ../go.sh build -v -i . -docker build -t tris-localserver . exec docker run --name tris-localserver --env TLSDEBUG=error "$@" tris-localserver diff --git a/_dev/tris-testclient/build.sh b/_dev/tris-testclient/build.sh deleted file mode 100755 index 5352533..0000000 --- a/_dev/tris-testclient/build.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -set -e -cd "$(dirname "$0")" -CGO_ENABLED=0 GOOS=linux ../go.sh build -v -i . -docker build -t tris-testclient .