From f6712ca4174fe7f51c44a1682d7a77cb29149846 Mon Sep 17 00:00:00 2001 From: Alexander Scheel Date: Tue, 15 Mar 2022 12:04:21 -0500 Subject: [PATCH] Introduce fips build tag (#14495) Unlike fips_140_3, fips will be a (FIPS) version-agnostic build tag. The listener support will remain in 140-3 only, but the IsFIPS() check should apply regardless of FIPS version. We add two FIPS-only build files which validate the constraints of FIPS builds here: fips must be specified with either fips_140_2 or fips_140_3 build tags, and fips and cgo must also be specified together. Additionally, using only a version-specific FIPS build tag without the version-agnostic FIPS tag should be a failure. Signed-off-by: Alexander Scheel --- helper/constants/fips.go | 2 +- helper/constants/fips_build_check.go | 38 ++++++++++++++++++++++++++++ helper/constants/fips_cgo_check.go | 18 +++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 helper/constants/fips_build_check.go create mode 100644 helper/constants/fips_cgo_check.go diff --git a/helper/constants/fips.go b/helper/constants/fips.go index d384e83e8..2a9f7ee7a 100644 --- a/helper/constants/fips.go +++ b/helper/constants/fips.go @@ -1,4 +1,4 @@ -//go:build !fips_140_3 +//go:build !fips package constants diff --git a/helper/constants/fips_build_check.go b/helper/constants/fips_build_check.go new file mode 100644 index 000000000..aee3d0edb --- /dev/null +++ b/helper/constants/fips_build_check.go @@ -0,0 +1,38 @@ +//go:build (!fips && (fips_140_2 || fips_140_3)) || (fips && !fips_140_2 && !fips_140_3) || (fips_140_2 && fips_140_3) + +package constants + +import "C" + +// This function is the equivalent of an external (CGo) function definition, +// without implementation in any imported or built library. This results in +// a linker err if the above build constraints are satisfied: +// +// /home/cipherboy/GitHub/cipherboy/vault-enterprise/helper/constants/fips_build_check.go:10: undefined reference to `github.com/hashicorp/vault/helper/constants.VaultFIPSBuildRequiresVersionAgnosticTagAndOneVersionTag' +// +// This indicates that a build error has occurred due to mismatched tags. +// +// In particular, we use this to enforce the following restrictions on build +// tags: +// +// - If a versioned fips_140_* tag is specified, the unversioned tag must +// also be. +// - If the unversioned tag is specified, a versioned tag must be. +// - Both versioned flags cannot be specified at the same time. +// +// In the unlikely event that a FFI implementation for this function exists +// in the future, it should be renamed to a new function which does not +// exist. +// +// This approach was chosen above the other implementation in fips_cgo_check.go +// because this version does not break static analysis tools: most tools do not +// cross the CGo boundary and thus do not know that the below function is +// missing an implementation. However, in the other file, the function call is +// not marked as CGo (in part large because the lack of a cgo build tag +// prohibits us from using the same technique) and thus it must be a Go +// declaration, that is missing. +func VaultFIPSBuildRequiresVersionAgnosticTagAndOneVersionTag() + +func init() { + VaultFIPSBuildRequiresVersionAgnosticTagAndOneVersionTag() +} diff --git a/helper/constants/fips_cgo_check.go b/helper/constants/fips_cgo_check.go new file mode 100644 index 000000000..56eabb6c8 --- /dev/null +++ b/helper/constants/fips_cgo_check.go @@ -0,0 +1,18 @@ +//go:build (fips || fips_140_2 || fips_140_3) && !cgo + +package constants + +func init() { + // See note in fips_build_check.go. + // + // This function call is missing a declaration, causing the build to + // fail on improper tags (fips specified but cgo not specified). This + // ensures Vault fails to build if a FIPS build is requested but CGo + // support is not enabled. + // + // Note that this could confuse static analysis tools as this function + // should not ever be defined. If this function is defined in the future, + // the below reference should be renamed to a new name that is not + // defined to ensure we get a build failure. + VaultFIPSBuildTagMustEnableCGo() +}