ac01048c5e
Similar to boringssl, reuse the NSS client image for the NSS server test against the tris client. Bump the NSS version to 3.34.1 gain support for TLS 1.3 keylogging which is useful while debugging. Adjust read check to fix intermittent NSS test failures: https://github.com/cloudflare/tls-tris/issues/58
124 lines
3.4 KiB
Go
124 lines
3.4 KiB
Go
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)
|
|
// A non-zero read with EOF is acceptable and occurs when a close_notify
|
|
// is received right after reading data (observed with NSS selfserv).
|
|
if !(n > 0 && err == io.EOF) && 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")
|
|
}
|
|
}
|