diff --git a/.buildkite/libbeat/pipeline.libbeat.yml b/.buildkite/libbeat/pipeline.libbeat.yml index 1e85705b1e37..06d54c04c084 100644 --- a/.buildkite/libbeat/pipeline.libbeat.yml +++ b/.buildkite/libbeat/pipeline.libbeat.yml @@ -16,8 +16,6 @@ env: IMAGE_WIN_2016: "platform-ingest-beats-windows-2016-1781496166" IMAGE_WIN_2019: "platform-ingest-beats-windows-2019-1781496166" IMAGE_WIN_2022: "platform-ingest-beats-windows-2022-1781496166" - IMAGE_UBUNTU_X86_64_FIPS: "platform-ingest-beats-ubuntu-2204-fips-1781496166" - IMAGE_BEATS_WITH_HOOKS_LATEST: "docker.elastic.co/ci-agent-images/platform-ingest/buildkite-agent-beats-ci-with-hooks:latest" #Deps @@ -97,7 +95,6 @@ steps: context: "libbeat: Ubuntu x86_64 Unit Tests" - label: ":ubuntu: Libbeat: Ubuntu x86_64 Go Unit Tests with fips provider and requirefips build tag" - skip: "https://github.com/elastic/beats/issues/50269: ssh keys not FIPS" key: "mandatory-linux-unit-test-fips-tag" command: | cd libbeat @@ -106,13 +103,11 @@ steps: automatic: - limit: 1 agents: - provider: "aws" - image: "${IMAGE_UBUNTU_X86_64_FIPS}" - instanceType: "m5.xlarge" + provider: "gcp" + image: "${IMAGE_UBUNTU_X86_64}" + machineType: "${GCP_DEFAULT_MACHINE_TYPE}" env: FIPS: "true" - GOEXPERIMENT: "systemcrypto" - ASDF_PYTHON_VERSION: "3.9.13" artifact_paths: - "libbeat/build/*.xml" - "libbeat/build/*.json" diff --git a/.buildkite/scripts/custom_fips_ech_test.sh b/.buildkite/scripts/custom_fips_ech_test.sh index 5264939a2dad..7b9bfa968791 100755 --- a/.buildkite/scripts/custom_fips_ech_test.sh +++ b/.buildkite/scripts/custom_fips_ech_test.sh @@ -14,5 +14,5 @@ ech_up $STACK_VERSION echo "~~~ Running custom FIPS ECH tests" pushd $BEAT_PATH -GOEXPERIMENT=systemcrypto SNAPSHOT=true FIPS=true mage build fipsECHTest +SNAPSHOT=true FIPS=true mage build fipsECHTest popd diff --git a/.buildkite/x-pack/pipeline.xpack.filebeat.yml b/.buildkite/x-pack/pipeline.xpack.filebeat.yml index e04447e0380e..d290dc965dd2 100644 --- a/.buildkite/x-pack/pipeline.xpack.filebeat.yml +++ b/.buildkite/x-pack/pipeline.xpack.filebeat.yml @@ -10,7 +10,6 @@ env: GCP_WIN_MACHINE_TYPE: "n2-standard-8" IMAGE_UBUNTU_X86_64: "platform-ingest-beats-ubuntu-2204-1781496166" - IMAGE_UBUNTU_X86_64_FIPS: "platform-ingest-beats-ubuntu-2204-fips-1781496166" IMAGE_WIN_10: "platform-ingest-beats-windows-10-pro" IMAGE_WIN_11: "platform-ingest-beats-windows-11-pro" IMAGE_WIN_10_VERSION: "1.0.1781496166" @@ -221,10 +220,8 @@ steps: context: "x-pack/filebeat: Go fips140=only Integration Tests" - label: ":ubuntu: x-pack/filebeat: FIPS ECH Integration Tests" - skip: "https://github.com/elastic/beats/issues/50269: ssh keys not FIPS" env: ASDF_TERRAFORM_VERSION: "1.9.3" - ASDF_PYTHON_VERSION: "3.9.13" # Not needed by ECH tests, but needed by VM # We are temporarily using the Production CFT environment instead of the Staging GovCloud # one. This is being done until issues with creating deployments in Staging GovCloud are # fixed. Once this happens, uncomment the lines below and delete the gcp-us-west2 line. @@ -238,9 +235,9 @@ steps: automatic: - limit: 1 agents: - provider: "aws" - image: "${IMAGE_UBUNTU_X86_64_FIPS}" - instanceType: "m5.xlarge" + provider: "gcp" + image: "${IMAGE_UBUNTU_X86_64}" + machineType: "${GCP_DEFAULT_MACHINE_TYPE}" artifact_paths: - "x-pack/filebeat/build/*.xml" - "x-pack/filebeat/build/*.json" diff --git a/.buildkite/x-pack/pipeline.xpack.metricbeat.yml b/.buildkite/x-pack/pipeline.xpack.metricbeat.yml index 09fccc934871..c578936d79e4 100644 --- a/.buildkite/x-pack/pipeline.xpack.metricbeat.yml +++ b/.buildkite/x-pack/pipeline.xpack.metricbeat.yml @@ -10,7 +10,6 @@ env: GCP_WIN_MACHINE_TYPE: "n2-standard-8" IMAGE_UBUNTU_X86_64: "platform-ingest-beats-ubuntu-2204-1781496166" - IMAGE_UBUNTU_X86_64_FIPS: "platform-ingest-beats-ubuntu-2204-fips-1781496166" IMAGE_WIN_10: "platform-ingest-beats-windows-10-pro" IMAGE_WIN_11: "platform-ingest-beats-windows-11-pro" IMAGE_WIN_10_VERSION: "1.0.1781496166" @@ -260,10 +259,8 @@ steps: context: "x-pack/metricbeat: Go fips140=only Integration Tests (Module)" - label: ":ubuntu: x-pack/metricbeat: FIPS ECH Integration Tests" - skip: "https://github.com/elastic/beats/issues/50269: ssh keys not FIPS" env: ASDF_TERRAFORM_VERSION: "1.9.3" - ASDF_PYTHON_VERSION: "3.9.13" # Not needed by ECH tests, but needed by VM # We are temporarily using the Production CFT environment instead of the Staging GovCloud # one. This is being done until issues with creating deployments in Staging GovCloud are # fixed. Once this happens, uncomment the lines below and delete the gcp-us-west2 line. @@ -277,9 +274,9 @@ steps: automatic: - limit: 1 agents: - provider: "aws" - image: "${IMAGE_UBUNTU_X86_64_FIPS}" - instanceType: "m5.xlarge" + provider: "gcp" + image: "${IMAGE_UBUNTU_X86_64}" + machineType: "${GCP_DEFAULT_MACHINE_TYPE}" artifact_paths: - "x-pack/metricbeat/build/*.xml" - "x-pack/metricbeat/build/*.json" diff --git a/NOTICE.txt b/NOTICE.txt index 55b8002360ef..ad2b4851e820 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -10761,11 +10761,11 @@ SOFTWARE -------------------------------------------------------------------------------- Dependency : github.com/elastic/elastic-agent-libs -Version: v0.44.0 +Version: v0.45.0 Licence type (autodetected): Apache-2.0 -------------------------------------------------------------------------------- -Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-libs@v0.44.0/LICENSE: +Contents of probable licence file $GOMODCACHE/github.com/elastic/elastic-agent-libs@v0.45.0/LICENSE: Apache License Version 2.0, January 2004 diff --git a/changelog/fragments/1781782084-use-native-go-for-linux-fips-builds.yaml b/changelog/fragments/1781782084-use-native-go-for-linux-fips-builds.yaml new file mode 100644 index 000000000000..75cbbfc9fe61 --- /dev/null +++ b/changelog/fragments/1781782084-use-native-go-for-linux-fips-builds.yaml @@ -0,0 +1,45 @@ +# REQUIRED +# Kind can be one of: +# - breaking-change: a change to previously-documented behavior +# - deprecation: functionality that is being removed in a later release +# - bug-fix: fixes a problem in a previous version +# - enhancement: extends functionality but does not break or fix existing behavior +# - feature: new functionality +# - known-issue: problems that we are aware of in a given version +# - security: impacts on the security of a product or a user’s deployment. +# - upgrade: important information for someone upgrading from a prior version +# - other: does not fit into any of the other categories +kind: enhancement + +# REQUIRED for all kinds +# Change summary; a 80ish characters long description of the change. +summary: Use native Go for Linux FIPS builds + +# REQUIRED for breaking-change, deprecation, known-issue +# Long description; in case the summary is not enough to describe the change +# this field accommodate a description without length limits. +# description: + +# REQUIRED for breaking-change, deprecation, known-issue +# impact: + +# REQUIRED for breaking-change, deprecation, known-issue +# action: + +# REQUIRED for all kinds +# Affected component; usually one of "elastic-agent", "fleet-server", "filebeat", "metricbeat", "auditbeat", "all", etc. +component: all + +# AUTOMATED +# OPTIONAL to manually add other PR URLs +# PR URL: A link the PR that added the changeset. +# If not present is automatically filled by the tooling finding the PR where this changelog fragment has been added. +# NOTE: the tooling supports backports, so it's able to fill the original PR number instead of the backport PR number. +# Please provide it if you are adding a fragment for a different PR. +# pr: https://github.com/owner/repo/1234 + +# AUTOMATED +# OPTIONAL to manually add other issue URLs +# Issue URL; optional; the GitHub issue related to this changeset (either closes or is part of). +# If not present is automatically filled by the tooling with the issue linked to the PR number. +# issue: https://github.com/owner/repo/1234 diff --git a/dev-tools/mage/build.go b/dev-tools/mage/build.go index c6c89957387a..0d5bd95ae15d 100644 --- a/dev-tools/mage/build.go +++ b/dev-tools/mage/build.go @@ -29,6 +29,8 @@ import ( "github.com/josephspurrier/goversioninfo" "github.com/magefile/mage/sh" + "golang.org/x/text/cases" + "golang.org/x/text/language" ) // BuildArgs are the arguments used for the "build" target and they define how @@ -113,7 +115,6 @@ func DefaultBuildArgs() BuildArgs { for _, tag := range FIPSConfig.Compile.Tags { args.ExtraFlags = append(args.ExtraFlags, "-tags="+tag) } - args.CGO = args.CGO || FIPSConfig.Compile.CGO for varName, value := range FIPSConfig.Compile.Env { args.Env[varName] = value } @@ -168,8 +169,8 @@ func DefaultGolangCrossBuildArgs() BuildArgs { // environment. func GolangCrossBuild(params BuildArgs) error { if os.Getenv("GOLANG_CROSSBUILD") != "1" { - return errors.New("Use the crossBuild target. golangCrossBuild can " + - "only be executed within the golang-crossbuild docker environment.") + return errors.New("use the crossBuild target; golangCrossBuild can " + + "only be executed within the golang-crossbuild docker environment") } mountPoint, err := ElasticBeatsDir() @@ -313,7 +314,7 @@ func MakeWindowsSysoFile() (string, error) { }, StringFileInfo: goversioninfo.StringFileInfo{ CompanyName: BeatVendor, - ProductName: strings.Title(BeatName), + ProductName: cases.Title(language.English).String(BeatName), ProductVersion: version, FileVersion: version, FileDescription: BeatDescription, diff --git a/dev-tools/mage/crossbuild.go b/dev-tools/mage/crossbuild.go index 575d1f35d16e..4a6e153ee1d5 100644 --- a/dev-tools/mage/crossbuild.go +++ b/dev-tools/mage/crossbuild.go @@ -193,6 +193,15 @@ func CrossBuild(options ...CrossBuildOption) error { // Make sure the module dependencies are downloaded on the host, // as they will be mounted into the container read-only. mg.Deps(func() error { return gotool.Mod.Download() }) + if FIPSBuild { + // GOFIPS140=v1.0.0 unpacks golang.org/fips140 from GOROOT/lib/fips140 + // into the module cache on first use. Pre-populate it on the host (as + // the host user) before the container mounts the cache read-only. + // Any go command triggers fips140.Init(), so list -m is sufficient. + mg.Deps(func() error { + return sh.RunWith(FIPSConfig.Compile.Env, "go", "list", "-m") + }) + } } // Build the magefile for Linux, so we can run it inside the container. @@ -278,9 +287,6 @@ func CrossBuildImage(platform string) (string, error) { if err != nil { return "", err } - if FIPSBuild { - tagSuffix += "-fips" - } return BeatsCrossBuildImage + ":" + goVersion + "-" + tagSuffix, nil } @@ -584,7 +590,7 @@ func chownPaths(uid, gid int, path string) error { return nil } - if err := os.Chown(name, uid, gid); err != nil { + if err := os.Chown(name, uid, gid); err != nil { //nolint:gosec // paths are controlled build artifacts inside a Docker container, not user input return fmt.Errorf("failed to chown path=%v: %w", name, err) } numFixed++ diff --git a/dev-tools/mage/fips-settings.yaml b/dev-tools/mage/fips-settings.yaml index 260b06c5090f..1051af713a30 100644 --- a/dev-tools/mage/fips-settings.yaml +++ b/dev-tools/mage/fips-settings.yaml @@ -5,10 +5,11 @@ beats: - metricbeat - heartbeat compile: - cgo: true env: - GOEXPERIMENT: systemcrypto - MS_GOTOOLCHAIN_TELEMETRY_ENABLED: "0" + # See https://go.dev/doc/security/fips140#go-cryptographic-module-v100 + # CMVP Certificate #5247: https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/5247 + # CAVP Certificate A6650: https://csrc.nist.gov/projects/cryptographic-algorithm-validation-program/details?product=19371 + GOFIPS140: v1.0.0 tags: - requirefips platforms: diff --git a/dev-tools/mage/gotest.go b/dev-tools/mage/gotest.go index a0ba2d66b349..96b4ffb40c63 100644 --- a/dev-tools/mage/gotest.go +++ b/dev-tools/mage/gotest.go @@ -69,7 +69,7 @@ func makeGoTestArgs(name string) GoTestArgs { TestName: name, Race: RaceDetector, Packages: []string{"./..."}, - Env: make(map[string]string), + Env: fipsTestEnv(), OutputFile: fileName + ".out", JUnitReportFile: fileName + ".xml", Tags: testTagsFromEnv(), @@ -89,6 +89,7 @@ func makeGoTestArgsForPackage(name, pkg string) GoTestArgs { TestName: fmt.Sprintf("%s-%s", name, pkg), Race: RaceDetector, Packages: []string{fmt.Sprintf("./module/%s", pkg)}, + Env: fipsTestEnv(), OutputFile: fileName + ".out", JUnitReportFile: fileName + ".xml", Tags: testTagsFromEnv(), @@ -141,6 +142,18 @@ func testTagsFromEnv() []string { return tags } +// fipsTestEnv returns the environment variables required to compile and run FIPS tests. +func fipsTestEnv() map[string]string { + env := make(map[string]string, len(FIPSConfig.Compile.Env)) + if !FIPSBuild { + return env + } + for k, v := range FIPSConfig.Compile.Env { + env[k] = v + } + return env +} + // DefaultGoTestUnitArgs returns a default set of arguments for running // all unit tests. We tag unit test files with '!integration'. func DefaultGoTestUnitArgs() GoTestArgs { return makeGoTestArgs("Unit") } @@ -395,6 +408,7 @@ func GoTest(ctx context.Context, params GoTestArgs) error { if raceAmd64 || raceArm64 { testArgs = append(testArgs, "-race") } else { + //nolint:gosec // G706: DEV_OS/DEV_ARCH are trusted build-time env vars, not untrusted input log.Printf("Warning: skipping -race flag for unsupported platform %s/%s\n", devOS, devArch) } } diff --git a/dev-tools/mage/settings.go b/dev-tools/mage/settings.go index 4c243314497a..dc198372c13d 100644 --- a/dev-tools/mage/settings.go +++ b/dev-tools/mage/settings.go @@ -91,7 +91,6 @@ var ( FIPSConfig struct { Beats []string `yaml:"beats"` Compile struct { - CGO bool `yaml:"cgo"` Env map[string]string `yaml:"env"` Tags []string `yaml:"tags"` Platforms []string `yaml:"platforms"` diff --git a/dev-tools/packaging/package_test.go b/dev-tools/packaging/package_test.go index 3d64b00cb179..c0bbfe4f1ee9 100644 --- a/dev-tools/packaging/package_test.go +++ b/dev-tools/packaging/package_test.go @@ -28,7 +28,6 @@ import ( "compress/gzip" "context" "debug/buildinfo" - "debug/elf" "errors" "flag" "fmt" @@ -43,7 +42,6 @@ import ( "github.com/blakesmith/ar" rpm "github.com/cavaliergopher/rpm" "github.com/moby/moby/api/types/container" - "github.com/moby/moby/api/types/strslice" "github.com/moby/moby/client" "github.com/stretchr/testify/require" @@ -616,7 +614,7 @@ func checkDockerImageRun(t *testing.T, p *packageFile, imagePath, imageRef strin } } - var caps strslice.StrSlice + var caps []string if strings.Contains(imageID, "packetbeat") { caps = append(caps, "NET_ADMIN") } @@ -903,41 +901,29 @@ func checkFIPS(t *testing.T, beatName, path string) { require.NoError(t, err) foundTags := false - foundExperiment := false + foundFIPS := false + foundFIPSDefault := false for _, setting := range info.Settings { switch setting.Key { case "-tags": foundTags = true require.Contains(t, setting.Value, "requirefips") continue - case "GOEXPERIMENT": - foundExperiment = true - require.Contains(t, setting.Value, "systemcrypto") + case "GOFIPS140": + foundFIPS = true + require.True(t, strings.HasPrefix(setting.Value, "v1.0.0"), "GOFIPS140 must reference the certified module version, got %q", setting.Value) + continue + case "DefaultGODEBUG": + if strings.Contains(setting.Value, "fips140=on") { + foundFIPSDefault = true + } continue } } require.True(t, foundTags, "Did not find -tags within binary version information") - require.True(t, foundExperiment, "Did not find GOEXPERIMENT within binary version information") - - // TODO only elf is supported at the moment, in the future we will need to use macho (darwin) and pe (windows) - f, err := elf.Open(binaryPath) - require.NoError(t, err, "unable to open ELF file") - - symbols, err := f.Symbols() - if err != nil { - t.Logf("no symbols present in %q: %v", binaryPath, err) - return - } - - hasOpenSSL := false - for _, symbol := range symbols { - if strings.Contains(symbol.Name, "OpenSSL_version") { - hasOpenSSL = true - break - } - } - require.True(t, hasOpenSSL, "unable to find OpenSSL_version symbol") + require.True(t, foundFIPS, "Did not find GOFIPS140 within binary version information") + require.True(t, foundFIPSDefault, "Did not find fips140=on in DefaultGODEBUG — binary will not enforce FIPS mode at runtime (check GOFIPS140 env at build time)") } // inspector is a file contents inspector. It vets the contents of the file diff --git a/go.mod b/go.mod index 6679db8bc9bb..396902fe2feb 100644 --- a/go.mod +++ b/go.mod @@ -171,7 +171,7 @@ require ( github.com/elastic/bayeux v1.0.5 github.com/elastic/ebpfevents v0.9.0 github.com/elastic/elastic-agent-autodiscover v0.10.3-0.20260423154939-e990715f9426 - github.com/elastic/elastic-agent-libs v0.44.0 + github.com/elastic/elastic-agent-libs v0.45.0 github.com/elastic/elastic-agent-system-metrics v0.14.4 github.com/elastic/go-elasticsearch/v8 v8.19.0 github.com/elastic/go-freelru v0.16.0 diff --git a/go.sum b/go.sum index 43a24f86e49b..bb5edf850844 100644 --- a/go.sum +++ b/go.sum @@ -379,8 +379,8 @@ github.com/elastic/elastic-agent-autodiscover v0.10.3-0.20260423154939-e990715f9 github.com/elastic/elastic-agent-autodiscover v0.10.3-0.20260423154939-e990715f9426/go.mod h1:HyjdiEVP/A7iMN0jeac2EoUohpHKAZIFRDQsvPDg2Dw= github.com/elastic/elastic-agent-client/v7 v7.18.1 h1:WnM53JjaukeysrAuiTyrhDPmFxJG07ZAByc2TrkcKcs= github.com/elastic/elastic-agent-client/v7 v7.18.1/go.mod h1:uDpSGZ+YCKgqgtkwCA0qjwX0gU/wmixDsVbPjY3GkPs= -github.com/elastic/elastic-agent-libs v0.44.0 h1:dONaZsY5G0rVGULP+j5xKyT51rK7nsBNEGywIXcCrg4= -github.com/elastic/elastic-agent-libs v0.44.0/go.mod h1:axkpqDCCzAky6G4D/cklgtZQa3jTNGAMVHVkU0u6YbU= +github.com/elastic/elastic-agent-libs v0.45.0 h1:ioCrNcd03tJVxrnAdZ19MCmea1SgOO+QeFtt+KvcJC0= +github.com/elastic/elastic-agent-libs v0.45.0/go.mod h1:axkpqDCCzAky6G4D/cklgtZQa3jTNGAMVHVkU0u6YbU= github.com/elastic/elastic-agent-system-metrics v0.14.4 h1:XGGepNVOxhtfJmanQsgqCAZESIJtyDIFOKErOaVzFEw= github.com/elastic/elastic-agent-system-metrics v0.14.4/go.mod h1:NyNMrdqMfznb/Zy8EmIAHlJpX6HuRlNW+bBL9UN7WQY= github.com/elastic/elastic-transport-go/v8 v8.8.0 h1:7k1Ua+qluFr6p1jfJjGDl97ssJS/P7cHNInzfxgBQAo= diff --git a/libbeat/esleg/eslegclient/connection_test.go b/libbeat/esleg/eslegclient/connection_test.go index d08ff412ff60..7788a0df63d3 100644 --- a/libbeat/esleg/eslegclient/connection_test.go +++ b/libbeat/esleg/eslegclient/connection_test.go @@ -240,45 +240,47 @@ func BenchmarkExecHTTPRequest(b *testing.B) { } } -// TestConnectionTLS tries to connect to a test HTTPS server (pretending -// to be an Elasticsearch cluster), that deliberately presents TLS options -// that are not FIPS-compliant. -// - If the test is running with a FIPS-capable build, the client, being FIPS- -// capable, should fail the TLS handshake. Concretely, the conn.Connect() method -// should return an error. -// - If the test is not running with a FIPS-capable build, the client should -// complete the TLS handshake successfully. Concretely, the conn.Connect() method -// should not return an error. +// TestConnectionTLS connects to a test HTTPS server that presents a 1024-bit +// RSA certificate, which is below the FIPS 140-3 minimum of 2048 bits. +// In a FIPS build the handshake must fail; in a non-FIPS build it must succeed. +// Both "strict" (verifies the full certificate chain) and "none" (skips chain +// building and inspects only the certificates the peer presents) are covered, +// since the FIPS key-type restriction must hold on either path. func TestConnectionTLS(t *testing.T) { - server := startTLSServer(t) - defer server.Close() + for _, verificationMode := range []string{"strict", "none"} { + t.Run(verificationMode, func(t *testing.T) { + server := startTLSServer(t) + defer server.Close() - transportSettings := ` + transportSettings := ` ssl: enabled: true + verification_mode: ` + verificationMode + ` ` - var transport httpcommon.HTTPTransportSettings - err := transport.Unpack(cfg.MustNewConfigFrom(transportSettings)) - require.NoError(t, err) + var transport httpcommon.HTTPTransportSettings + err := transport.Unpack(cfg.MustNewConfigFrom(transportSettings)) + require.NoError(t, err) - transport.TLS.CAs = []string{string(caCertPEM)} + transport.TLS.CAs = []string{string(caCertPEM)} - log := logptest.NewTestingLogger(t, "TestConnectionTLS") - conn, err := NewConnection(ConnectionSettings{ - URL: server.URL, - Transport: transport, - }, log) - require.NoError(t, err) + log := logptest.NewTestingLogger(t, "TestConnectionTLS") + conn, err := NewConnection(ConnectionSettings{ + URL: server.URL, + Transport: transport, + }, log) + require.NoError(t, err) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() - err = conn.Connect(ctx) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + err = conn.Connect(ctx) - if version.FIPSDistribution { - require.ErrorContains(t, err, "tls: internal error") - } else { - require.NoError(t, err) + if version.FIPSDistribution { + require.ErrorContains(t, err, "RSA-1024 public key which is not allowed by FIPS 140-3") + } else { + require.NoError(t, err) + } + }) } } diff --git a/testing/go-ech/ech.go b/testing/go-ech/ech.go index 76e6e41f0ec1..77d43959b76e 100644 --- a/testing/go-ech/ech.go +++ b/testing/go-ech/ech.go @@ -22,8 +22,6 @@ package ech import ( "debug/buildinfo" "os" - "os/exec" - "runtime" "strings" "testing" "time" @@ -57,33 +55,28 @@ func VerifyFIPSBinary(t *testing.T, binaryPath string) { info, err := buildinfo.ReadFile(binaryPath) assert.NoError(t, err) - var checkLinks, foundTags, foundExperiment bool + var foundTags, foundFIPS, foundFIPSDefault bool for _, setting := range info.Settings { switch setting.Key { case "-tags": foundTags = true assert.Contains(t, setting.Value, "requirefips") continue - case "GOEXPERIMENT": - foundExperiment = true - assert.Contains(t, setting.Value, "systemcrypto") + case "GOFIPS140": + foundFIPS = true + assert.True(t, strings.HasPrefix(setting.Value, "v1.0.0"), "GOFIPS140 must reference the certified module version, got %q", setting.Value) continue - case "-ldflags": - if !strings.Contains(setting.Value, "-s") { - checkLinks = true + case "DefaultGODEBUG": + if strings.Contains(setting.Value, "fips140=on") { + foundFIPSDefault = true } + continue } } assert.True(t, foundTags, "did not find build tags") - assert.True(t, foundExperiment, "did not find GOEXPERIMENT") - - if checkLinks && runtime.GOOS == "linux" { - t.Log("Binary is not stripped, checking for OpenSSL in the symbols table.") - output, err := exec.CommandContext(t.Context(), "go", "tool", "nm", binaryPath).Output() - assert.NoError(t, err, "unable to run go tool nm") - assert.Contains(t, output, "OpenSSL_version", "Unable to find OpenSSL_version in symbols link") - } + assert.True(t, foundFIPS, "did not find GOFIPS140 within binary version information") + assert.True(t, foundFIPSDefault, "did not find fips140=on in DefaultGODEBUG — binary will not enforce FIPS mode at runtime (check GOFIPS140 env at build time)") if t.Failed() { t.Fatal("Unable to verify FIPS binary.") // stop test if non-FIPS binary is used. }