I am trying to understand the mutual TLS working, I have the following example:
I have a client who wants to connect to server "svc1.example.com"
but the server has a
server certificate with a commonName as "svc1.example.cloud" and a SAN as "svc.example.test.cloud".
Now when I make a GET request, I get the following:
x509: certificate is valid for svc.example.test.cloud, not svc1.example.com.
So, my question is should I make a the TLS clientConfig changes to include the servername? or should I add a custom verifyPeerCertificate function in the TLS client config, something like below?
Please, let me know, what should be the Servername and what should I check for in the verifyPeerCertificate function.
func customverify(customCName func(*x509.Certificate) bool) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
if customCName == nil {
return nil
}
return func(_ [][]byte, verifiedChains [][]*x509.Certificate) error {
for _, certs := range verifiedChains {
leaf := certs[0]
if customCName(leaf) {
return nil
}
}
return fmt.Errorf("client identity verification failed")
}
}
func configureClient(certFile, keyFile string) (*http.Client, error) {
certpool, err := addRootCA()
if err != nil {
return nil, err
}
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, err
}
transport := ytls.NewClientTransport()
transport.TLSClientConfig.Certificates = []tls.Certificate{cert}
transport.TLSClientConfig.RootCAs = certpool
//transport.TLSClientConfig.ServerName = expectedCName
transport.TLSClientConfig.VerifyPeerCertificate = customverify(func(cert *x509.Certificate) bool {
return cert.Subject.CommonName == "svc1.example.cloud"
})
httpClient := &http.Client{Transport: transport}
return httpClient, nil
}