What version of Go are you using (go version)?
1.18.2
I'm pretty sure this is a regression from https://go-review.googlesource.com/c/go/+/353132 (#46287).
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env)?
The bug reproduces on darwin/arm64 (and I suspect darwin/amd64 as well). I tested that the bug does not exist on linux/amd64.
What did you do?
Below is a minimal reproduction.
package main
import (
"crypto/x509"
"errors"
"fmt"
"net/http"
"net/http/httptest"
"time"
)
func main() {
handler := func(w http.ResponseWriter, req *http.Request) {
w.WriteHeader(200)
}
srv := httptest.NewTLSServer(http.HandlerFunc(handler))
defer srv.Close()
req, _ := http.NewRequest("GET", srv.URL, nil)
c := http.Client{Timeout: time.Second}
_, err := c.Do(req)
fmt.Println(err)
var uaErr x509.UnknownAuthorityError
ok := errors.As(err, &uaErr)
fmt.Println("should be true", ok)
}
The problem can be seen in libraries as well. For example this commit hashicorp/go-retryablehttp@bff1f16 is someone trying to work around the problem in hashicorp/go-retryablehttp.
What did you expect to see?
I expected the underlying error (url.Error.Err) to be x509.UnknownAuthorityError on all platforms regardless of what value I used for tls.Config.RootCAs.
In most cases:
- on
linux/amd64 with all versions of Go
- on
darwin with Go <= 1.17.x
- when using non-system roots (i.e. any non-default value for
tls.Config.RootCAs)
the errors.As(err, &uaErr) line correctly returns true, and the caller is able to inspect the certificate.
I did not test on windows, but from a quick read of root_windows.go it seems there is some effort made to create an UnknownAuthorityError in a number of cases, so it is likely that it works correctly on windows as well.
What did you see instead?
On darwin with Go 1.18.x , errors.As(err, &uaErr) returns false. The error is something like this:
url.Error{Op: "GET", Err: fmt.Errorf("x509: “ServerName” certificate is not trusted")}
url.Error.Err has a type of errors.errorString instead of x509.UnknownAuthorityError.
TestPlatformVerifier in crypto/x509/root_darwin_test.go is the only place I can find this error message, so I guess it must come from Certificate.systemVerify in root_darwin.go.
What version of Go are you using (
go version)?I'm pretty sure this is a regression from https://go-review.googlesource.com/c/go/+/353132 (#46287).
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env)?The bug reproduces on
darwin/arm64(and I suspectdarwin/amd64as well). I tested that the bug does not exist onlinux/amd64.What did you do?
Below is a minimal reproduction.
The problem can be seen in libraries as well. For example this commit hashicorp/go-retryablehttp@bff1f16 is someone trying to work around the problem in
hashicorp/go-retryablehttp.What did you expect to see?
I expected the underlying error (
url.Error.Err) to bex509.UnknownAuthorityErroron all platforms regardless of what value I used fortls.Config.RootCAs.In most cases:
linux/amd64with all versions of Godarwinwith Go <= 1.17.xtls.Config.RootCAs)the
errors.As(err, &uaErr)line correctly returnstrue, and the caller is able to inspect the certificate.I did not test on windows, but from a quick read of
root_windows.goit seems there is some effort made to create anUnknownAuthorityErrorin a number of cases, so it is likely that it works correctly on windows as well.What did you see instead?
On
darwinwith Go 1.18.x ,errors.As(err, &uaErr)returnsfalse. The error is something like this:url.Error.Errhas a type oferrors.errorStringinstead ofx509.UnknownAuthorityError.TestPlatformVerifierincrypto/x509/root_darwin_test.gois the only place I can find this error message, so I guess it must come fromCertificate.systemVerifyinroot_darwin.go.