crowdsec/pkg/csconfig/tls.go

88 lines
2.7 KiB
Go
Raw Normal View History

package csconfig
import (
"crypto/tls"
"crypto/x509"
"fmt"
"os"
"time"
log "github.com/sirupsen/logrus"
)
type TLSCfg struct {
CertFilePath string `yaml:"cert_file"`
KeyFilePath string `yaml:"key_file"`
ClientVerification string `yaml:"client_verification,omitempty"`
ServerName string `yaml:"server_name"`
CACertPath string `yaml:"ca_cert_path"`
AllowedAgentsOU []string `yaml:"agents_allowed_ou"`
AllowedBouncersOU []string `yaml:"bouncers_allowed_ou"`
CRLPath string `yaml:"crl_path"`
CacheExpiration *time.Duration `yaml:"cache_expiration,omitempty"`
}
func (t *TLSCfg) GetAuthType() (tls.ClientAuthType, error) {
if t.ClientVerification == "" {
// sounds like a sane default: verify client cert if given, but don't make it mandatory
return tls.VerifyClientCertIfGiven, nil
}
switch t.ClientVerification {
case "NoClientCert":
return tls.NoClientCert, nil
case "RequestClientCert":
log.Warn("RequestClientCert is insecure, please use VerifyClientCertIfGiven or RequireAndVerifyClientCert instead")
return tls.RequestClientCert, nil
case "RequireAnyClientCert":
log.Warn("RequireAnyClientCert is insecure, please use VerifyClientCertIfGiven or RequireAndVerifyClientCert instead")
return tls.RequireAnyClientCert, nil
case "VerifyClientCertIfGiven":
return tls.VerifyClientCertIfGiven, nil
case "RequireAndVerifyClientCert":
return tls.RequireAndVerifyClientCert, nil
default:
return 0, fmt.Errorf("unknown TLS client_verification value: %s", t.ClientVerification)
}
}
func (t *TLSCfg) GetTLSConfig() (*tls.Config, error) {
if t == nil {
return &tls.Config{}, nil
}
clientAuthType, err := t.GetAuthType()
if err != nil {
return nil, err
}
caCertPool, err := x509.SystemCertPool()
if err != nil {
log.Warnf("Error loading system CA certificates: %s", err)
}
if caCertPool == nil {
caCertPool = x509.NewCertPool()
}
// the > condition below is a weird way to say "if a client certificate is required"
// see https://pkg.go.dev/crypto/tls#ClientAuthType
if clientAuthType > tls.RequestClientCert && t.CACertPath != "" {
log.Infof("(tls) Client Auth Type set to %s", clientAuthType.String())
caCert, err := os.ReadFile(t.CACertPath)
if err != nil {
return nil, fmt.Errorf("while opening cert file: %w", err)
}
caCertPool.AppendCertsFromPEM(caCert)
}
return &tls.Config{
ServerName: t.ServerName, //should it be removed ?
ClientAuth: clientAuthType,
ClientCAs: caCertPool,
MinVersion: tls.VersionTLS12, // TLS versions below 1.2 are considered insecure - see https://www.rfc-editor.org/rfc/rfc7525.txt for details
}, nil
}