I have a bunch of clients connecting to my TLS tcp endpoint with different certs. I'm trying to use RequireAndVerifyClientCert
:
certPool := x509.NewCertPool()
clientCACert, err := ioutil.ReadFile("client-ca.crt")
if err != nil {
log.Fatal(err)
}
certPool.AppendCertsFromPEM(clientCACert)
// Create a base TLS config
baseTLSConfig := &tls.Config{
ClientCAs: certPool,
ClientAuth: tls.RequireAndVerifyClientCert,
}
So I can get access to ConnectionState().PeerCertificates[0]
and read the clientCert.Subject.CommonName
first BEFORE I tell it which server cert and key to use. i.e. each CommonName cert needs a different server side cert and key. It's not just one server cert and key for all the connections.
listener, err := tls.Listen("tcp", ":8080", baseTLSConfig)
for {
conn, _ := listener.Accept()
clientCert := conn.(*tls.Conn).ConnectionState().PeerCertificates[0]
switch clientCert.Subject.CommonName {
But either this cast fails: (*tls.Conn)
and I can't call ConnectionState
or I make another tcp.Server call but then len(PeerCertificates)
is zero. I've tried:
GetConfigForClient: func(hello *tls.ClientHelloInfo) (*tls.Config, error) {
passing that in vs. tls.RequireAndVerifyClientCert
or in addition to but the *tls.ClientHelloInfo doesn't have the info I need.
So I can get access to ConnectionState().PeerCertificates[0] and read the clientCert.Subject.CommonName first BEFORE I tell it which server cert and key to use.
It is impossible to decide which server certificate to use based on the client certificate.
In the TLS handshake the server first sends its server certificate, then requests the client certificate and only after this the client will sends its client certificate to the server.