Commit f6be1cf1 authored by Filippo Valsorda's avatar Filippo Valsorda Committed by Filippo Valsorda

crypto/x509: fix root CA extraction on macOS (cgo path)

The cgo path was not taking policies into account, using the last
security setting in the array whatever it was. Also, it was not aware of
the defaults for empty security settings, and for security settings
without a result type. Finally, certificates restricted to a hostname
were considered roots.

The API docs for this code are partial and not very clear, so this is a
best effort, really.

Updates #24652

Change-Id: I8fa2fe4706f44f3d963b32e0615d149e997b537d
Reviewed-on: https://go-review.googlesource.com/c/128056
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarAdam Langley <agl@google.com>
Reviewed-by: default avatarAdam Langley <agl@golang.org>
parent fb69478e
This diff is collapsed.
...@@ -21,7 +21,7 @@ import ( ...@@ -21,7 +21,7 @@ import (
"sync" "sync"
) )
var debugExecDarwinRoots = strings.Contains(os.Getenv("GODEBUG"), "x509roots=1") var debugDarwinRoots = strings.Contains(os.Getenv("GODEBUG"), "x509roots=1")
func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
return nil, nil return nil, nil
...@@ -57,7 +57,7 @@ func execSecurityRoots() (*CertPool, error) { ...@@ -57,7 +57,7 @@ func execSecurityRoots() (*CertPool, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if debugExecDarwinRoots { if debugDarwinRoots {
println(fmt.Sprintf("crypto/x509: %d certs have a trust policy", len(hasPolicy))) println(fmt.Sprintf("crypto/x509: %d certs have a trust policy", len(hasPolicy)))
} }
...@@ -68,8 +68,8 @@ func execSecurityRoots() (*CertPool, error) { ...@@ -68,8 +68,8 @@ func execSecurityRoots() (*CertPool, error) {
home, err := os.UserHomeDir() home, err := os.UserHomeDir()
if err != nil { if err != nil {
if debugExecDarwinRoots { if debugDarwinRoots {
println("crypto/x509: can't get user home directory: %v", err) println(fmt.Sprintf("crypto/x509: can't get user home directory: %v", err))
} }
} else { } else {
args = append(args, args = append(args,
...@@ -147,7 +147,7 @@ func execSecurityRoots() (*CertPool, error) { ...@@ -147,7 +147,7 @@ func execSecurityRoots() (*CertPool, error) {
close(blockCh) close(blockCh)
wg.Wait() wg.Wait()
if debugExecDarwinRoots { if debugDarwinRoots {
mu.Lock() mu.Lock()
defer mu.Unlock() defer mu.Unlock()
println(fmt.Sprintf("crypto/x509: ran security verify-cert %d times", numVerified)) println(fmt.Sprintf("crypto/x509: ran security verify-cert %d times", numVerified))
...@@ -175,16 +175,16 @@ func verifyCertWithSystem(block *pem.Block, cert *Certificate) bool { ...@@ -175,16 +175,16 @@ func verifyCertWithSystem(block *pem.Block, cert *Certificate) bool {
} }
cmd := exec.Command("/usr/bin/security", "verify-cert", "-c", f.Name(), "-l", "-L") cmd := exec.Command("/usr/bin/security", "verify-cert", "-c", f.Name(), "-l", "-L")
var stderr bytes.Buffer var stderr bytes.Buffer
if debugExecDarwinRoots { if debugDarwinRoots {
cmd.Stderr = &stderr cmd.Stderr = &stderr
} }
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
if debugExecDarwinRoots { if debugDarwinRoots {
println(fmt.Sprintf("crypto/x509: verify-cert rejected %s: %q", cert.Subject, bytes.TrimSpace(stderr.Bytes()))) println(fmt.Sprintf("crypto/x509: verify-cert rejected %s: %q", cert.Subject, bytes.TrimSpace(stderr.Bytes())))
} }
return false return false
} }
if debugExecDarwinRoots { if debugDarwinRoots {
println(fmt.Sprintf("crypto/x509: verify-cert approved %s", cert.Subject)) println(fmt.Sprintf("crypto/x509: verify-cert approved %s", cert.Subject))
} }
return true return true
...@@ -217,7 +217,7 @@ func getCertsWithTrustPolicy() (map[string]bool, error) { ...@@ -217,7 +217,7 @@ func getCertsWithTrustPolicy() (map[string]bool, error) {
// Rather than match on English substrings that are probably // Rather than match on English substrings that are probably
// localized on macOS, just interpret any failure to mean that // localized on macOS, just interpret any failure to mean that
// there are no trust settings. // there are no trust settings.
if debugExecDarwinRoots { if debugDarwinRoots {
println(fmt.Sprintf("crypto/x509: exec %q: %v, %s", cmd.Args, err, stderr.Bytes())) println(fmt.Sprintf("crypto/x509: exec %q: %v, %s", cmd.Args, err, stderr.Bytes()))
} }
return nil return nil
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment