x509 mTLS with client config using InsecureSkipVerify: false and Server config using tls.RequireAndVerifyClientCert **NOT USING the SAME Cert/Key PAIR** for both client and server


(Rob) #1

I’m trying to find the right configuration for tls.Config - both on the client-side and the server-side that satisfies the following constraints:

  1. We generate separate certificates from a CA - one for the client and a distinct and separate one for the server
  2. Certificates are generated using golang x509.CreateCertificate - not openssl .
  3. Client’s tls.Config must specifies InsecureSkipVerify is false
  4. Server’s tls.Config must specifies ClientAuth is RequireAndVerifyClientCert

I’ve not been able to generate Certificates that satisfy this set of constraints and allows for a connection to occur. The closest that I come is when I use the CA cert for both the client and the server - all works between the client and the server only in that case.

If I generate a CA cert and use it to create and sign the server, and generate a client cert signed by the CA Cert - I fail with:

failed to connect: x509: certificate signed by unknown authority (possibly because of “crypto/rsa: verification error” while trying to verify candidate authority certificate “localhost”).

Same error occurs if the client uses the CA Cert to connect to the server (when the server uses a Cert generated and signed by the CA).

When I tell the server to use the CA Cert for the server, and the client uses a cert generated and signed by the CA, I fail AFTER the Dial when I attempt to read on the connection with:

Err reading on conn: remote error: tls: bad certificate

only when the Server and the Client use the IDENTICAL certificate will the Client and Server connect and exchange data.

All thoughts and ideas welcome. I can post a git repo if anyone wants to dive in and take a peek. Fair warning - I’m doing this to demonstrate dynamic certificate generation with dynamic tls.Config and validation using GetConfigForClient and VerifyPeerCertificate using a customer validator.


(Jakob Borg) #2

Have you added your custom CAs to RootCAs (in tls.Config) or the system trust store?

Note that this is only called after normal validation (host name, trust chain, …) succeeds.


(Rob) #3

thanks for your reply. I’ve since done some research into the crypto/x509/verify.go file and found the issue - I think there’s an issue using NewCertPool over SystemCertPool in that using former builds a zero-length chain regardless of what certs you present from the server…. To me I’d classify it as as bug - but maybe I’m wrong.