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 [email protected].
For more options, visit https://groups.google.com/d/optout.