package mtls import "crypto/tls" // Mode legt fest, ob mTLS erzwungen wird. Fuer Stufe-1-Einzel-LXC ist mTLS // laut Ticket "optional/nicht zwingend" (lokale Kommunikation) — ModeOff // liefert einen ganz normalen TLS-Server OHNE Client-Zertifikatspruefung, // damit Stufe-1-Betrieb unveraendert weiterlaeuft (Akzeptanzkriterium 3 / // Pruefung 3). type Mode string const ( ModeOff Mode = "off" // Stufe 1: kein mTLS-Zwang ModeRequired Mode = "required" // Stufe 2/3: Client-Zertifikat zwingend ) // ServerTLSConfig liefert die tls.Config fuer eine Modul-Instanz, die // eingehende Verbindungen ANDERER Modul-Instanzen annimmt. // // - ModeRequired: verlangt UND verifiziert ein Client-Zertifikat gegen // authority.TrustPool() (Akzeptanzkriterium 2) — eine Verbindung ohne // gueltiges Zertifikat wird vom TLS-Handshake selbst abgelehnt, bevor // irgendein Anwendungscode erreicht wird. // - ModeOff: normales TLS ohne Client-Zertifikatspruefung // (Akzeptanzkriterium 3 / Pruefung 3: Stufe-1-Betrieb funktioniert // weiterhin ohne mTLS-Zwang). func ServerTLSConfig(mode Mode, serverCert tls.Certificate, authority *Authority) *tls.Config { cfg := &tls.Config{Certificates: []tls.Certificate{serverCert}} if mode == ModeRequired { cfg.ClientAuth = tls.RequireAndVerifyClientCert cfg.ClientCAs = authority.TrustPool() } return cfg } // ClientTLSConfig liefert die tls.Config fuer eine Modul-Instanz, die eine // Verbindung zu einer ANDEREN Modul-Instanz aufbaut — praesentiert das // eigene Zertifikat und vertraut Gegenstellen, die von derselben Authority // signiert wurden. func ClientTLSConfig(mode Mode, clientCert tls.Certificate, authority *Authority) *tls.Config { cfg := &tls.Config{RootCAs: authority.TrustPool()} if mode == ModeRequired { cfg.Certificates = []tls.Certificate{clientCert} } return cfg }