Issue with client tls authentication

Hello

my issue is that server requests certificate from client afer first request to from client to server, but in response client does not send it back. I tried this also with NodeJs if certificates are ok, and there it works. I asked this question on few forums but nobody is really know how to fix this :pensive:

my code:

import (
    "bytes"
    "crypto/tls"
    "crypto/x509"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

func main() {

    xml := `
    <Packet>
<Header>
 <ID>1231232132132354234</ID>
 </Header>
 <Body>
 <Item>
 <Content>SMS</Content>
 <Phone_no>+123123213</Phone_no>
 <Content>test</Content>
 <OriginAddress>Posiljatelj</OriginAddress>
 </Item>
 </Body>
</Packet>
    `

    // Load client cert
    cert, err := tls.LoadX509KeyPair("../cert/certNEW.pem", "../cert/serverNEW.key")
    if err != nil {
        log.Fatal(err)
    }

    // Load CA cert
    caCert, err := ioutil.ReadFile("../cert/cacerts.cer")
    if err != nil {
        log.Fatal(err)
    }
    caCertPool := x509.NewCertPool()
    caCertPool.AppendCertsFromPEM(caCert)

    // Setup HTTPS client
    tlsConfig := &tls.Config{
        Certificates:       []tls.Certificate{cert},
        RootCAs:            caCertPool,
        InsecureSkipVerify: true,
    }

    tlsConfig.BuildNameToCertificate()
    transport := &http.Transport{TLSClientConfig: tlsConfig}
    client := &http.Client{Transport: transport}

    resp, err := client.Post("https://api.url", "text/xml", bytes.NewBuffer([]byte(xml)))

    if err != nil {
        fmt.Println(err)
    }
    contents, err := ioutil.ReadAll(resp.Body)
    fmt.Printf("%s\n", string(contents))
}

I made this recommendation when you asked on the mailing list:

Try without using Config.BuildNameToCertificate.

You didn’t say whether you tried it. Using that method makes the TLS package respond to certificate requests based on their common name. It’s likely that won’t do what you want in a client scenario. Must likely you just want to send the first certificate in the list.

Hello @calmh

I tried this already. sorry for not posting this in question
//tlsConfig.BuildNameToCertificate()

but it is the same :frowning:

Then I’m not sure. You’re doing more than I usually do (setting CA pool and stuff), but otherwise it looks like it should work. From your file names it looks like the key might not match the certificate, but it shouldn’t load if that were the case.

yes, i tried that, if the key and public key are not matched go will bring error when starting program.
But certificates are i guess ok as in NodeJs it is working with the same certificates…

and i do not need to include rootCA as it is already on trusted list. but still if it works with other programing languages it should aslo work here i guess…

@calmh hey.
Can I ask you for help with using: tls.Config.GetClientCertificate which is defined like GetClientCertificate func(*CertificateRequestInfo) (*Certificate, error) under config for tls.

As I good feedback on git but do not know how to define this:slight_smile:
what I think is happening here is that the Certificate Request applies constraints (RSA vs ECDSA, or a specific issuer) which are not satisfied by your certificate.”

you can bypass the default logic by using tls.Config.GetClientCertificate

I guess override that function and return your certificate from it. If that works, when the certificate doesn’t satisfy the constraints, I have no idea.

Hey @calmh
this is the thing. How to use this function to do that :slight_smile:
tnx

Like this, roughly:

https://play.golang.org/p/EB32QUT2U0s

1 Like

@calmh thank you so much for this! Now it is working :slight_smile:

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.