Hi, I've a legacy application at hand that has a nginx as TLS offloader in front of it. Besides a simple frontend the application offers an API including a PKI infrastructure (CSRs are pushed to server, signed CRTs are returned). The nginx is configured to optionally request a client certificate ("ssl_verify_client optional") from the requesting party (browsers, IoT devices, ...).
This approach is working for most browsers except OS X's Safari. nginx offers a list acceptable client certificate CA names but Safari tends to ignore this list and prompts the user to chose a certificate (including iCloud certificates and stuff). Browsers are not necessarily required to provide a client certificate. IoT devices are configured to always provide a client certificate. Differing from nginx's and Apache's SSL configuration, the TLS implementation of golang seems to offer another client authentication mechanism: VerifyClientCertIfGiven (see https://golang.org/pkg/crypto/tls/#ClientAuthType). So I decided to give golang a try (as a potential TLS offloader replacing nginx) and came up with the following simple TLS secured HTTP server: package main import ( "log" "net/http" "crypto/tls" "crypto/x509" "encoding/pem" "io/ioutil" "fmt" ) func handler(w http.ResponseWriter, req *http.Request) { w.Header().Set("Content-Type", "text/plain") w.Write([]byte("Test.\n")) } func main() { http.HandleFunc("/", handler) pemByte, _ := ioutil.ReadFile("ssl/ca.pem") block, pemByte := pem.Decode(pemByte) cert, err := x509.ParseCertificate(block.Bytes) if err != nil { fmt.Println(err) } certPool := x509.NewCertPool() certPool.AddCert(cert) server := &http.Server{ TLSConfig: &tls.Config{ ClientAuth: tls.VerifyClientCertIfGiven, ClientCAs: certPool, }, Addr: "0.0.0.0:10443", } server.TLSConfig.BuildNameToCertificate() err = server.ListenAndServeTLS("ssl/server.crt", "ssl/server.key") if err != nil { log.Fatal(err) } } My initial thought when reading the const "VerifyClientCertIfGiven" was that a list of acceptable client certificate CA names will NOT be sent to the connecting client, but certificates that are provided will be validated against the configured ClientCAs. I had a look into the server TLS implementation and I'm wondering about the conditional statement "if config.ClientAuth > RequestClientCert" around the certificate request message (see https://github.com/golang/go/blob/release-branch.go1.7/src/crypto/tls/handshake_server.go#L409). I'm new to golang and my knowledge of the TLS spec isn't good either but I'm wondering if this conditional would be better changed to "c.config.ClientAuth == RequireAnyClientCert || c.config.ClientAuth == RequireAndVerifyClientCert || c.config.ClientAuth == RequestClientCert"? >From my point of view "VerifyClientCertIfGiven" has no special meaning and acts exactly as RequireAndVerifyClientCert. Am I missing something? BR, Sven -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.