Elaborating on the previous answer, which led me to the source of the issue 
I'm facing but did not quite solve the problem.

In case you have no control over the server, you are using private CA, and 
the server does not include Certificate Authorities 
<https://tools.ietf.org/html/rfc8446#section-4.2.4> extension in TLS 
Handshake Certificate Request, in this case golang will not include 
certificates from private CAs even if they are included in the tls 
configuration. This can be solved by implementing 
tls.Config.GetClientCertificate and doing the cert, err := 
tls.LoadX509KeyPair(certFile, keyFile) part there.

Hope that helps.

On Wednesday, May 20, 2020 at 2:27:58 AM UTC+3 mspet...@gmail.com wrote:

> 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/dc66f3b0-36bb-4970-90e6-588282b4fbben%40googlegroups.com.

Reply via email to