From f755a3cb3665c741f5201064bb5bf73f34796fa6 Mon Sep 17 00:00:00 2001 From: Feng Ruohang Date: Wed, 9 Sep 2026 18:50:12 +0800 Subject: [PATCH] test(tls): cover web environment key exchange defaults Exercise the real web-environment client with ML-KEM enabled and disabled, and document consuming-application defaults and macOS CA replacement. Validation: make test with the full race suite and lint passes; the new test also compiles and passes with Go 1.26.5. Adversarial review: Claude Code Fable 5.1, max effort. Final verdict: APPROVE FOR COMMIT. Signed-off-by: Feng Ruohang --- README.md | 21 +++++++++++++++++ env/web_env_tls_test.go | 50 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 env/web_env_tls_test.go diff --git a/README.md b/README.md index 48d6245..3738a08 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,27 @@ require this path, and rewrite the imports. The repository was renamed from `pgsty/minio-pkg` on 2026-08-02. GitHub redirects the old path, but pin the new one. +## Go and TLS compatibility + +The library retains its Go 1.26 floor and is also tested with Go 1.27. Runtime +defaults depend on the consuming application's Go version and `GODEBUG`, not +just this library's `go.mod`. The web-environment client leaves TLS key exchange +at Go defaults; LDAP and OIDC helpers also preserve caller-supplied TLS settings. +For default-configured TLS, `GODEBUG=tlsmlkem=0` disables hybrid key exchanges; +`GODEBUG=tlssecpmlkem=0` disables only the SecP hybrids and retains X25519MLKEM768. +These settings preserve certificate verification. + +On macOS, applications targeting Go 1.27 replace Keychain trust with on-disk +roots and Go's verifier when either `SSL_CERT_FILE` or `SSL_CERT_DIR` is set. +Stale or incomplete CA paths can break previously trusted connections; unset +inherited values to restore Keychain trust. Explicit CAs supplied to +`certs.GetRootCAs` remain additive to the selected root pool. +An application still targeting Go 1.26 retains the +old platform default unless it opts in with +`GODEBUG=x509sslcertoverrideplatform=1`. The Windows loader in this package reads +the Windows ROOT store directly and is unchanged. See the +[Go release notes](https://go.dev/doc/go1.27). + ## Versioning Tags follow upstream's numbering so it is obvious which release a version is diff --git a/env/web_env_tls_test.go b/env/web_env_tls_test.go new file mode 100644 index 0000000..f90010b --- /dev/null +++ b/env/web_env_tls_test.go @@ -0,0 +1,50 @@ +// Copyright (c) 2026 Pigsty +// SPDX-License-Identifier: AGPL-3.0-or-later + +package env + +import ( + "crypto/tls" + "crypto/x509" + "io" + "net/http" + "net/http/httptest" + "slices" + "strings" + "testing" +) + +func TestWebEnvTLSKeyExchangeDefaults(t *testing.T) { + for _, debug := range []string{"tlsmlkem=0", "tlsmlkem=1"} { + t.Run(debug, func(t *testing.T) { + t.Setenv("GODEBUG", debug) + hellos := make(chan []tls.CurveID, 1) + server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { + _, _ = io.WriteString(w, "lab-value") + })) + server.TLS = &tls.Config{GetConfigForClient: func(hello *tls.ClientHelloInfo) (*tls.Config, error) { + select { + case hellos <- slices.Clone(hello.SupportedCurves): + default: + } + return nil, nil + }} + server.StartTLS() + defer server.Close() + roots := x509.NewCertPool() + roots.AddCert(server.Certificate()) + previousRoots := globalRootCAs + RegisterGlobalCAs(roots) + t.Cleanup(func() { RegisterGlobalCAs(previousRoots) }) + endpoint := "env+tls://local:" + strings.Repeat("x", 64) + "@" + server.Listener.Addr().String() + value, _, _, err := getEnvValueFromHTTP(endpoint, "lab-key") + if err != nil || value != "lab-value" { + t.Fatalf("value %q, error %v", value, err) + } + curves := <-hellos + if got, want := slices.Contains(curves, tls.X25519MLKEM768), debug == "tlsmlkem=1"; got != want { + t.Errorf("ML-KEM offered = %v, want %v; curves %v", got, want, curves) + } + }) + } +}