99 lines
2.6 KiB
Go
99 lines
2.6 KiB
Go
// FILE: src/internal/tls/server.go
|
|
package tls
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"fmt"
|
|
"os"
|
|
|
|
"logwisp/src/internal/config"
|
|
|
|
"github.com/lixenwraith/log"
|
|
)
|
|
|
|
// ServerManager handles TLS configuration for server components.
|
|
type ServerManager struct {
|
|
config *config.TLSServerConfig
|
|
tlsConfig *tls.Config
|
|
logger *log.Logger
|
|
}
|
|
|
|
// NewServerManager creates a TLS manager for servers (HTTP Source/Sink).
|
|
func NewServerManager(cfg *config.TLSServerConfig, logger *log.Logger) (*ServerManager, error) {
|
|
if cfg == nil || !cfg.Enabled {
|
|
return nil, nil
|
|
}
|
|
|
|
m := &ServerManager{
|
|
config: cfg,
|
|
logger: logger,
|
|
}
|
|
|
|
cert, err := tls.LoadX509KeyPair(cfg.CertFile, cfg.KeyFile)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to load server cert/key: %w", err)
|
|
}
|
|
|
|
// Enforce TLS 1.2 / TLS 1.3
|
|
m.tlsConfig = &tls.Config{
|
|
Certificates: []tls.Certificate{cert},
|
|
MinVersion: parseTLSVersion(cfg.MinVersion, tls.VersionTLS12),
|
|
MaxVersion: parseTLSVersion(cfg.MaxVersion, tls.VersionTLS13),
|
|
}
|
|
|
|
if cfg.CipherSuites != "" {
|
|
m.tlsConfig.CipherSuites = parseCipherSuites(cfg.CipherSuites)
|
|
} else {
|
|
// Use secure defaults
|
|
m.tlsConfig.CipherSuites = []uint16{
|
|
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
|
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
|
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
|
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
|
}
|
|
}
|
|
|
|
// Configure client authentication (mTLS)
|
|
if cfg.ClientAuth {
|
|
if cfg.ClientCAFile == "" {
|
|
return nil, fmt.Errorf("client_auth is enabled but client_ca_file is not specified")
|
|
}
|
|
caCert, err := os.ReadFile(cfg.ClientCAFile)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to read client CA file: %w", err)
|
|
}
|
|
caCertPool := x509.NewCertPool()
|
|
if !caCertPool.AppendCertsFromPEM(caCert) {
|
|
return nil, fmt.Errorf("failed to parse client CA certificate")
|
|
}
|
|
m.tlsConfig.ClientCAs = caCertPool
|
|
}
|
|
|
|
logger.Info("msg", "TLS Server Manager initialized", "component", "tls")
|
|
return m, nil
|
|
}
|
|
|
|
// GetHTTPConfig returns a TLS configuration suitable for HTTP servers.
|
|
func (m *ServerManager) GetHTTPConfig() *tls.Config {
|
|
if m == nil {
|
|
return nil
|
|
}
|
|
cfg := m.tlsConfig.Clone()
|
|
cfg.NextProtos = []string{"h2", "http/1.1"}
|
|
return cfg
|
|
}
|
|
|
|
// GetStats returns statistics about the current server TLS configuration.
|
|
func (m *ServerManager) GetStats() map[string]any {
|
|
if m == nil {
|
|
return map[string]any{"enabled": false}
|
|
}
|
|
return map[string]any{
|
|
"enabled": true,
|
|
"min_version": tlsVersionString(m.tlsConfig.MinVersion),
|
|
"max_version": tlsVersionString(m.tlsConfig.MaxVersion),
|
|
"client_auth": m.config.ClientAuth,
|
|
"cipher_suites": len(m.tlsConfig.CipherSuites),
|
|
}
|
|
} |