diff --git a/internal/go118_sha1_patch.go b/internal/go118_sha1_patch.go new file mode 100644 index 0000000000..8076166f5b --- /dev/null +++ b/internal/go118_sha1_patch.go @@ -0,0 +1,47 @@ +package internal + +import ( + "fmt" + "os" + "sync" + _ "unsafe" // for go:linkname + + goversion "github.com/hashicorp/go-version" + "github.com/hashicorp/vault/sdk/version" +) + +const sha1PatchVersionsBefore = "1.12.0" + +var patchSha1 sync.Once + +//go:linkname debugAllowSHA1 crypto/x509.debugAllowSHA1 +var debugAllowSHA1 bool + +// PatchSha1 patches Go 1.18+ to allow certificates with signatures containing SHA-1 hashes to be allowed. +// It is safe to call this function multiple times. +// This is necessary to allow Vault 1.10 and 1.11 to work with Go 1.18+ without breaking backwards compatibility +// with these certificates. See https://go.dev/doc/go1.18#sha1 and +// https://developer.hashicorp.com/vault/docs/deprecation/faq#q-what-is-the-impact-of-removing-support-for-x-509-certificates-with-signatures-that-use-sha-1 +// for more details. +// TODO: remove when Vault <=1.11 is no longer supported +func PatchSha1() { + patchSha1.Do(func() { + patchBefore, err := goversion.NewSemver(sha1PatchVersionsBefore) + if err != nil { + panic(err) + } + + patch := false + v, err := goversion.NewSemver(version.GetVersion().Version) + if err == nil { + patch = v.LessThan(patchBefore) + } else { + fmt.Fprintf(os.Stderr, "Cannot parse version %s; going to apply SHA-1 deprecation patch workaround\n", version.GetVersion().Version) + patch = true + } + + if patch { + debugAllowSHA1 = true + } + }) +} diff --git a/main.go b/main.go index 7e4b1c9d28..bc8a8651f8 100644 --- a/main.go +++ b/main.go @@ -4,8 +4,14 @@ import ( "os" "github.com/hashicorp/vault/command" + "github.com/hashicorp/vault/internal" ) +func init() { + // this is a good place to patch SHA-1 support back into x509 + internal.PatchSha1() +} + func main() { os.Exit(command.Run(os.Args[1:])) }