package mtls import ( "crypto/tls" "crypto/x509" ) // NewServerTLSConfig builds the *tls.Config for the Pangolin gRPC server. // // Single-port strategy: // - ClientAuth = tls.VerifyClientCertIfGiven: agents that have not yet enrolled // complete the TLS handshake without a client cert; the identity interceptor // enforces cert presence for all non-Enroll RPCs at the application layer. // - ClientCAs is set to a pool containing only the Pangolin Node CA, so the TLS // stack will verify any presented certificate against it. // - VerifyPeerCertificate is wired to CRL.VerifyPeerCertificate: if the leaf cert // CN is revoked the handshake fails immediately, before any RPC handler runs. // - Minimum TLS version is 1.3. // // The caller must set cfg.Certificates with the server's own TLS certificate // (typically from Let's Encrypt) before using this config. func NewServerTLSConfig(ca *CA, crl *CRL) *tls.Config { pool := x509.NewCertPool() pool.AddCert(ca.CACert()) return &tls.Config{ ClientAuth: tls.VerifyClientCertIfGiven, ClientCAs: pool, MinVersion: tls.VersionTLS13, VerifyPeerCertificate: crl.VerifyPeerCertificate, } }