From 81871bbad5f411debd34d492386ac1453e4a84c3 Mon Sep 17 00:00:00 2001 From: Kris Kwiatkowski Date: Sun, 19 Aug 2018 20:59:43 +0100 Subject: [PATCH] tls tris server: allow custom server keypairs (#128) --- _dev/tris-localserver/runner.sh | 12 ++--- _dev/tris-localserver/server.go | 78 +++++++++++++++++++++++++-------- 2 files changed, 66 insertions(+), 24 deletions(-) diff --git a/_dev/tris-localserver/runner.sh b/_dev/tris-localserver/runner.sh index 9b20c41..8871b51 100755 --- a/_dev/tris-localserver/runner.sh +++ b/_dev/tris-localserver/runner.sh @@ -1,10 +1,10 @@ #!/bin/sh -./tris-localserver -b 0.0.0.0:1443 -palg=rsa -rtt0=n 2>&1 & # first port: ECDSA (and no 0-RTT) -./tris-localserver -b 0.0.0.0:2443 -palg=ecdsa -rtt0=a 2>&1 & # second port: RSA (and accept 0-RTT but not offer it) -./tris-localserver -b 0.0.0.0:3443 -palg=ecdsa -rtt0=o 2>&1 & # third port: offer and reject 0-RTT -./tris-localserver -b 0.0.0.0:4443 -palg=ecdsa -rtt0=oa 2>&1 & # fourth port: offer and accept 0-RTT -./tris-localserver -b 0.0.0.0:5443 -palg=ecdsa -rtt0=oa -rtt0ack 2>&1 & # fifth port: offer and accept 0-RTT but confirm -./tris-localserver -b 0.0.0.0:6443 -palg=rsa -cliauth 2>&1 & # sixth port: RSA with required client authentication +./tris-localserver -b 0.0.0.0:1443 -cert=rsa -rtt0=n 2>&1 & # first port: ECDSA (and no 0-RTT) +./tris-localserver -b 0.0.0.0:2443 -cert=ecdsa -rtt0=a 2>&1 & # second port: RSA (and accept 0-RTT but not offer it) +./tris-localserver -b 0.0.0.0:3443 -cert=ecdsa -rtt0=o 2>&1 & # third port: offer and reject 0-RTT +./tris-localserver -b 0.0.0.0:4443 -cert=ecdsa -rtt0=oa 2>&1 & # fourth port: offer and accept 0-RTT +./tris-localserver -b 0.0.0.0:5443 -cert=ecdsa -rtt0=oa -rtt0ack 2>&1 & # fifth port: offer and accept 0-RTT but confirm +./tris-localserver -b 0.0.0.0:6443 -cert=rsa -cliauth 2>&1 & # sixth port: RSA with required client authentication wait diff --git a/_dev/tris-localserver/server.go b/_dev/tris-localserver/server.go index 0523974..f318a05 100644 --- a/_dev/tris-localserver/server.go +++ b/_dev/tris-localserver/server.go @@ -4,11 +4,14 @@ import ( "crypto/tls" "crypto/x509" "encoding/hex" + "errors" "flag" "fmt" + "io/ioutil" "log" "net/http" "os" + "strings" "time" ) @@ -22,15 +25,9 @@ const ( ZeroRTT_Accept = 1 << 1 ) -const ( - PubKeyRSA PubKeyAlgo_t = iota - PubKeyECDSA -) - type server struct { Address string ZeroRTT ZeroRTT_t - PubKey PubKeyAlgo_t TLS tls.Config } @@ -60,14 +57,7 @@ func NewServer() *server { } func (s *server) start() { - cert, err := tls.X509KeyPair([]byte(ecdsaCert), []byte(ecdsaKey)) - if s.PubKey == PubKeyRSA { - cert, err = tls.X509KeyPair([]byte(rsaCert), []byte(rsaKey)) - } - s.TLS.Certificates = []tls.Certificate{cert} - if err != nil { - log.Fatal(err) - } + var err error if (s.ZeroRTT & ZeroRTT_Offer) == ZeroRTT_Offer { s.TLS.Max0RTTDataSize = 100 * 1024 } @@ -91,12 +81,66 @@ func (s *server) start() { log.Fatal(httpServer.ListenAndServeTLS("", "")) } +// setServerCertificateFromArgs sets server certificate from an argument provided by the caller. Possible values +// for arg_cert: +// * "rsa": sets hardcoded RSA keypair +// * "ecdsa": sets hardcoded ECDSA keypair +// * FILE1:FILE2: Uses private key from FILE1 and public key from FILE2. Both must be in PEM format. FILE2 can +// be single certificate or certificate chain. +// * nil: fallbacks to "rsa" +// +// Function generate a panic in case certificate can't be correctly set +func (s *server) setServerCertificateFromArgs(arg_cert *string) { + var certStr, keyStr []byte + var cert tls.Certificate + var err error + + if arg_cert == nil { + // set rsa by default + certStr, keyStr = []byte(rsaCert), []byte(rsaKey) + } else { + switch *arg_cert { + case "rsa": + certStr, keyStr = []byte(rsaCert), []byte(rsaKey) + case "ecdsa": + certStr, keyStr = []byte(ecdsaCert), []byte(ecdsaKey) + default: + files := strings.Split(*arg_cert, ":") + if len(files) != 2 { + err = errors.New("Wrong format provided after -cert.") + goto err + } + keyStr, err = ioutil.ReadFile(files[0]) + if err != nil { + goto err + } + certStr, err = ioutil.ReadFile(files[1]) + if err != nil { + goto err + } + } + } + + cert, err = tls.X509KeyPair(certStr, keyStr) + if err != nil { + goto err + } + + s.TLS.Certificates = []tls.Certificate{cert} +err: + if err != nil { + // Not possible to proceed really + log.Fatal(err) + panic(err) + } +} + func main() { s := NewServer() arg_addr := flag.String("b", "0.0.0.0:443", "Address:port used for binding") - arg_palg := flag.String("palg", "rsa", "Public algorithm to use: rsa or ecdsa") + arg_cert := flag.String("cert", "rsa", "Public algorithm to use:\nOptions [rsa, ecdsa, PrivateKeyFile:CertificateChainFile]") arg_zerortt := flag.String("rtt0", "n", `0-RTT, accepts following values [n: None, a: Accept, o: Offer, oa: Offer and Accept]`) arg_confirm := flag.Bool("rtt0ack", false, "0-RTT confirm") arg_clientauth := flag.Bool("cliauth", false, "Performs client authentication (RequireAndVerifyClientCert used)") @@ -104,9 +148,7 @@ func main() { s.Address = *arg_addr - if *arg_palg == "ecdsa" { - s.PubKey = PubKeyECDSA - } + s.setServerCertificateFromArgs(arg_cert) if *arg_zerortt == "a" { s.ZeroRTT = ZeroRTT_Accept