I have many clients connecting to my TLS tcp endpoint using different certificates. 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 before I tell it which server certificate and key to use, I can access ConnectionState().PeerCertificates[0]
and first read clientCert.Subject.CommonName
. That is, each CommonName certificate requires a different server-side certificate and key. It's not just one server certificate and key used for all connections.
listener, err := tls.Listen("tcp", ":8080", baseTLSConfig) for { conn, _ := listener.Accept() clientCert := conn.(*tls.Conn).ConnectionState().PeerCertificates[0] switch clientCert.Subject.CommonName {
But this conversion fails: (*tls.Conn)
and I cannot call ConnectionState
or I make another tcp.Server call but len(PeerCertificates)
is zero. I have tried before:
GetConfigForClient: func(hello *tls.ClientHelloInfo) (*tls.Config, error) {
Pass it to tls.RequireAndVerifyClientCert
or other than that, but *tls.ClientHelloInfo doesn't have the information I need.
There is no way to decide which server certificate to use based on the client certificate.
In the TLS handshake, the server first sends its server certificate and then requests the client certificate, and only after that the client sends its client certificate to the server.
The above is the detailed content of How to get clientCert.Subject.CommonName from golang tcp handshake?. For more information, please follow other related articles on the PHP Chinese website!