What version of Go are you using (go version)?
$ go version
go version go1.13.5 darwin/amd64
Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (go env)?
go env Output
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/ganni/Library/Caches/go-build"
GOENV="/Users/ganni/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/ganni/.gvm/pkgsets/go1.13.5/global"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/Users/ganni/.gvm/gos/go1.13.5"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/ganni/.gvm/gos/go1.13.5/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/jk/kkbbm14x25l9hj_xj1rb4scm002zdg/T/go-build540477719=/tmp/go-build -gno-record-gcc-switches -fno-common"
What did you do?
I ran the following quick program to reproduce it:
package main
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"time"
)
func main() {
client := http.Client{
Timeout: 5 * time.Second,
}
resp, err := client.Get("https://192.168.210.129")
if err != nil {
fmt.Println(err)
os.Exit(1)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
os.Exit(1)
return
}
fmt.Printf("Response:\n\n%s", string(body))
}
Where 192.168.210.129 is a custom server using a self-signed certificate. The notable aspects of this cert are that I'm connecting via IP (which is not present in the CN) and it is only present in the IP Address field of the SAN, like so:
IP Address=192.168.210.129
When I compile the binary to run on a Windows box, I run the following:
GOOS=windows GOARCH=386 go build -o quicktest.exe main.go
What did you expect to see?
I expect to see a response from the server. This server is healthy and I can access it from my browser, so I expect to see an HTML output from the last line.
What did you see instead?
I see the following output while running:
PS C:\> C:\quicktest.exe
Get https://192.168.210.129: x509: certificate is valid for 192.168.210.129, not 192.168.210.129
The interesting part is that it that's the same IP address in both notes.
I then ran a modified version of go to add a panic near https://sourcegraph.com/github.com/golang/go@release-branch.go1.11/-/blob/src/crypto/x509/root_windows.go#L129, changing:
if status.Error != 0 {
switch status.Error {
case syscall.CERT_E_EXPIRED:
return CertificateInvalidError{c, Expired, ""}
case syscall.CERT_E_CN_NO_MATCH:
return HostnameError{c, opts.DNSName}
to
if status.Error != 0 {
switch status.Error {
case syscall.CERT_E_EXPIRED:
return CertificateInvalidError{c, Expired, ""}
case syscall.CERT_E_CN_NO_MATCH:
panic("failed here")
// return HostnameError{c, opts.DNSName}
and see the following stack trace to verify this is indeed where it fails, which is Windows-specific.
Windows PowerShell
Copyright (C) 2016 Microsoft Corporation. All rights reserved.
PS C:\> & 'C:\quicktestcustom.exe'
panic: failed here
goroutine 21 [running]:
crypto/x509.checkChainSSLServerPolicy(0x128cc2c0, 0xb2d7b8, 0x128adb6c, 0xb14850, 0x128adab8)
/code/github.com/golang/go-darwin-amd64-bootstrap/src/crypto/x509/root_windows.go:130 +0x2c7
crypto/x509.(*Certificate).systemVerify(0x128cc2c0, 0x128adb6c, 0x0, 0x0, 0x0, 0x0, 0x0)
/code/github.com/golang/go-darwin-amd64-bootstrap/src/crypto/x509/root_windows.go:213 +0x652
crypto/x509.(*Certificate).Verify(0x128cc2c0, 0x1289a280, 0xf, 0x128f65c0, 0x0, 0x526d9c8, 0xbf88e6b7, 0x112bdfd, 0x0, 0
x814560, ...)
/code/github.com/golang/go-darwin-amd64-bootstrap/src/crypto/x509/verify.go:750 +0x5b6
crypto/tls.(*Conn).verifyServerCertificate(0x128fc000, 0x12892320, 0x1, 0x1, 0x3eb, 0x0)
/code/github.com/golang/go-darwin-amd64-bootstrap/src/crypto/tls/handshake_client.go:815 +0x1e4
crypto/tls.(*clientHandshakeState).doFullHandshake(0x128adec8, 0x128ba0e0, 0x68)
/code/github.com/golang/go-darwin-amd64-bootstrap/src/crypto/tls/handshake_client.go:452 +0x136c
crypto/tls.(*clientHandshakeState).handshake(0x128adec8, 0x128a26c0, 0x0)
/code/github.com/golang/go-darwin-amd64-bootstrap/src/crypto/tls/handshake_client.go:397 +0x343
crypto/tls.(*Conn).clientHandshake(0x128fc000, 0x0, 0x0)
/code/github.com/golang/go-darwin-amd64-bootstrap/src/crypto/tls/handshake_client.go:206 +0x47a
crypto/tls.(*Conn).Handshake(0x128fc000, 0x0, 0x0)
/code/github.com/golang/go-darwin-amd64-bootstrap/src/crypto/tls/conn.go:1340 +0xe0
net/http.(*persistConn).addTLS.func2(0x0, 0x128fc000, 0x128f4400, 0x128f43c0)
/code/github.com/golang/go-darwin-amd64-bootstrap/src/net/http/transport.go:1453 +0x34
created by net/http.(*persistConn).addTLS
/code/github.com/golang/go-darwin-amd64-bootstrap/src/net/http/transport.go:1449 +0x175
I also further validated I do not see such issues on Linux or Mac machines.
For additional debugging help, I should also mention I only have access to one specific Windows machine that I tested with at the time, so I'm not sure if this is apparent on other Windows versions.
My Windows version is: Windows Server 2012 R2 Standard
What version of Go are you using (
go version)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env)?go envOutputWhat did you do?
I ran the following quick program to reproduce it:
Where
192.168.210.129is a custom server using a self-signed certificate. The notable aspects of this cert are that I'm connecting via IP (which is not present in the CN) and it is only present in theIP Addressfield of the SAN, like so:When I compile the binary to run on a Windows box, I run the following:
What did you expect to see?
I expect to see a response from the server. This server is healthy and I can access it from my browser, so I expect to see an HTML output from the last line.
What did you see instead?
I see the following output while running:
The interesting part is that it that's the same IP address in both notes.
I then ran a modified version of
goto add apanicnear https://sourcegraph.com/github.com/golang/go@release-branch.go1.11/-/blob/src/crypto/x509/root_windows.go#L129, changing:to
and see the following stack trace to verify this is indeed where it fails, which is Windows-specific.
I also further validated I do not see such issues on Linux or Mac machines.
For additional debugging help, I should also mention I only have access to one specific Windows machine that I tested with at the time, so I'm not sure if this is apparent on other Windows versions.
My Windows version is:
Windows Server 2012 R2 Standard