Repository: go
Issue: crypto/x509: Trust relationship of certs returned by 'x509.SystemCertPool()' is ambiguous
Labels: NeedsInvestigation

### What version of Go are you using (`go version`)?

<pre>
$ go version
go version go1.13.7 darwin/amd64
</pre>

### Does this issue reproduce with the latest release?
Yes.

### What operating system and processor architecture are you using (`go env`)?
CentOS 7.8.

<details><summary><code>go env</code> Output</summary><br><pre>
$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/root/go"
GOPRIVATE=""
GOPROXY="direct"
GOROOT="/usr/lib/golang"
GOSUMDB="off"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/golang/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build466747349=/tmp/go-build -gno-record-gcc-switches"
</pre></details>

### What did you do?
On a CentOS 7.8 system, the `x509.SystemCertPool()` function returns a `CertPool` containing all X.509 certificates stored in the directory `/etc/pki/tls/certs/`. While I cannot find a clear source describing the purpose of this directory, there is RedHat documentation that indicates Apache httpd end entity (server) certificates can be stored there (I believe this is also the default directory for end entity certificates in the httpd configs as well). This can be seen in the following snippets from https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/5/html/deployment_guide/s1-httpd-secure-server:
```
25.8.3. Using Pre-Existing Keys and Certificates
[...]
Move your existing certificate file to: 
/etc/pki/tls/certs/server.crt
```

```
25.8.6. How to configure the server to use the new key
[...]
Edit /etc/httpd/conf.d/ssl.conf. Change the SSLCertificateFile and SSLCertificateKey lines to be.
SSLCertificateFile /etc/pki/tls/certs/www.example.com.crt
SSLCertificateKeyFile /etc/pki/tls/private/www.example.com.key
```

I would never implicitly trust these certificates, even if I am serving them. However, the `CertPool` returned by `SystemCertPool()` includes them via `loadSystemRoots()` in 'root_unix.go'.

Taking a look at the function, its current documentation states:
```
// SystemCertPool returns a copy of the system cert pool.
//
// Any mutations to the returned pool are not written to disk and do
// not affect any other pool returned by SystemCertPool.
//
// New changes in the system cert pool might not be reflected
// in subsequent calls.
```

I realize that there is no mention of trust relationship here - however, in a few spots in the code, there are hints about "roots", which to me indicates CA certificates (or at least non-server certificates). For example the error message in 'cert_pool.go', line 50:
```
return nil, errors.New("crypto/x509: system root pool is not available on Windows")
```

And the function name `loadSystemRoots()`, and the local variable name in 'root_unix.go', line 39:
```
func loadSystemRoots() (*CertPool, error) {
	roots := NewCertPool()
```

The change to search in `/etc/pki/tls/certs` for certificates in `loadSystemRoots()` occurred in:
https://github.com/golang/go/commit/e83bcd95a4a86e4caf2faa78158170d512dd9de5

I do not see any obvious reason why any random certificate file in this directory would be trusted, barring `ca-bundle.crt`. As noted in the RedHat documentation, there *could* be end entity certificates stored in `/etc/pki/tls/certs`... So, Go's behavior feels incorrect.

At the very least, the purpose of `SystemCertPool()` feels ambiguous.

### What did you expect to see?
I expected `x509.SystemCertPool()` to return only CA certificates trusted by the operating system.

### What did you see instead?
The function returns non-CA, or end entity certificates that are not trusted by the operating system (specifically, on CentOS 7.8). This can result in unexpected validation paths ("verified chains" as referenced by the Go library) when connecting to TLS servers.