mTLS Handshake
Source: Custom
Topics: crypto/tls, crypto/x509, certificate chains, mutual TLS
Problem
Build the certificate plumbing for mutual TLS: generate a CA, issue certs signed by it,
and configure a server that requires + verifies client certificates.
Requirements:
GenerateCA(commonName string) (certPEM, keyPEM []byte, err error) — self-signed CA cert (ECDSA P-256), IsCA: true.
GenerateCert(commonName string, caCertPEM, caKeyPEM []byte) (certPEM, keyPEM []byte, err error) — leaf cert signed by the CA. If commonName parses as an IP, set it as an IP SAN; otherwise as a DNS SAN (so hostname verification works in tests against 127.0.0.1).
ServerTLSConfig(certPEM, keyPEM, caCertPEM []byte) (*tls.Config, error) — server config with ClientAuth: tls.RequireAndVerifyClientCert and ClientCAs set to a pool containing the CA.
ClientTLSConfig(certPEM, keyPEM, caCertPEM []byte) (*tls.Config, error) — client config presenting its own cert and trusting the CA via RootCAs.
Type:
func GenerateCA(commonName string) (certPEM, keyPEM []byte, err error)
func GenerateCert(commonName string, caCertPEM, caKeyPEM []byte) (certPEM, keyPEM []byte, err error)
func ServerTLSConfig(certPEM, keyPEM, caCertPEM []byte) (*tls.Config, error)
func ClientTLSConfig(certPEM, keyPEM, caCertPEM []byte) (*tls.Config, error)
Key concepts
- x509.CreateCertificate: signs a certificate template with a parent (the CA) and the CA's private key — self-signed when
template == parent.
- PEM encoding:
pem.EncodeToMemory wraps DER bytes with -----BEGIN CERTIFICATE----- headers.
- ClientAuth modes:
tls.RequireAndVerifyClientCert rejects the handshake unless the client presents a cert chaining to ClientCAs.
- ConnectionState().PeerCertificates: after a successful handshake, the server reads the client's verified identity from
Subject.CommonName.
- SAN vs CommonName: modern Go (
crypto/tls) verifies hostnames against Subject Alternative Names, not CommonName — so leaf certs need DNSNames or IPAddresses.
Run
go test -v ./challenges/networking/mtls-handshake/
Sign in to submit your solution.