From 80fe037aa883b276aab109643e18a55bf66bce9f Mon Sep 17 00:00:00 2001 From: Kris Date: Wed, 14 Feb 2018 07:27:33 +0000 Subject: [PATCH] (tests) Client Authentication: Tests against boringssl --- .travis.yml | 10 ++- _dev/boring/server.sh | 8 +++ _dev/interop.sh | 13 +++- _dev/tris-testclient/client.go | 113 +++++++++++++++++++++++++++++++-- 4 files changed, 134 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index e28173d..8afb3b6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,8 +8,12 @@ go: - 1.10.x env: - - MODE=interop CLIENT=boring SERVER=boring - - MODE=interop CLIENT=tstclnt SERVER=tstclnt + # 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=C # ClientAuth. CLIENT: tris, SERVER: boringssl + - MODE=interop CLIENT=tstclnt SERVER=tstclnt CLIAUTH=NONE - MODE=interop CLIENT=picotls ZRTT=1 # - MODE=interop CLIENT=mint # does not support draft 22 - MODE=bogo @@ -33,7 +37,7 @@ install: 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 [ -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 diff --git a/_dev/boring/server.sh b/_dev/boring/server.sh index b71e7b4..0311a97 100755 --- a/_dev/boring/server.sh +++ b/_dev/boring/server.sh @@ -16,4 +16,12 @@ bssl server \ -tls13-draft22-variant \ -accept 2443 -loop -www 2>&1 & +# Require client authentication (with ECDSA) +bssl server \ + -key ecdsa.pem \ + -min-version tls1.2 -max-version tls1.3 \ + -tls13-draft22-variant \ + -accept 6443 -loop -www \ + -require-any-client-cert -debug 2>&1 & + wait diff --git a/_dev/interop.sh b/_dev/interop.sh index 9478bf8..1eb24e8 100755 --- a/_dev/interop.sh +++ b/_dev/interop.sh @@ -22,6 +22,8 @@ elif [ "$1" = "RUN" ]; then 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" + + elif [ "$1" = "0-RTT" ]; then # 0-RTT IP=$(docker inspect -f '{{ .NetworkSettings.IPAddress }}' tris-localserver) @@ -46,13 +48,18 @@ elif [ "$1" = "RUN-CLIENT" ]; then servername="$2-localserver" docker run --rm --detach --name "$servername" \ --entrypoint /server.sh \ - --expose 1443 --expose 2443 \ + --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 - docker run --rm tris-testclient -ecdsa=false $IP:1443 # RSA - docker run --rm tris-testclient -rsa=false $IP:2443 # ECDSA + # 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 + [[ $3 =~ .*C.* ]] && docker run --rm tris-testclient -rsa=false -cliauth $IP:6443 + # TODO maybe check server logs for expected output? fi diff --git a/_dev/tris-testclient/client.go b/_dev/tris-testclient/client.go index e76ea65..d48cf12 100644 --- a/_dev/tris-testclient/client.go +++ b/_dev/tris-testclient/client.go @@ -2,6 +2,7 @@ package main import ( "crypto/tls" + "crypto/x509" "flag" "fmt" "io" @@ -27,8 +28,10 @@ var cipherSuiteIdToName = map[uint16]string{ } type Client struct { - KeyLogWriter io.Writer - failed uint + KeyLogWriter io.Writer + failed uint + client_cert tls.Certificate + client_certpool *x509.CertPool } func (c *Client) run(addr string, version, cipherSuite uint16) { @@ -39,6 +42,8 @@ func (c *Client) run(addr string, version, cipherSuite uint16) { MaxVersion: version, CipherSuites: []uint16{cipherSuite}, KeyLogWriter: c.KeyLogWriter, + Certificates: []tls.Certificate{c.client_cert}, + RootCAs: c.client_certpool, } con, err := tls.Dial("tcp", addr, tls_config) if err != nil { @@ -71,10 +76,12 @@ func (c *Client) run(addr string, version, cipherSuite uint16) { func main() { var keylog_file string - var enable_rsa, enable_ecdsa bool + var enable_rsa, enable_ecdsa, client_auth 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.BoolVar(&client_auth, "cliauth", false, "Whether to enable client authentication") flag.Parse() if flag.NArg() != 1 { flag.Usage() @@ -98,6 +105,19 @@ func main() { log.Println("Enabled keylog") } + if client_auth { + var err error + client.client_cert, err = tls.X509KeyPair([]byte(client_crt), []byte(client_key)) + if err != nil { + panic("Can't load client certificate") + } + + client.client_certpool = x509.NewCertPool() + if !client.client_certpool.AppendCertsFromPEM([]byte(client_ca)) { + panic("Can't load client CA cert") + } + } + 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) @@ -107,11 +127,11 @@ func main() { 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? @@ -121,3 +141,88 @@ func main() { fmt.Println("All handshakes passed") } } + +const ( + client_ca = `-----BEGIN CERTIFICATE----- +MIIFYDCCA0igAwIBAgIJAPpBgIvtQb1EMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQwHhcNMTgwMjEzMjAxNjA3WhcNMTkwMjEzMjAxNjA3WjBF +MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50 +ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC +CgKCAgEAr4xgdmB4DaEh8zRFmg/1ZxYhQZMUP0iQX/Y8nDWxNlcd42p3TgpY1biz +jrq58ln9Om4U/GAn2RmtBAynSBXIlR5oVa44JeMM8Ka8R/dMKyHpF0Nj2EJB9unb +TC33PfzOlnKQxATwevnnhI6tGluWmwvxXUi7WnX0di+nQg9HrIVom3KrmRr2/41y +g497ccYUuNnKE6sewGdGzw045oWZpMDA2Us+MFo1IywOurjaM9bueRhPTcIiQ8RE +h7qb+FRwfxaj9ynZA2PCM7WMSSWCiZJV0uj/pshYF2lvtJcJef4dhwnsYBpc+mgx +2q9qcUBeo3ZHbi1/PRqjwSmcW3yY5cQRbpYp6xFmgmX3oHQkVXS0UlpNVZ+morcS +HEpaK8b76fCFcL5yFsAJkPPfny1IKU+CfaVq60dM/mxbEW6J4mZT/uAiqrCilMC+ +FyiATCZur8Ks7p47eZy700DllLod7gWTiuZTgHeQFVoX+jxbCZKlFn5Xspu8ALoK +Mla/q83mICRVy3+eMUsD7DNvoWYpCAYy/oMk0VWfrQ48JkCGbBW2PW/dU2nmqVhY +/11rurkr+1TUvYodnajANtXvUjW1DPOLb4dES4Qc4b7Fw8eFXrARhl5mXiL5HFKR +/VnRshiJ+QwTVkxl+KkZHEm/WS8QD+Zd8leAxh9MCoaU/XrBUBkCAwEAAaNTMFEw +HQYDVR0OBBYEFKUinuD1xRvcNd2Wti/PnBJp7On1MB8GA1UdIwQYMBaAFKUinuD1 +xRvcNd2Wti/PnBJp7On1MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD +ggIBAJdJrNBftqkTs2HyuJ3x5RIsTxYh85hJYwNOdFLyzVG6HER9jRCnvmNTjG0O +I5wz5hQvDpwXs4BCCXHQZrTLAi3BEjq3AjrmR/XeGHulbWh3eh8LVu7MiLRgt+Ys +GnL2IaERrbkje24nCCMNPbI3fGDQEhTIYmmX8RJp+5BOJgCycKk6pFgfrjJv2C+d +78pcjlYII6M4vPnr/a08M49Bq6b5ADvIfe5G2KrUvD/+vwoAwv6d/daymHCQ2rY5 +kmdVk9VUp3Q4uKoeej4ENJSAUNTV7oTu346oc7q9sJffB5OltqbrE7ichak7lL+v +EjArZHElAhKNFXRZViCMvGDs+7JztqbsfT8Xb6Z27e+WyudB2bOUGm3hKuTIl06D +bA7yUskwEhmkd1CJqO5RLEJjKitOqe6Ye0/GsmPQNDK8GvyXTyGQK5OqBuzEexF0 +mlPoIhpSVH3K9SkRTTHvvcbdYlaQLi6gKq2uhbk4PnS2nfBtXqYIy9mxcgBJzLiB +/ydfLcf3GClwgvO1JHp6qAl4CO7oe8jqHpoGuznwi1aqkTyNkQWh0OXq3MS+dyqB +2yXFCFIeKCx18TE1OtuTD3ppBDjpyd0o/a6kYR3FDmdks/J33bGwLsLH3lbN6VjF +PNfNkaE1tfkpSGYsuT1DPxX8aAT4JLUfZ1Si6iO+E0Sj9LXA +-----END CERTIFICATE-----` + client_crt = `-----BEGIN CERTIFICATE----- +MIID/jCCAeYCAQEwDQYJKoZIhvcNAQELBQAwRTELMAkGA1UEBhMCQVUxEzARBgNV +BAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0 +ZDAeFw0xODAyMTMyMDU0MjZaFw0xOTAyMTMyMDU0MjZaMEUxCzAJBgNVBAYTAkFV +MRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRz +IFB0eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDD1li7/35Q +C/T6FACSbsd0WlImu42i6w96wfngAfEgbz5Ip+IA2rJ8G5LNHTYYCpr9LlmhY6zm +soHgAkff6XwUnZaetX01UmGP4CD4D3UumkR1uKY4bCSNImm53SZgelOznpsqAWKE +zosMrDcOAJKJSN411KwVzWysfRCPyxvmLETzU9KHFCJ1oY3t1HzYIAqpHv9sMSst +dNHW3X7bWEAVKCQMKO+rWe/wAhE4iTVdlRi02oRoRWSVj41+nk6jI8KJNq70stHc +QSST0A7SUacPYKJWqJRhP1pZ6k4G3ZVE8332az7jvcN1uGGjERZoUbZxGB+mbMCC +GJwnwnNiI6/hAgMBAAEwDQYJKoZIhvcNAQELBQADggIBADNr6QMl57CdHEzNwc2M +CSZsuOLakp8YiovVDOXJ/p/lykUIIcR1rI1iNfb8oOFTZmrndGZVAh76EExdMHYG +m+4Vr2+z/73AZwvhhnLhftOKFFwkdjCfXouPlkc/zmhOORakIFGlLZFkuZRY6k2D +Q8uIt7E5uXSVl11A1LxN5X8lhK2G4lxJZuj1AqEFj9QD44Qy+MdgX38lzGCEXd8c +Y5K8zLJGbgXgYaFxqd0bImfjgjj82+Mui0OTV5PcRlczJX08ygKjcoAMVyvPHu72 +3zzxvoNcqUrvbptVvg9c7FSOpK95YZOe1LiyqZCwNJQl4fPRE++XQ4zDNdyiAp76 +a6BQg/M8gOpV/VBMTsNDr/yP/7eBqkfvU7jLfz7wKMDdcjeZnKom42f+/XOLEo6E +hyDuHGdQh10bZD/Ukcs69+pA3ioic1A8pQzAElH3IuDBsMJg30x8tACLKNcUY8BE +2eJgrCxWcvq88DeAT03W9AVpFZA8ZQUR3SHCquMBFogsmUDDMN+CoC0u5dBwHP+O +9rmWOXn8gp/zBCKGwemgVV5vSNzJs7z3aoqIiAABl56LBaXxjKzRmXoB/SyUW5zl +1zy4SQTE6SJYqqU6h2yRdT8n0oWN3AMy0VxbJTRq32kdYJVQK9cLKVqpxtCCtPnN +3lV+HDsj7k+AJjHiu1F4O+sp +-----END CERTIFICATE-----` + client_key = `-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAw9ZYu/9+UAv0+hQAkm7HdFpSJruNousPesH54AHxIG8+SKfi +ANqyfBuSzR02GAqa/S5ZoWOs5rKB4AJH3+l8FJ2WnrV9NVJhj+Ag+A91LppEdbim +OGwkjSJpud0mYHpTs56bKgFihM6LDKw3DgCSiUjeNdSsFc1srH0Qj8sb5ixE81PS +hxQidaGN7dR82CAKqR7/bDErLXTR1t1+21hAFSgkDCjvq1nv8AIROIk1XZUYtNqE +aEVklY+Nfp5OoyPCiTau9LLR3EEkk9AO0lGnD2CiVqiUYT9aWepOBt2VRPN99ms+ +473DdbhhoxEWaFG2cRgfpmzAghicJ8JzYiOv4QIDAQABAoIBADKcbZhAYjt7q5cJ +nlA5svA9+2cpJ2SITRrTkKk0t0VDmpwaTw0bd+8dDSZXO0ihTQbLeLx9zwxb67ah +wEN8yuVlCK0BiFdEcBRHvx18mTMvCSxHSSXhxNx4nUw8fBOI6aLNBZqoevaJjmP7 +CctjmHtESrEswkBsM36sX6BZxF8Kc4Q5Znuxqksnl6HNoxnjhmygJmYCFTToiTHa +f2HWKBiZfgfxX7WEuHer3h6nmBbBCOX1/hcipBMBBVIqFl1ZSIF/B3lR8UV4/X+a +SNMqggOqkEIuHKkSCKo1lNxEPP2p54EHrKkjepoqMzIFuYnn4qWesMznpmy+zBGB +6PCjfzUCgYEA92etvRVQjBx8dHTSiyCNbS1ELgiCkzar8PGH+ytTIaj/TTF1LfAi +UYRp5MtOKmQXxE3IRLDF8P8rEKC06aV12hVwhd2xfHjje+KZkwWZ2PIj+GbK7f1r +MvKN5eE0NhGiSvu5SiFuks/SV8Qc4StFPmiWf33XKvJuAWNkCu+bUZsCgYEAyqQL +nVNKTlgHNKDJKMHi/buZt8wtwGGXCxcv+w88PmEC0OCbH/V2niCPLvFmK1xDXpru +k7z9FTc+QeasEMtxY/Gcs3IgUzxOHxAL7cn6KBM44uDhpIcv3BFWtR053acVU6S4 +IKuijWIJNJEk2qksgQTX7Mv/xq2uXvfZqajdKjMCgYEA3x+5F9s+Pm5+a4TkUSc1 +hS4a3C0+ncfjv7QEwCftnGDOhu7A0IJOYRg7bGVShHaq3JaNtC19BwEJ9MALCOD5 +bYqCZahvpmNcPeE6Qdb+TiLq/96sy4AOiu8nvBejv9Ode2SUUd/e2jbla9Ppe8VL +eKJYgHicchYb0dKyag54FFsCgYEAuToEB9W3aS9bvsZtuZyooSfXFcND2sMZrqCO +Uh2WAqroSQfVo/vaZiX623z62A2o4xQZmd+5MqhhdxmkFGHyDtouU3SxiYPpIMmp +Lb1etT0E1ZWbi6mqnK0YpcrGNw5gFynMyMg6eKOxKGS33EuhC3ni6Wd7MB9X8ST6 +x/M73jMCgYBBge3/ugnZPE78TDL3DdefrjeYFaKhVc622eimS/MEPbkbdxh8azTM +LAoibwDU1NC8/3MfOBYMe6Qklu3kjexOJrfdo0Z7Khgd9F8A4tKwslUndSSlAfKF +2rjfqabVMZMLZ2XEbA4W5JTfaZS4YYGcrjY7+i7OsnSxoYG2sb+xlQ== +-----END RSA PRIVATE KEY-----` +) \ No newline at end of file