diff --git a/control-plane/api-gateway/binding/result.go b/control-plane/api-gateway/binding/result.go index 1953d4836c..e6c0760e7a 100644 --- a/control-plane/api-gateway/binding/result.go +++ b/control-plane/api-gateway/binding/result.go @@ -241,7 +241,11 @@ var ( // Below is where any custom generic listener validation errors should go. // We map anything under here to a custom ListenerConditionReason of Invalid on // an Accepted status type. - errListenerNoTLSPassthrough = errors.New("TLS passthrough is not supported") + errListenerNoTLSPassthrough = errors.New("TLS passthrough is not supported") + errListenerTLSCipherSuiteNotConfigurable = errors.New("tls_min_version does not allow tls_cipher_suites configuration") + errListenerUnsupportedTLSCipherSuite = errors.New("unsupported cipher suite in tls_cipher_suites") + errListenerUnsupportedTLSMaxVersion = errors.New("unsupported tls_max_version") + errListenerUnsupportedTLSMinVersion = errors.New("unsupported tls_min_version") // This custom listener validation error is used to differentiate between an errListenerPortUnavailable because of // direct port conflicts defined by the user (two listeners on the same port) vs a port conflict because we map diff --git a/control-plane/api-gateway/binding/validation.go b/control-plane/api-gateway/binding/validation.go index b0482069e4..02e6db8438 100644 --- a/control-plane/api-gateway/binding/validation.go +++ b/control-plane/api-gateway/binding/validation.go @@ -4,7 +4,6 @@ package binding import ( - "errors" "strings" corev1 "k8s.io/api/core/v1" @@ -264,14 +263,14 @@ func validateTLSOptions(options map[gwv1beta1.AnnotationKey]gwv1beta1.Annotation tlsMinVersionValue := string(options[common.TLSMinVersionAnnotationKey]) if tlsMinVersionValue != "" { if _, supported := allSupportedTLSVersions[tlsMinVersionValue]; !supported { - return errors.New("unsupported tls_min_version") + return errListenerUnsupportedTLSMinVersion } } tlsMaxVersionValue := string(options[common.TLSMaxVersionAnnotationKey]) if tlsMaxVersionValue != "" { if _, supported := allSupportedTLSVersions[tlsMaxVersionValue]; !supported { - return errors.New("unsupported tls_max_version") + return errListenerUnsupportedTLSMaxVersion } } @@ -280,14 +279,14 @@ func validateTLSOptions(options map[gwv1beta1.AnnotationKey]gwv1beta1.Annotation // If a minimum TLS version is configured, verify that it supports configuring cipher suites if tlsMinVersionValue != "" { if _, supported := allTLSVersionsWithConfigurableCipherSuites[tlsMinVersionValue]; !supported { - return errors.New("tls_min_version does not allow tls_cipher_suites configuration") + return errListenerTLSCipherSuiteNotConfigurable } } for _, tlsCipherSuiteValue := range strings.Split(tlsCipherSuitesValue, ",") { tlsCipherSuite := strings.TrimSpace(tlsCipherSuiteValue) if _, supported := allSupportedTLSCipherSuites[tlsCipherSuite]; !supported { - return errors.New("unsupported cipher suite in tls_cipher_suites") + return errListenerUnsupportedTLSCipherSuite } } } diff --git a/control-plane/api-gateway/binding/validation_test.go b/control-plane/api-gateway/binding/validation_test.go index 10cdf851c3..1f2b143387 100644 --- a/control-plane/api-gateway/binding/validation_test.go +++ b/control-plane/api-gateway/binding/validation_test.go @@ -510,6 +510,47 @@ func TestValidateTLS(t *testing.T) { expectedResolvedRefsErr: nil, expectedAcceptedErr: nil, }, + "invalid cipher suite": { + gateway: gatewayWithFinalizer(gwv1beta1.GatewaySpec{}), + tls: &gwv1beta1.GatewayTLSConfig{ + Options: map[gwv1beta1.AnnotationKey]gwv1beta1.AnnotationValue{ + common.TLSCipherSuitesAnnotationKey: "invalid", + }, + }, + certificates: nil, + expectedAcceptedErr: errListenerUnsupportedTLSCipherSuite, + }, + "cipher suite not configurable": { + gateway: gatewayWithFinalizer(gwv1beta1.GatewaySpec{}), + tls: &gwv1beta1.GatewayTLSConfig{ + Options: map[gwv1beta1.AnnotationKey]gwv1beta1.AnnotationValue{ + common.TLSMinVersionAnnotationKey: "TLSv1_3", + common.TLSCipherSuitesAnnotationKey: "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + }, + }, + certificates: nil, + expectedAcceptedErr: errListenerTLSCipherSuiteNotConfigurable, + }, + "invalid max version": { + gateway: gatewayWithFinalizer(gwv1beta1.GatewaySpec{}), + tls: &gwv1beta1.GatewayTLSConfig{ + Options: map[gwv1beta1.AnnotationKey]gwv1beta1.AnnotationValue{ + common.TLSMaxVersionAnnotationKey: "invalid", + }, + }, + certificates: nil, + expectedAcceptedErr: errListenerUnsupportedTLSMaxVersion, + }, + "invalid min version": { + gateway: gatewayWithFinalizer(gwv1beta1.GatewaySpec{}), + tls: &gwv1beta1.GatewayTLSConfig{ + Options: map[gwv1beta1.AnnotationKey]gwv1beta1.AnnotationValue{ + common.TLSMinVersionAnnotationKey: "invalid", + }, + }, + certificates: nil, + expectedAcceptedErr: errListenerUnsupportedTLSMinVersion, + }, } { t.Run(name, func(t *testing.T) { resources := common.NewResourceMap(common.ResourceTranslator{}, NewReferenceValidator(tt.grants), logrtest.NewTestLogger(t))