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?
答案 0 :(得分:4)
没有机制可以为您执行此操作,但从go 1.8开始,您可以使用tls.Config对象中的VerifyPeerCertificate
字段指定自己的回调(这在服务器上都有效)和客户方)。
这采用具有以下签名的方法:
func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error
根据文档:
它接收对等方提供的原始ASN.1证书 正常处理发现的任何经过验证的链。
证书验证已经运行,因此您只需要应用您的特定逻辑:检查verifiedChains
中的叶证书(每个链中的第一个)并检查证书是否在允许的证书列表中(仅在你的情况下A
)。如果不是:返回错误,握手将失败。