@@ -18,8 +18,8 @@ type GRPCServerOptions struct {
1818 TLSCertFile string `json:"tls_cert_file" yaml:"tls_cert_file"`
1919 TLSKeyFile string `json:"tls_key_file" yaml:"tls_key_file"`
2020 ClientCAFile string `json:"client_ca_file" yaml:"client_ca_file"`
21- TLSMinVersion uint16 `json:"tls_min_version" yaml:"tls_min_version"`
22- TLSMaxVersion uint16 `json:"tls_max_version" yaml:"tls_max_version"`
21+ TLSMinVersion string `json:"tls_min_version" yaml:"tls_min_version"`
22+ TLSMaxVersion string `json:"tls_max_version" yaml:"tls_max_version"`
2323 CipherSuites string `json:"cipher_suites" yaml:"cipher_suites"`
2424 ServerBindPort string `json:"server_bind_port" yaml:"server_bind_port"`
2525 MaxConcurrentStreams uint32 `json:"max_concurrent_streams" yaml:"max_concurrent_streams"`
@@ -35,7 +35,9 @@ type GRPCServerOptions struct {
3535 PermitPingWithoutStream bool `json:"permit_ping_without_stream" yaml:"permit_ping_without_stream"`
3636 CertWatchInterval time.Duration `json:"cert_watch_interval" yaml:"cert_watch_interval"`
3737
38- // cipherSuiteIDs holds the parsed uint16 IDs from CipherSuites, populated by Validate().
38+ // Parsed TLS settings, populated by Validate().
39+ tlsMinVersion uint16
40+ tlsMaxVersion uint16
3941 cipherSuiteIDs []uint16
4042}
4143
@@ -67,8 +69,8 @@ func NewGRPCServerOptions() *GRPCServerOptions {
6769 ClientCAFile : "/var/run/secrets/hub/grpc/ca/ca-bundle.crt" ,
6870 TLSCertFile : "/var/run/secrets/hub/grpc/serving-cert/tls.crt" ,
6971 TLSKeyFile : "/var/run/secrets/hub/grpc/serving-cert/tls.key" ,
70- TLSMinVersion : tls . VersionTLS12 ,
71- TLSMaxVersion : tls . VersionTLS13 ,
72+ TLSMinVersion : " VersionTLS12" ,
73+ TLSMaxVersion : " VersionTLS13" ,
7274 ServerBindPort : "8090" ,
7375 MaxConcurrentStreams : math .MaxUint32 ,
7476 MaxReceiveMessageSize : 1024 * 1024 * 4 ,
@@ -105,13 +107,22 @@ func (o *GRPCServerOptions) AddFlags(flags *pflag.FlagSet) {
105107
106108// Validate checks option ranges and cross-field constraints.
107109func (o * GRPCServerOptions ) Validate () error {
108- // Enforce sane floor for TLS for security posture.
109- if o .TLSMinVersion < tls .VersionTLS12 {
110- return fmt .Errorf ("tls_min_version (%d) is lower than TLS 1.2 (771); minimum supported is TLS 1.2" , o .TLSMinVersion )
110+ minVer , err := pkgtls .ParseTLSVersion (o .TLSMinVersion )
111+ if err != nil {
112+ return fmt .Errorf ("invalid tls_min_version %q: %w" , o .TLSMinVersion , err )
113+ }
114+ maxVer , err := pkgtls .ParseTLSVersion (o .TLSMaxVersion )
115+ if err != nil {
116+ return fmt .Errorf ("invalid tls_max_version %q: %w" , o .TLSMaxVersion , err )
117+ }
118+ if minVer < tls .VersionTLS12 {
119+ return fmt .Errorf ("tls_min_version %q is lower than TLS 1.2; minimum supported is TLS 1.2" , o .TLSMinVersion )
111120 }
112- if o . TLSMinVersion > o . TLSMaxVersion {
113- return fmt .Errorf ("tls_min_version (%d) must be <= tls_max_version (%d) " , o .TLSMinVersion , o .TLSMaxVersion )
121+ if minVer > maxVer {
122+ return fmt .Errorf ("tls_min_version %q must be <= tls_max_version %q " , o .TLSMinVersion , o .TLSMaxVersion )
114123 }
124+ o .tlsMinVersion = minVer
125+ o .tlsMaxVersion = maxVer
115126 // Validate certificate watch interval to prevent time.NewTicker panic
116127 if o .CertWatchInterval <= 30 * time .Second {
117128 return fmt .Errorf ("cert_watch_interval (%v) must be greater than 30 seconds" , o .CertWatchInterval )
@@ -125,11 +136,7 @@ func (o *GRPCServerOptions) Validate() error {
125136// Called after LoadGRPCServerOptions so flags take precedence over the config file.
126137func (o * GRPCServerOptions ) ApplyTLSFlags (minVersion , cipherSuites string ) error {
127138 if minVersion != "" {
128- ver , err := pkgtls .ParseTLSVersion (minVersion )
129- if err != nil {
130- return fmt .Errorf ("invalid --tls-min-version: %w" , err )
131- }
132- o .TLSMinVersion = ver
139+ o .TLSMinVersion = minVersion
133140 }
134141 if cipherSuites != "" {
135142 o .CipherSuites = cipherSuites
0 commit comments