From 3df707b0c1f52f732270d16bddc8b5446ada32cc Mon Sep 17 00:00:00 2001 From: kruskal <99559985+kruskall@users.noreply.github.com> Date: Thu, 6 Mar 2025 05:23:28 +0100 Subject: [PATCH 1/3] feat(fips): do not allow scram sasl mechanism in fips mode scram is using custom implementation of pbkdf2 which is not allowed in fips mode --- libbeat/common/kafka/sasl.go | 17 +-------- libbeat/common/kafka/sasl_fips.go | 39 ++++++++++++++++++++ libbeat/common/kafka/sasl_fips_test.go | 36 ++++++++++++++++++ libbeat/common/kafka/sasl_nofips.go | 47 ++++++++++++++++++++++++ libbeat/common/kafka/sasl_nofips_test.go | 36 ++++++++++++++++++ libbeat/common/kafka/scram.go | 2 + 6 files changed, 162 insertions(+), 15 deletions(-) create mode 100644 libbeat/common/kafka/sasl_fips.go create mode 100644 libbeat/common/kafka/sasl_fips_test.go create mode 100644 libbeat/common/kafka/sasl_nofips.go create mode 100644 libbeat/common/kafka/sasl_nofips_test.go diff --git a/libbeat/common/kafka/sasl.go b/libbeat/common/kafka/sasl.go index ca9df078ebcd..2f0d2ea79e43 100644 --- a/libbeat/common/kafka/sasl.go +++ b/libbeat/common/kafka/sasl.go @@ -44,26 +44,13 @@ func (c *SaslConfig) ConfigureSarama(config *sarama.Config) { case saslTypeSCRAMSHA256: config.Net.SASL.Handshake = true config.Net.SASL.Mechanism = sarama.SASLMechanism(sarama.SASLTypeSCRAMSHA256) - config.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { - return &XDGSCRAMClient{HashGeneratorFcn: SHA256} - } + config.Net.SASL.SCRAMClientGeneratorFunc = scramClient(saslTypeSCRAMSHA256) case saslTypeSCRAMSHA512: config.Net.SASL.Handshake = true config.Net.SASL.Mechanism = sarama.SASLMechanism(sarama.SASLTypeSCRAMSHA512) - config.Net.SASL.SCRAMClientGeneratorFunc = func() sarama.SCRAMClient { - return &XDGSCRAMClient{HashGeneratorFcn: SHA512} - } + config.Net.SASL.SCRAMClientGeneratorFunc = scramClient(saslTypeSCRAMSHA512) default: // This should never happen because `SaslMechanism` is checked on `Validate()`, keeping a panic to detect it earlier if it happens. panic(fmt.Sprintf("not valid SASL mechanism '%v', only supported with PLAIN|SCRAM-SHA-512|SCRAM-SHA-256", c.SaslMechanism)) } } - -func (c *SaslConfig) Validate() error { - switch strings.ToUpper(c.SaslMechanism) { // try not to force users to use all upper case - case "", saslTypePlaintext, saslTypeSCRAMSHA256, saslTypeSCRAMSHA512: - default: - return fmt.Errorf("not valid SASL mechanism '%v', only supported with PLAIN|SCRAM-SHA-512|SCRAM-SHA-256", c.SaslMechanism) - } - return nil -} diff --git a/libbeat/common/kafka/sasl_fips.go b/libbeat/common/kafka/sasl_fips.go new file mode 100644 index 000000000000..6347cc32d68c --- /dev/null +++ b/libbeat/common/kafka/sasl_fips.go @@ -0,0 +1,39 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//go:build requirefips + +package kafka + +import ( + "fmt" + "strings" +) + +func (c *SaslConfig) Validate() error { + switch strings.ToUpper(c.SaslMechanism) { // try not to force users to use all upper case + case "", saslTypePlaintext: + default: + return fmt.Errorf("not valid SASL mechanism '%v', only supported with PLAIN", c.SaslMechanism) + } + return nil +} + +func scramClient(mechanism string) func() sarama.SCRAMClient { + // This should never happen because `SaslMechanism` is checked on `Validate()`, keeping a panic to detect it earlier if it happens. + panic("scram sasl auth not supported in fips mode") +} diff --git a/libbeat/common/kafka/sasl_fips_test.go b/libbeat/common/kafka/sasl_fips_test.go new file mode 100644 index 000000000000..a3fc1be53a39 --- /dev/null +++ b/libbeat/common/kafka/sasl_fips_test.go @@ -0,0 +1,36 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//go:build requirefips + +package kafka + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestValidate(t *testing.T) { + cfg := SaslConfig{ + SaslMechanism: saslTypeSCRAMSHA512, + } + require.Error(t, cfg.Validate()) + + cfg.SaslMechanism = saslTypeSCRAMSHA256 + require.Error(t, cfg.Validate()) +} diff --git a/libbeat/common/kafka/sasl_nofips.go b/libbeat/common/kafka/sasl_nofips.go new file mode 100644 index 000000000000..5a3f927571f5 --- /dev/null +++ b/libbeat/common/kafka/sasl_nofips.go @@ -0,0 +1,47 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//go:build !requirefips + +package kafka + +import ( + "fmt" + "strings" + + "github.com/elastic/sarama" +) + +func (c *SaslConfig) Validate() error { + switch strings.ToUpper(c.SaslMechanism) { // try not to force users to use all upper case + case "", saslTypePlaintext, saslTypeSCRAMSHA256, saslTypeSCRAMSHA512: + default: + return fmt.Errorf("not valid SASL mechanism '%v', only supported with PLAIN|SCRAM-SHA-512|SCRAM-SHA-256", c.SaslMechanism) + } + return nil +} + +func scramClient(mechanism string) func() sarama.SCRAMClient { + if mechanism == saslTypeSCRAMSHA512 { + return func() sarama.SCRAMClient { + return &XDGSCRAMClient{HashGeneratorFcn: SHA512} + } + } + return func() sarama.SCRAMClient { + return &XDGSCRAMClient{HashGeneratorFcn: SHA256} + } +} diff --git a/libbeat/common/kafka/sasl_nofips_test.go b/libbeat/common/kafka/sasl_nofips_test.go new file mode 100644 index 000000000000..507054789868 --- /dev/null +++ b/libbeat/common/kafka/sasl_nofips_test.go @@ -0,0 +1,36 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +//go:build !requirefips + +package kafka + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestValidate(t *testing.T) { + cfg := SaslConfig{ + SaslMechanism: saslTypeSCRAMSHA512, + } + require.NoError(t, cfg.Validate()) + + cfg.SaslMechanism = saslTypeSCRAMSHA256 + require.NoError(t, cfg.Validate()) +} diff --git a/libbeat/common/kafka/scram.go b/libbeat/common/kafka/scram.go index e87ed11f756e..af85f2df9831 100644 --- a/libbeat/common/kafka/scram.go +++ b/libbeat/common/kafka/scram.go @@ -15,6 +15,8 @@ // specific language governing permissions and limitations // under the License. +//go:build !requirefips + // https://github.com/Shopify/sarama/blob/master/examples/sasl_scram_client/scram_client.go package kafka From 197ba02c4ff590289cec18f5e4cc8da724f91c11 Mon Sep 17 00:00:00 2001 From: kruskall <99559985+kruskall@users.noreply.github.com> Date: Thu, 6 Mar 2025 05:37:14 +0100 Subject: [PATCH 2/3] Update sasl_fips.go From a358a169b7392101a6b7e779b3ac25a02ffe22ef Mon Sep 17 00:00:00 2001 From: kruskall <99559985+kruskall@users.noreply.github.com> Date: Thu, 6 Mar 2025 06:44:37 +0100 Subject: [PATCH 3/3] Update sasl_fips.go --- libbeat/common/kafka/sasl_fips.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libbeat/common/kafka/sasl_fips.go b/libbeat/common/kafka/sasl_fips.go index 6347cc32d68c..414854cb9e33 100644 --- a/libbeat/common/kafka/sasl_fips.go +++ b/libbeat/common/kafka/sasl_fips.go @@ -22,6 +22,8 @@ package kafka import ( "fmt" "strings" + + "github.com/elastic/sarama" ) func (c *SaslConfig) Validate() error {