-
Notifications
You must be signed in to change notification settings - Fork 18.3k
Description
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
.