tris: Add initial client interoperability tests
Prepare framework for testing tls-tris as client against other servers. Currently only boringssl is implemented, but the idea is to add support for others too (NSS, OpenSSL, picotls, tris, ...). To test multiple certificate types, copy ecdsa.pem and rsa.pem from tris-localserver for boringssl. The boringssl image is reused for the server since the binaries were built anyway. Revision is bumped to something to fix a build error and make the -loop and -www options work.
This commit is contained in:
parent
dee13626ef
commit
c89a0a5f3a
@ -8,7 +8,7 @@ go:
|
||||
- 1.7
|
||||
|
||||
env:
|
||||
- MODE=interop CLIENT=boring
|
||||
- MODE=interop CLIENT=boring SERVER=boring
|
||||
- MODE=interop CLIENT=tstclnt
|
||||
- MODE=interop CLIENT=picotls ZRTT=1
|
||||
- MODE=interop CLIENT=mint
|
||||
@ -28,10 +28,13 @@ matrix:
|
||||
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
|
||||
|
||||
script:
|
||||
- if [ "$MODE" = "interop" ]; then ./_dev/interop.sh RUN $CLIENT; fi
|
||||
- if [ "$MODE" = "interop" ] && [ "$ZRTT" = "1" ]; then ./_dev/interop.sh 0-RTT $CLIENT; fi
|
||||
- if [ -n "$SERVER" ]; then ./_dev/interop.sh RUN-CLIENT $SERVER; fi
|
||||
- if [ "$MODE" = "gotest" ]; then ./_dev/go.sh test -race crypto/tls; fi
|
||||
- if [ "$MODE" = "bogo" ]; then ./_dev/bogo.sh; fi
|
||||
|
||||
|
1
_dev/.gitignore
vendored
1
_dev/.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
/GOROOT
|
||||
/go
|
||||
/tris-localserver/tris-localserver
|
||||
/tris-testclient/tris-testclient
|
||||
/caddy/caddy
|
||||
/caddy/echo
|
||||
|
@ -12,11 +12,7 @@ RUN apk add --update \
|
||||
|
||||
RUN git clone https://boringssl.googlesource.com/boringssl
|
||||
|
||||
# Cacheable layer of compilation, to make the next incremental
|
||||
RUN cd boringssl && git checkout 9b885c5
|
||||
RUN mkdir boringssl/build
|
||||
RUN cd boringssl/build && cmake -GNinja ..
|
||||
RUN cd boringssl && ninja -C build
|
||||
|
||||
# Draft 14
|
||||
# ARG REVISION=88536c3
|
||||
@ -38,7 +34,9 @@ RUN cd boringssl && ninja -C build
|
||||
# ARG REVISION=89917a5
|
||||
|
||||
# Draft 18
|
||||
ARG REVISION=9b885c5
|
||||
#ARG REVISION=9b885c5
|
||||
# Draft 18, but with "bssl server -loop -www" support and build fix
|
||||
ARG REVISION=40b24c8154
|
||||
|
||||
RUN cd boringssl && git fetch
|
||||
RUN cd boringssl && git checkout $REVISION
|
||||
@ -47,4 +45,5 @@ RUN cd boringssl && ninja -C build
|
||||
|
||||
ADD httpreq.txt /httpreq.txt
|
||||
ADD run.sh /run.sh
|
||||
ADD server.sh rsa.pem ecdsa.pem /
|
||||
ENTRYPOINT ["/run.sh"]
|
||||
|
15
_dev/boring/ecdsa.pem
Normal file
15
_dev/boring/ecdsa.pem
Normal file
@ -0,0 +1,15 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIBbTCCAROgAwIBAgIQZCsHZcs5ZkzV+zC2E6j5RzAKBggqhkjOPQQDAjASMRAw
|
||||
DgYDVQQKEwdBY21lIENvMB4XDTE2MDkyNDE3NTE1OFoXDTI2MDkyMjE3NTE1OFow
|
||||
EjEQMA4GA1UEChMHQWNtZSBDbzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDTO
|
||||
B3IyzjYfKCp2HWy+P3QHxhdBT4AUGYgwTiSEj5phumPIahFNcOSWptN0UzlZvJdN
|
||||
MMjVmrFYK/FjF4abkNKjSzBJMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggr
|
||||
BgEFBQcDATAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAKBggq
|
||||
hkjOPQQDAgNIADBFAiEAp9W157PM1IadPBc33Cbj7vaFvp+rXs/hSuMCzP8pgV8C
|
||||
IHCswo1qiC0ZjQmWsBlmz5Zbp9rOorIzBYmGRhRdNs3j
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIFdhO7IW5UIwpB1e2Vunm9QyKvUHWcVwGfLjhpOajuR7oAoGCCqGSM49
|
||||
AwEHoUQDQgAENM4HcjLONh8oKnYdbL4/dAfGF0FPgBQZiDBOJISPmmG6Y8hqEU1w
|
||||
5Jam03RTOVm8l00wyNWasVgr8WMXhpuQ0g==
|
||||
-----END EC PRIVATE KEY-----
|
45
_dev/boring/rsa.pem
Normal file
45
_dev/boring/rsa.pem
Normal file
@ -0,0 +1,45 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEA1DHcIM3SThFqy8nAkPQFX0E7ph8jqh8EATXryjKHGuVjR3Xh
|
||||
OQ0BSPoJxyfdg/VEwevFrtmZAfz0WCbxvP2SVCmf7oobg4V2KPSo3nNt9vlBFUne
|
||||
RtIyHRQ8YRnGSWaRHzJbX6ffltnG2aD+8qUfk161rdZgxBA9G0Ga47IkwQhT2Hqu
|
||||
H3dW2Uu4W2WMyt6gX/tdyEAV57MOPcoceknr7Nb2kfiuDPR7h6wFrW3I6eoj8oX2
|
||||
SkIOuVNt1Z31BAUcPJDUjqopI0o9tolM/7X13M8dEY0OJQVr7FQYDF9JeSYeEMyb
|
||||
wizjBaHDm48mSghP1o5UssQBbNNC83btXCjiLQIDAQABAoIBACzvGgRAUYaCnbDl
|
||||
2kdXxUN0luMIuQ6vXrO67WF17bI+XRWm2riwDlObzzJDON9Wsua1vLjYD1SickOw
|
||||
i4RP1grIfbuPt1/UhT8LAC+LFgA0rBmL+OvaWw5ZWKffQ2QLujN3AG5zKB/Tog43
|
||||
z4UmfldAuQxE11zta2M4M0qAUNQnQj1oiuI8RUdG0VvvLw8Htdi1ogH0CI5R669z
|
||||
NjHt+JV+2gzKx6EX0s8mQL3yXGkC2xXItRbFclyCMJEhPS7QbBu+tru35N6WpzAq
|
||||
BCl2Q7LQogvSA6MXuMOx6CyuExVfgmhbfeoheLE8gmXwl0Y37n/g6ZBZFAtpCjcs
|
||||
UckPv0ECgYEA1orl7RwgIsZljMap6vWtMGoRIHKmT91DGpMmkh4suZe+yAk85maU
|
||||
49Vd+8ZfIN41AH37yrsGOcPHgz5o5QufELpoub6DCsQ7u9F1vQp55cp+qyBWzAgz
|
||||
b/xUuVnIyv3kLan3fpk7ZGCBXFBpLG0QXMFOHtda3Mlk5SmuoEYaYRkCgYEA/TLR
|
||||
u4neKqyqwsqMuRJGC1iKFVmfCjZeNMtPNbTWpdqez/vvT8APnEpIumUGt8YROLGZ
|
||||
8biUr5/ViOkmaP3wmQbO9m2/cE01lMTYv75w1cw2KVQe6kAHJkOx+JEx9xg53RJ/
|
||||
QlFtG5MQUy2599Gxp8BMGaXLH5yo4qwvNvY6CDUCgYEArxr7AwX7rKZlZ/sV4HHY
|
||||
gzVu+R7aY0DibiRATO5X7rrNuhLgI+UCDNqvNLn6FqeGdvpcsmDneeozQwmDL77G
|
||||
ey7KHyBBcF4tquQQxtRwHX+i1yUz8p+W7AX1WLrRSezjeenJ2QhUE1849hGjZeE2
|
||||
g546lq2Kub2enfPhVWsiSLECgYEA72T5QCPeVuLioUH5Q5Kvf1K7W+xcnr9A2xHP
|
||||
Vqwgtre5qFQ/tFuXZuIlWXbjnyY6aiwhrZYjntm0f7pRgrt2nHj/fafOdVPK8Voc
|
||||
xU4+SSbHntPWVw0qtVcUEjzVzRauvwMaJ43tZ0DpEnwNdO5i1oTObwF+x+jLFWZP
|
||||
TdwIinECgYBzjZeCxxOMk5SlPpTsLUtgC+q3m1AavXhUVNEPP2gKMOIPTETPbhbG
|
||||
LBxB2vVbJiS3J7itQy8gceT89O0vSEZnaTPXiM/Ws1QbkBJ8yW7KI7X4WuzN4Imq
|
||||
/cLBRXLb8R328U27YyQFNGMjr2tX/+vx5FulJjSloWMRNuFWUngv7w==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC+jCCAeKgAwIBAgIRANBDimJ/ww2tz77qcYIhuZowDQYJKoZIhvcNAQELBQAw
|
||||
EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xNjA5MjQxNzI5MTlaFw0yNjA5MjIxNzI5
|
||||
MTlaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||
ggEKAoIBAQDUMdwgzdJOEWrLycCQ9AVfQTumHyOqHwQBNevKMoca5WNHdeE5DQFI
|
||||
+gnHJ92D9UTB68Wu2ZkB/PRYJvG8/ZJUKZ/uihuDhXYo9Kjec232+UEVSd5G0jId
|
||||
FDxhGcZJZpEfMltfp9+W2cbZoP7ypR+TXrWt1mDEED0bQZrjsiTBCFPYeq4fd1bZ
|
||||
S7hbZYzK3qBf+13IQBXnsw49yhx6Sevs1vaR+K4M9HuHrAWtbcjp6iPyhfZKQg65
|
||||
U23VnfUEBRw8kNSOqikjSj22iUz/tfXczx0RjQ4lBWvsVBgMX0l5Jh4QzJvCLOMF
|
||||
ocObjyZKCE/WjlSyxAFs00Lzdu1cKOItAgMBAAGjSzBJMA4GA1UdDwEB/wQEAwIF
|
||||
oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBQGA1UdEQQNMAuC
|
||||
CWxvY2FsaG9zdDANBgkqhkiG9w0BAQsFAAOCAQEAygPV4enmvwSuMd1JarxOXpOK
|
||||
Z4Nsk7EKlfCPgzxQUOkFdLIr5ZG1kUkQt/omzTmoIWjLAsoYzT0ZCPOrioczKsWj
|
||||
MceFUIkT0w+eIl+8DzauPy34o8rjcApglF165UG3iphlpI+jdPzv5TBarUAbwsFb
|
||||
ClMLEiNJQ0OMxAIaRtb2RehD4q3OWlpWf6joJ36PRBqL8T5+f2x6Tg3c64UR+QPX
|
||||
98UcCQHHdEhm7y2z5Z2Wt0B48tZ+UAxDEoEwMghNyw7wUD79IRlXGYypBnXaMuLX
|
||||
46aGxbsSQ7Rfg62Co3JG7vo+eJd0AoZHrtFUnfM8V70IFzMBZnSwRslHRJe56Q==
|
||||
-----END CERTIFICATE-----
|
17
_dev/boring/server.sh
Executable file
17
_dev/boring/server.sh
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
PATH=/boringssl/build/tool:$PATH
|
||||
set -x
|
||||
|
||||
# RSA
|
||||
bssl server \
|
||||
-key rsa.pem \
|
||||
-min-version tls1.2 -max-version tls1.3 \
|
||||
-accept 1443 -loop -www 2>&1 &
|
||||
|
||||
# ECDSA
|
||||
bssl server \
|
||||
-key ecdsa.pem \
|
||||
-min-version tls1.2 -max-version tls1.3 \
|
||||
-accept 2443 -loop -www 2>&1 &
|
||||
|
||||
wait
|
@ -2,6 +2,7 @@
|
||||
set -xeuo pipefail
|
||||
|
||||
if [ "$1" = "INSTALL" ]; then
|
||||
# INSTALL <client> [<revision>]
|
||||
if [ -n "${3:-}" ]; then
|
||||
REVISION="--build-arg REVISION=$3"
|
||||
else
|
||||
@ -10,6 +11,7 @@ if [ "$1" = "INSTALL" ]; then
|
||||
docker build $REVISION -t tls-tris:$2 _dev/$2
|
||||
|
||||
elif [ "$1" = "RUN" ]; then
|
||||
# RUN <client>
|
||||
IP=$(docker inspect -f '{{ .NetworkSettings.IPAddress }}' tris-localserver)
|
||||
|
||||
docker run --rm tls-tris:$2 $IP:1443 | tee output.txt # RSA
|
||||
@ -21,6 +23,7 @@ elif [ "$1" = "RUN" ]; then
|
||||
grep "Hello TLS 1.3" output.txt | grep "resumed" | grep -v "0-RTT"
|
||||
|
||||
elif [ "$1" = "0-RTT" ]; then
|
||||
# 0-RTT <client>
|
||||
IP=$(docker inspect -f '{{ .NetworkSettings.IPAddress }}' tris-localserver)
|
||||
|
||||
docker run --rm tls-tris:$2 $IP:3443 | tee output.txt # rejecting 0-RTT
|
||||
@ -32,4 +35,24 @@ elif [ "$1" = "0-RTT" ]; then
|
||||
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 <target-server>
|
||||
cd "$(dirname "$0")/tris-testclient"
|
||||
|
||||
servername="$2-localserver"
|
||||
docker run --rm --detach --name "$servername" \
|
||||
--entrypoint /server.sh \
|
||||
--expose 1443 --expose 2443 \
|
||||
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
|
||||
|
||||
docker run --rm tris-testclient -ecdsa=false $IP:1443 # RSA
|
||||
docker run --rm tris-testclient -rsa=false $IP:2443 # ECDSA
|
||||
# TODO maybe check server logs for expected output?
|
||||
fi
|
||||
|
7
_dev/tris-testclient/Dockerfile
Normal file
7
_dev/tris-testclient/Dockerfile
Normal file
@ -0,0 +1,7 @@
|
||||
FROM scratch
|
||||
|
||||
ENV TLSDEBUG error
|
||||
|
||||
ADD tris-testclient /
|
||||
|
||||
ENTRYPOINT ["/tris-testclient"]
|
5
_dev/tris-testclient/build.sh
Executable file
5
_dev/tris-testclient/build.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
cd "$(dirname "$0")"
|
||||
GOOS=linux ../go.sh build -v -i .
|
||||
docker build -t tris-testclient .
|
121
_dev/tris-testclient/client.go
Normal file
121
_dev/tris-testclient/client.go
Normal file
@ -0,0 +1,121 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var tlsVersionToName = map[uint16]string{
|
||||
tls.VersionTLS10: "1.0",
|
||||
tls.VersionTLS11: "1.1",
|
||||
tls.VersionTLS12: "1.2",
|
||||
tls.VersionTLS13: "1.3",
|
||||
tls.VersionTLS13Draft18: "1.3 (draft 18)",
|
||||
}
|
||||
|
||||
var cipherSuiteIdToName = map[uint16]string{
|
||||
tls.TLS_RSA_WITH_AES_128_CBC_SHA: "TLS_RSA_WITH_AES_128_CBC_SHA",
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
|
||||
tls.TLS_AES_128_GCM_SHA256: "TLS_AES_128_GCM_SHA256",
|
||||
tls.TLS_AES_256_GCM_SHA384: "TLS_AES_256_GCM_SHA384",
|
||||
tls.TLS_CHACHA20_POLY1305_SHA256: "TLS_CHACHA20_POLY1305_SHA256",
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
KeyLogWriter io.Writer
|
||||
failed uint
|
||||
}
|
||||
|
||||
func (c *Client) run(addr string, version, cipherSuite uint16) {
|
||||
fmt.Printf("TLS %s with %s\n", tlsVersionToName[version], cipherSuiteIdToName[cipherSuite])
|
||||
tls_config := &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
MinVersion: version,
|
||||
MaxVersion: version,
|
||||
CipherSuites: []uint16{cipherSuite},
|
||||
KeyLogWriter: c.KeyLogWriter,
|
||||
}
|
||||
con, err := tls.Dial("tcp", addr, tls_config)
|
||||
if err != nil {
|
||||
fmt.Printf("handshake failed: %v\n\n", err)
|
||||
c.failed++
|
||||
return
|
||||
}
|
||||
defer con.Close()
|
||||
|
||||
_, err = con.Write([]byte("GET / HTTP/1.1\r\nHost: localhost\r\n\r\n"))
|
||||
if err != nil {
|
||||
fmt.Printf("Write failed: %v\n\n", err)
|
||||
c.failed++
|
||||
return
|
||||
}
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
n, err := con.Read(buf)
|
||||
if err != nil {
|
||||
fmt.Printf("Read failed: %v\n\n", err)
|
||||
c.failed++
|
||||
return
|
||||
}
|
||||
fmt.Printf("Read %d bytes\n", n)
|
||||
|
||||
fmt.Println("OK\n")
|
||||
}
|
||||
|
||||
func main() {
|
||||
var keylog_file string
|
||||
var enable_rsa, enable_ecdsa bool
|
||||
flag.StringVar(&keylog_file, "keylogfile", "", "Secrets will be logged here")
|
||||
flag.BoolVar(&enable_rsa, "rsa", true, "Whether to enable RSA cipher suites")
|
||||
flag.BoolVar(&enable_ecdsa, "ecdsa", true, "Whether to enable ECDSA cipher suites")
|
||||
flag.Parse()
|
||||
if flag.NArg() != 1 {
|
||||
flag.Usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
addr := flag.Arg(0)
|
||||
if !strings.Contains(addr, ":") {
|
||||
addr += ":443"
|
||||
}
|
||||
|
||||
client := Client{}
|
||||
if keylog_file == "" {
|
||||
keylog_file = os.Getenv("SSLKEYLOGFILE")
|
||||
}
|
||||
if keylog_file != "" {
|
||||
keylog_writer, err := os.OpenFile(keylog_file, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
log.Fatalf("Cannot open keylog file: %v", err)
|
||||
}
|
||||
client.KeyLogWriter = keylog_writer
|
||||
log.Println("Enabled keylog")
|
||||
}
|
||||
|
||||
if enable_rsa {
|
||||
// Sanity check: TLS 1.2 with the mandatory cipher suite from RFC 5246
|
||||
client.run(addr, tls.VersionTLS12, tls.TLS_RSA_WITH_AES_128_CBC_SHA)
|
||||
}
|
||||
if enable_ecdsa {
|
||||
// Sane cipher suite for TLS 1.2 with an ECDSA cert (as used by boringssl)
|
||||
client.run(addr, tls.VersionTLS12, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
|
||||
}
|
||||
|
||||
client.run(addr, tls.VersionTLS13, tls.TLS_CHACHA20_POLY1305_SHA256)
|
||||
client.run(addr, tls.VersionTLS13, tls.TLS_AES_128_GCM_SHA256)
|
||||
client.run(addr, tls.VersionTLS13, tls.TLS_AES_256_GCM_SHA384)
|
||||
|
||||
// TODO test with client cert
|
||||
// TODO test other kex methods besides X25519, like MTI secp256r1
|
||||
// TODO limit supported groups?
|
||||
|
||||
if client.failed > 0 {
|
||||
log.Fatalf("Failed handshakes: %d\n", client.failed)
|
||||
} else {
|
||||
fmt.Println("All handshakes passed")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user