I know this is an old thread, but I found it, so others might, too. I struggled with a similar problem of the Go HTTP client not sending client certs when challenged by the server. Yet, curl worked fine when given the same client certs, calling the same server endpoint. The cert chains I was dealing with look like
leaf + intermediate + root The solution for me was to provide the server (Envoy proxy) with a the root cert AND intermediate cert, the latter of which signed my Go client cert. When the server challenges the client for its cert, the server will send a TLS Certificate Request with, among other things, the certificate authority that must have signed the client cert. Without including the intermediate cert with the root cert on the server side, the client cannot not build a complete path from its client cert to the root and therefore cannot determine which cert to send in response. The client will not use tls.Config.RootCAs in this analysis (RootCAs is for validating the server cert chain). Moreover, when the client parses its cert with cert, err := tls.LoadX509KeyPair(*certFile, *keyFile) only the leaf is returned even if the certFile contains the concatenated intermediate. Including the full cert bundle on the server side solves this for me. Hope that helps. On Tuesday, March 17, 2015 at 10:19:01 AM UTC-7, Dots Connected wrote: > > Hello! > > I am trying to access an API served by nginx (with a self-signed SSL cert) > that requires client certificate authentication, and while I can > successfully auth with curl, I unable to accomplish the same with golang. > > Example using curl: > > # Will not work > curl -k https://127.0.0.1/api > > # Works > curl -k -E example_key+cert.pem https://127.0.0.1/api > > > I found an example from this list that I've tried to adapt: > > https://groups.google.com/forum/#!topic/golang-nuts/dEfqPOSccIchttps://groups.google.com/forum/#!topic/golang-nuts/dEfqPOSccIc > > <https://groups.google.com/forum/#!topic/golang-nuts/dEfqPOSccIc> > And another from github: > https://gist.github.com/michaljemala/d6f4e01c4834bf47a9c4 > > Despite this, golang gets the same result as the first curl with no client > cert. > Am I missing something, or is this a regression in go? > > I'm on go version go1.4.2 linux/amd64. My code (or via > http://pastebin.com/LGiXZpgx): > > package main > > import ( > "crypto/tls" > "io/ioutil" > "log" > "net/http" > ) > > func main() { > > certFile := "example_cert.pem" > keyFile := "example_key.pem" > > // Load client cert > cert, err := tls.LoadX509KeyPair(certFile, keyFile) > if err != nil { > log.Fatal(err) > } > > // Setup HTTPS client > tlsConfig := &tls.Config{ > Certificates: []tls.Certificate{cert}, > ClientAuth: tls.RequireAndVerifyClientCert, > InsecureSkipVerify: true, > } > tlsConfig.BuildNameToCertificate() > > transport := &http.Transport{ > TLSClientConfig: tlsConfig, > } > client := &http.Client{ > Transport: transport, > } > > // Do GET something > resp, err := client.Get("https://localhost/api/") > if err != nil { > log.Fatal(err) > } > defer resp.Body.Close() > > // Dump response > data, err := ioutil.ReadAll(resp.Body) > if err != nil { > log.Fatal(err) > } > log.Println(string(data)) > } > > -- 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. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/43ca36e6-bffe-4b2f-8ee6-c34288685023%40googlegroups.com.