使用golang相互TLS身份验证信任特定客户端

I've had a successful TLS mutual authentication client/server setup in Go for a while, but now looking to make some small tweaks.

Specifically, I'm wondering if there is a way to require only a specific client certificate for mutual auth.

I'm currently using something like this:

    // Load cert and build pool
    caCert, _ := ioutil.ReadFile(caPath)        
    caCertPool := x509.NewCertPool()
    caCertPool.AppendCertsFromPEM(caCert)

    // Require client authentication
    tlsConfig := &tls.Config{
        ClientAuth: tls.RequireAndVerifyClientCert,
        ClientCAs: caCertPool,
    }

Which works fine, however if the PEM file I'm reading in is actually a certificate chain (A issued by B, and B is a root CA), this will actually end up trusting any certificate issued by B, which I don't want.

Is there any way I can tweak this code to ONLY trust the specific A certificate?

It seems that if I only include A in the loaded PEM file, the server handshake code tells the client "send me all your certs signed by A", which of course is not what I want, as cert A is not signed by A.

Ideally I'd want to say "you require specifically certificate A" to connect successfully. Is there such a mechanism?

There is no mechanism to do this for you, but starting with go 1.8 you can specify your own callback using the VerifyPeerCertificate field in the tls.Config object (this works both on the server and client side).

This takes a method with the following signature:

func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error

Per the docs:

It receives the raw ASN.1 certificates provided by the peer and also any verified chains that normal processing found.

The certificate validation has already run, so you only need to apply your specific logic: examine the leaf certificates (first in each chain) in verifiedChains and check that the certificate is in the list of allowed certificates (just A in your case). If it is not: return an error and the handshake will fail.