From a9c8cb65622b30483c594daa4a82de81e8f15aba Mon Sep 17 00:00:00 2001 From: Evan Hearne Date: Thu, 3 Sep 2026 08:58:21 +0100 Subject: [PATCH 1/2] OCPBUGS-109578: bump library-go to fix oc macos hcp insecure login This commit bumps library-go to include the latest changes. This fixes an issue seen when oc client is used to login to a HCP cluster on macOS. This allows oc to login successfully. `verifyServerCertChain()` now has a check that returns an unknown authority error when it detects macOS and a string based x509 error. It falls back to kubeconfig CA when a string based x509 error is observed on the macOS platform. --- go.mod | 2 +- go.sum | 4 ++-- .../pkg/oauth/tokenrequest/request_token.go | 18 +++++++++++++++++- vendor/modules.txt | 2 +- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 3acb4b54b9..4b90d09a05 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( github.com/openshift/api v0.0.0-20260805215214-cfb63858e9d7 github.com/openshift/build-machinery-go v0.0.0-20260629141115-154a2b810491 github.com/openshift/client-go v0.0.0-20260806041845-b74fb348f1e7 - github.com/openshift/library-go v0.0.0-20260901055840-8c76f7d75dd6 + github.com/openshift/library-go v0.0.0-20260902200604-6de66ffc2023 github.com/openshift/osincli v0.0.0-20160924135400-fababb0555f2 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c github.com/prometheus/client_golang v1.23.2 diff --git a/go.sum b/go.sum index 327a6cc4c2..8c3baa21f4 100644 --- a/go.sum +++ b/go.sum @@ -385,8 +385,8 @@ github.com/openshift/client-go v0.0.0-20260806041845-b74fb348f1e7 h1:Lphm0uMAyM2 github.com/openshift/client-go v0.0.0-20260806041845-b74fb348f1e7/go.mod h1:u08LcpI8Hq3IpelQLbciGRa/P158cE/O3uQe2Bt3Roo= github.com/openshift/gssapi v0.0.0-20260819120910-d6b72669a11e h1:UCxtFDw0ObWGm4bmaAhFZ1hEwZPZnwiSONKj7G6WBr0= github.com/openshift/gssapi v0.0.0-20260819120910-d6b72669a11e/go.mod h1:tNrEB5k8SI+g5kOlsCmL2ELASfpqEofI0+FLBgBdN08= -github.com/openshift/library-go v0.0.0-20260901055840-8c76f7d75dd6 h1:nmN0ZlH/5yVEv6QQgMcsvp1LtOIcoF8zFAQZ/rOus9s= -github.com/openshift/library-go v0.0.0-20260901055840-8c76f7d75dd6/go.mod h1:pH7rnNOj3dJpdpBtE32LB2pAg0AYDIaaBJJrFxX2pPY= +github.com/openshift/library-go v0.0.0-20260902200604-6de66ffc2023 h1:Em0zfVCYoLmxk/LnftWd/PDV7VpY5qdes3dpzanNFdI= +github.com/openshift/library-go v0.0.0-20260902200604-6de66ffc2023/go.mod h1:pH7rnNOj3dJpdpBtE32LB2pAg0AYDIaaBJJrFxX2pPY= github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1 h1:PMTgifBcBRLJJiM+LgSzPDTk9/Rx4qS09OUrfpY6GBQ= github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/openshift/osincli v0.0.0-20160924135400-fababb0555f2 h1:9oADVMmPa4G60MQtoSjD26aD/vZreqbIAfiUiO220eY= diff --git a/vendor/github.com/openshift/library-go/pkg/oauth/tokenrequest/request_token.go b/vendor/github.com/openshift/library-go/pkg/oauth/tokenrequest/request_token.go index 820265537a..5458e08b07 100644 --- a/vendor/github.com/openshift/library-go/pkg/oauth/tokenrequest/request_token.go +++ b/vendor/github.com/openshift/library-go/pkg/oauth/tokenrequest/request_token.go @@ -10,6 +10,7 @@ import ( "net" "net/http" "net/url" + "runtime" "slices" "strings" @@ -602,8 +603,23 @@ func verifyServerCertChain(dnsName string, chain []*x509.Certificate) ([][]*x509 intermediates.AddCert(c) } - return chain[0].Verify(x509.VerifyOptions{ + certChainList, err := chain[0].Verify(x509.VerifyOptions{ Intermediates: intermediates, DNSName: dnsName, }) + + if runtime.GOOS == "darwin" && strings.HasPrefix(err.Error(), "x509:") { + // this check fills in the gap where root_darwin.go has insufficient + // typed errors for macOS platform, leading to a generic string based + // x509 error. This will return a proper x509 error which can be used + // to return kubeconfig CA client. x509.UnknownAuthorityError was + // chosen because this is the fall back also used on Linux/Windows, + // keeping the approach consistent across platforms. + // https://github.com/golang/go/blob/5a6340ff28c87e099f33c941e3d73e50d715ddf7/src/crypto/x509/root_darwin.go#L74 + return nil, x509.UnknownAuthorityError{ + Cert: chain[0], + } + } + + return certChainList, err } diff --git a/vendor/modules.txt b/vendor/modules.txt index 88aece9ea7..0f99df04ac 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -900,7 +900,7 @@ github.com/openshift/client-go/user/clientset/versioned/fake github.com/openshift/client-go/user/clientset/versioned/scheme github.com/openshift/client-go/user/clientset/versioned/typed/user/v1 github.com/openshift/client-go/user/clientset/versioned/typed/user/v1/fake -# github.com/openshift/library-go v0.0.0-20260901055840-8c76f7d75dd6 +# github.com/openshift/library-go v0.0.0-20260902200604-6de66ffc2023 ## explicit; go 1.26.0 github.com/openshift/library-go/pkg/apiserver/jsonpatch github.com/openshift/library-go/pkg/apps/appsserialization From 40bfd32dc098d33036605d4c11a5dd53616daec7 Mon Sep 17 00:00:00 2001 From: Evan Hearne Date: Wed, 9 Sep 2026 12:03:28 +0100 Subject: [PATCH 2/2] bump library-go to ehearne-redhat/library-go#2455 version This fix resolves a major issue introduced in a recent change where logging in using oc on macos to a hcp client with insecure flag was used. On other clusters where there was no error, the check now panics on strings.HasPrefix(err.Error(), ...) as there was no check to see if err != nil. This was flagged by coderabbitai in library-go bump pr in oc. https://github.com/openshift/oc/pull/2391#discussion_r3922929300 This change move darwin cert verify logic out of verifyServerCertChain, and additionally, adds a unit test that actually tests the error logic for darwin based systems. Additionally, this commit simplifies the error checking process by wrapping the error in a custom error for better readability. it also simplifies the error checking and unit tests for this problem. It demonstrates the change in action in oc. --- go.mod | 2 + go.sum | 4 +- .../pkg/oauth/tokenrequest/request_token.go | 46 +++++++++++++------ vendor/modules.txt | 3 +- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/go.mod b/go.mod index 4b90d09a05..9cd06e81c9 100644 --- a/go.mod +++ b/go.mod @@ -231,3 +231,5 @@ require ( replace github.com/apcera/gssapi => github.com/openshift/gssapi v0.0.0-20260819120910-d6b72669a11e replace github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1 + +replace github.com/openshift/library-go => github.com/ehearne-redhat/library-go v0.0.0-20260909101331-46cb1db2f53d diff --git a/go.sum b/go.sum index 8c3baa21f4..5b83c62335 100644 --- a/go.sum +++ b/go.sum @@ -137,6 +137,8 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4 github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4= github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/ehearne-redhat/library-go v0.0.0-20260909101331-46cb1db2f53d h1:i1w/f4jzVCRF1OfWG6uVecnIq8KdCOWHNHlSH+BJ4sg= +github.com/ehearne-redhat/library-go v0.0.0-20260909101331-46cb1db2f53d/go.mod h1:pH7rnNOj3dJpdpBtE32LB2pAg0AYDIaaBJJrFxX2pPY= github.com/elazarl/goproxy v1.8.2 h1:keGt9KHFAnrXFEctQuOF9NRxKFCXtd5cQg5PrBdeVW4= github.com/elazarl/goproxy v1.8.2/go.mod h1:b5xm6W48AUHNpRTCvlnd0YVh+JafCCtsLsJZvvNTz+E= github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= @@ -385,8 +387,6 @@ github.com/openshift/client-go v0.0.0-20260806041845-b74fb348f1e7 h1:Lphm0uMAyM2 github.com/openshift/client-go v0.0.0-20260806041845-b74fb348f1e7/go.mod h1:u08LcpI8Hq3IpelQLbciGRa/P158cE/O3uQe2Bt3Roo= github.com/openshift/gssapi v0.0.0-20260819120910-d6b72669a11e h1:UCxtFDw0ObWGm4bmaAhFZ1hEwZPZnwiSONKj7G6WBr0= github.com/openshift/gssapi v0.0.0-20260819120910-d6b72669a11e/go.mod h1:tNrEB5k8SI+g5kOlsCmL2ELASfpqEofI0+FLBgBdN08= -github.com/openshift/library-go v0.0.0-20260902200604-6de66ffc2023 h1:Em0zfVCYoLmxk/LnftWd/PDV7VpY5qdes3dpzanNFdI= -github.com/openshift/library-go v0.0.0-20260902200604-6de66ffc2023/go.mod h1:pH7rnNOj3dJpdpBtE32LB2pAg0AYDIaaBJJrFxX2pPY= github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1 h1:PMTgifBcBRLJJiM+LgSzPDTk9/Rx4qS09OUrfpY6GBQ= github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= github.com/openshift/osincli v0.0.0-20160924135400-fababb0555f2 h1:9oADVMmPa4G60MQtoSjD26aD/vZreqbIAfiUiO220eY= diff --git a/vendor/github.com/openshift/library-go/pkg/oauth/tokenrequest/request_token.go b/vendor/github.com/openshift/library-go/pkg/oauth/tokenrequest/request_token.go index 5458e08b07..255f212971 100644 --- a/vendor/github.com/openshift/library-go/pkg/oauth/tokenrequest/request_token.go +++ b/vendor/github.com/openshift/library-go/pkg/oauth/tokenrequest/request_token.go @@ -5,6 +5,7 @@ import ( "crypto/tls" "crypto/x509" "encoding/json" + "errors" "fmt" "io" "net" @@ -552,6 +553,7 @@ func transportWithSystemRoots(issuer string, clientConfig *restclient.Config) (h resp.Body.Close() _, err = verifyServerCertChain(issuerURL.Hostname(), resp.TLS.PeerCertificates) + switch err.(type) { case nil: // copy the config so we can freely mutate it @@ -585,6 +587,12 @@ func transportWithSystemRoots(issuer string, clientConfig *restclient.Config) (h klog.V(4).Infof("falling back to kubeconfig CA due to possible IO error: %v", err) return restclient.TransportFor(clientConfig) } + // could be string based x509 error... + err = convertErrorIfUnknownX509(runtime.GOOS, err) + if _, ok := errors.AsType[unknownX509VerificationError](err); ok { + klog.V(4).Infof("falling back to kubeconfig CA due to possible unknown x509 error: %v", err) + return restclient.TransportFor(clientConfig) + } // unknown error, fail (ideally should never occur) klog.V(4).Infof("unexpected error during system roots probe: %v", err) return nil, err @@ -603,23 +611,33 @@ func verifyServerCertChain(dnsName string, chain []*x509.Certificate) ([][]*x509 intermediates.AddCert(c) } - certChainList, err := chain[0].Verify(x509.VerifyOptions{ + return chain[0].Verify(x509.VerifyOptions{ Intermediates: intermediates, DNSName: dnsName, }) +} - if runtime.GOOS == "darwin" && strings.HasPrefix(err.Error(), "x509:") { - // this check fills in the gap where root_darwin.go has insufficient - // typed errors for macOS platform, leading to a generic string based - // x509 error. This will return a proper x509 error which can be used - // to return kubeconfig CA client. x509.UnknownAuthorityError was - // chosen because this is the fall back also used on Linux/Windows, - // keeping the approach consistent across platforms. - // https://github.com/golang/go/blob/5a6340ff28c87e099f33c941e3d73e50d715ddf7/src/crypto/x509/root_darwin.go#L74 - return nil, x509.UnknownAuthorityError{ - Cert: chain[0], - } +// convertErrorIfUnknownX509 normalizes certificate verification errors on macOS. +// root_darwin.go in the Go standard library has insufficient typed errors for the +// macOS platform, leading to a generic string based "x509:" error rather than a +// typed one. This wraps such an error in an unknownX509VerificationError so callers +// can react to it the same way they do on Linux/Windows (e.g. falling back to the +// kubeconfig CA), keeping the approach consistent across platforms. The original +// error is preserved and remains recoverable via errors.Unwrap/errors.Is. +// +// goos is passed in (rather than read from runtime.GOOS) so the darwin branch can +// be exercised in tests regardless of the platform they run on. +// https://github.com/golang/go/blob/5a6340ff28c87e099f33c941e3d73e50d715ddf7/src/crypto/x509/root_darwin.go#L74 +func convertErrorIfUnknownX509(goos string, err error) error { + if goos == "darwin" && err != nil && strings.HasPrefix(err.Error(), "x509:") { + return unknownX509VerificationError{err} } - - return certChainList, err + return err } + +// unknownX509VerificationError wraps an opaque, string based x509 verification +// error (see convertErrorIfUnknownX509) so it can be matched by type while still +// preserving the underlying error. +type unknownX509VerificationError struct{ error } + +func (e unknownX509VerificationError) Unwrap() error { return e.error } diff --git a/vendor/modules.txt b/vendor/modules.txt index 0f99df04ac..90b4e92a53 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -900,7 +900,7 @@ github.com/openshift/client-go/user/clientset/versioned/fake github.com/openshift/client-go/user/clientset/versioned/scheme github.com/openshift/client-go/user/clientset/versioned/typed/user/v1 github.com/openshift/client-go/user/clientset/versioned/typed/user/v1/fake -# github.com/openshift/library-go v0.0.0-20260902200604-6de66ffc2023 +# github.com/openshift/library-go v0.0.0-20260902200604-6de66ffc2023 => github.com/ehearne-redhat/library-go v0.0.0-20260909101331-46cb1db2f53d ## explicit; go 1.26.0 github.com/openshift/library-go/pkg/apiserver/jsonpatch github.com/openshift/library-go/pkg/apps/appsserialization @@ -2062,3 +2062,4 @@ sigs.k8s.io/yaml/goyaml.v3 sigs.k8s.io/yaml/kyaml # github.com/apcera/gssapi => github.com/openshift/gssapi v0.0.0-20260819120910-d6b72669a11e # github.com/onsi/ginkgo/v2 => github.com/openshift/onsi-ginkgo/v2 v2.6.1-0.20251001123353-fd5b1fb35db1 +# github.com/openshift/library-go => github.com/ehearne-redhat/library-go v0.0.0-20260909101331-46cb1db2f53d