diff --git a/config/config.go b/config/config.go index 30a878693..c224da980 100644 --- a/config/config.go +++ b/config/config.go @@ -173,30 +173,11 @@ func (cfg *Config) GetTLSClientConfig() (*tls.Config, error) { }, nil } -// GenerateCatchAllCertificate generates a catch-all certificate. If no derived CA is defined a -// self-signed certificate will be generated. -func (cfg *Config) GenerateCatchAllCertificate() (*tls.Certificate, error) { - if cfg.Options.DeriveInternalDomainCert != nil { - sharedKey, err := cfg.Options.GetSharedKey() - if err != nil { - return nil, fmt.Errorf("failed to generate cert, invalid shared key: %w", err) - } - - ca, err := derivecert.NewCA(sharedKey) - if err != nil { - return nil, fmt.Errorf("failed to generate cert, invalid derived CA: %w", err) - } - - pem, err := ca.NewServerCert([]string{"*"}) - if err != nil { - return nil, fmt.Errorf("failed to generate cert, error creating server certificate: %w", err) - } - - cert, err := pem.TLS() - if err != nil { - return nil, fmt.Errorf("failed to generate cert, error converting generated certificate into TLS certificate: %w", err) - } - return &cert, nil +// GenerateDerivedCertificate generates a wildcard certificate from a CA +// derived from the shared secret. +func (cfg *Config) GenerateDerivedCertificate() (*tls.Certificate, error) { + if cfg.Options.DeriveInternalDomainCert == nil { + return nil, nil } sharedKey, err := cfg.Options.GetSharedKey() @@ -204,7 +185,30 @@ func (cfg *Config) GenerateCatchAllCertificate() (*tls.Certificate, error) { return nil, fmt.Errorf("failed to generate cert, invalid shared key: %w", err) } - // finally fall back to a generated, self-signed certificate + ca, err := derivecert.NewCA(sharedKey) + if err != nil { + return nil, fmt.Errorf("failed to generate cert, invalid derived CA: %w", err) + } + + pem, err := ca.NewServerCert([]string{"*"}) + if err != nil { + return nil, fmt.Errorf("failed to generate cert, error creating server certificate: %w", err) + } + + cert, err := pem.TLS() + if err != nil { + return nil, fmt.Errorf("failed to generate cert, error converting generated certificate into TLS certificate: %w", err) + } + return &cert, nil +} + +// GenerateFallbackCertificate generates a self-signed certificate derived from +// the shared secret. +func (cfg *Config) GenerateFallbackCertificate() (*tls.Certificate, error) { + sharedKey, err := cfg.Options.GetSharedKey() + if err != nil { + return nil, fmt.Errorf("failed to generate cert, invalid shared key: %w", err) + } return cryptutil.GenerateCertificate(sharedKey, "*") } diff --git a/config/envoyconfig/listeners.go b/config/envoyconfig/listeners.go index 1cbf57c9e..9f57abd66 100644 --- a/config/envoyconfig/listeners.go +++ b/config/envoyconfig/listeners.go @@ -104,12 +104,25 @@ func getAllCertificates(cfg *config.Config) ([]tls.Certificate, error) { return nil, fmt.Errorf("error collecting all certificates: %w", err) } - wc, err := cfg.GenerateCatchAllCertificate() - if err != nil { - return nil, fmt.Errorf("error getting wildcard certificate: %w", err) + if cfg.Options.DeriveInternalDomainCert != nil { + wc, err := cfg.GenerateDerivedCertificate() + if err != nil { + return nil, fmt.Errorf("error generating wildcard certificate: %w", err) + } + allCertificates = append(allCertificates, *wc) } - return append(allCertificates, *wc), nil + // Generate a fallback certificate only as a last resort, if no other + // certificates are configured. + if len(allCertificates) == 0 { + wc, err := cfg.GenerateFallbackCertificate() + if err != nil { + return nil, fmt.Errorf("error generating wildcard certificate: %w", err) + } + allCertificates = append(allCertificates, *wc) + } + + return allCertificates, nil } func (b *Builder) buildTLSSocket(ctx context.Context, cfg *config.Config, certs []tls.Certificate) (*envoy_config_core_v3.TransportSocket, error) {