// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:generate go run root_darwin_arm_gen.go -output root_darwin_armx.go

package x509

import (
	"bufio"
	"bytes"
	"crypto/sha1"
	"encoding/pem"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"sync"
)

var debugExecDarwinRoots = strings.Contains(os.Getenv("GODEBUG"), "x509roots=1")

func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) {
	return nil, nil
}

// This code is only used when compiling without cgo.
// It is here, instead of root_nocgo_darwin.go, so that tests can check it
// even if the tests are run with cgo enabled.
// The linker will not include these unused functions in binaries built with cgo enabled.

// execSecurityRoots finds the macOS list of trusted root certificates
// using only command-line tools. This is our fallback path when cgo isn't available.
//
// The strategy is as follows:
//
// 1. Run "security trust-settings-export" and "security
//    trust-settings-export -d" to discover the set of certs with some
//    user-tweaked trust policy. We're too lazy to parse the XML (at
//    least at this stage of Go 1.8) to understand what the trust
//    policy actually is. We just learn that there is _some_ policy.
//
// 2. Run "security find-certificate" to dump the list of system root
//    CAs in PEM format.
//
// 3. For each dumped cert, conditionally verify it with "security
//    verify-cert" if that cert was in the set discovered in Step 1.
//    Without the Step 1 optimization, running "security verify-cert"
//    150-200 times takes 3.5 seconds. With the optimization, the
//    whole process takes about 180 milliseconds with 1 untrusted root
//    CA. (Compared to 110ms in the cgo path)
func execSecurityRoots() (*CertPool, error) {
	hasPolicy, err := getCertsWithTrustPolicy()
	if err != nil {
		return nil, err
	}
	if debugExecDarwinRoots {
		println(fmt.Sprintf("crypto/x509: %d certs have a trust policy", len(hasPolicy)))
	}

	args := []string{"find-certificate", "-a", "-p",
		"/System/Library/Keychains/SystemRootCertificates.keychain",
		"/Library/Keychains/System.keychain",
	}

	home := os.UserHomeDir()
	if home == "" {
		if debugExecDarwinRoots {
			println("crypto/x509: can't get user home directory")
		}
	} else {
		args = append(args,
			filepath.Join(home, "/Library/Keychains/login.keychain"),

			// Fresh installs of Sierra use a slightly different path for the login keychain
			filepath.Join(home, "/Library/Keychains/login.keychain-db"),
		)
	}

	cmd := exec.Command("/usr/bin/security", args...)
	data, err := cmd.Output()
	if err != nil {
		return nil, err
	}

	var (
		mu          sync.Mutex
		roots       = NewCertPool()
		numVerified int // number of execs of 'security verify-cert', for debug stats
	)

	blockCh := make(chan *pem.Block)
	var wg sync.WaitGroup

	// Using 4 goroutines to pipe into verify-cert seems to be
	// about the best we can do. The verify-cert binary seems to
	// just RPC to another server with coarse locking anyway, so
	// running 16 at a time for instance doesn't help at all. Due
	// to the "if hasPolicy" check below, though, we will rarely
	// (or never) call verify-cert on stock macOS systems, though.
	// The hope is that we only call verify-cert when the user has
	// tweaked their trust policy. These 4 goroutines are only
	// defensive in the pathological case of many trust edits.
	for i := 0; i < 4; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			for block := range blockCh {
				cert, err := ParseCertificate(block.Bytes)
				if err != nil {
					continue
				}
				sha1CapHex := fmt.Sprintf("%X", sha1.Sum(block.Bytes))

				valid := true
				verifyChecks := 0
				if hasPolicy[sha1CapHex] {
					verifyChecks++
					if !verifyCertWithSystem(block, cert) {
						valid = false
					}
				}

				mu.Lock()
				numVerified += verifyChecks
				if valid {
					roots.AddCert(cert)
				}
				mu.Unlock()
			}
		}()
	}
	for len(data) > 0 {
		var block *pem.Block
		block, data = pem.Decode(data)
		if block == nil {
			break
		}
		if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
			continue
		}
		blockCh <- block
	}
	close(blockCh)
	wg.Wait()

	if debugExecDarwinRoots {
		mu.Lock()
		defer mu.Unlock()
		println(fmt.Sprintf("crypto/x509: ran security verify-cert %d times", numVerified))
	}

	return roots, nil
}

func verifyCertWithSystem(block *pem.Block, cert *Certificate) bool {
	data := pem.EncodeToMemory(block)

	f, err := ioutil.TempFile("", "cert")
	if err != nil {
		fmt.Fprintf(os.Stderr, "can't create temporary file for cert: %v", err)
		return false
	}
	defer os.Remove(f.Name())
	if _, err := f.Write(data); err != nil {
		fmt.Fprintf(os.Stderr, "can't write temporary file for cert: %v", err)
		return false
	}
	if err := f.Close(); err != nil {
		fmt.Fprintf(os.Stderr, "can't write temporary file for cert: %v", err)
		return false
	}
	cmd := exec.Command("/usr/bin/security", "verify-cert", "-c", f.Name(), "-l", "-L")
	var stderr bytes.Buffer
	if debugExecDarwinRoots {
		cmd.Stderr = &stderr
	}
	if err := cmd.Run(); err != nil {
		if debugExecDarwinRoots {
			println(fmt.Sprintf("crypto/x509: verify-cert rejected %s: %q", cert.Subject, bytes.TrimSpace(stderr.Bytes())))
		}
		return false
	}
	if debugExecDarwinRoots {
		println(fmt.Sprintf("crypto/x509: verify-cert approved %s", cert.Subject))
	}
	return true
}

// getCertsWithTrustPolicy returns the set of certs that have a
// possibly-altered trust policy. The keys of the map are capitalized
// sha1 hex of the raw cert.
// They are the certs that should be checked against `security
// verify-cert` to see whether the user altered the default trust
// settings. This code is only used for cgo-disabled builds.
func getCertsWithTrustPolicy() (map[string]bool, error) {
	set := map[string]bool{}
	td, err := ioutil.TempDir("", "x509trustpolicy")
	if err != nil {
		return nil, err
	}
	defer os.RemoveAll(td)
	run := func(file string, args ...string) error {
		file = filepath.Join(td, file)
		args = append(args, file)
		cmd := exec.Command("/usr/bin/security", args...)
		var stderr bytes.Buffer
		cmd.Stderr = &stderr
		if err := cmd.Run(); err != nil {
			// If there are no trust settings, the
			// `security trust-settings-export` command
			// fails with:
			//    exit status 1, SecTrustSettingsCreateExternalRepresentation: No Trust Settings were found.
			// Rather than match on English substrings that are probably
			// localized on macOS, just interpret any failure to mean that
			// there are no trust settings.
			if debugExecDarwinRoots {
				println(fmt.Sprintf("crypto/x509: exec %q: %v, %s", cmd.Args, err, stderr.Bytes()))
			}
			return nil
		}

		f, err := os.Open(file)
		if err != nil {
			return err
		}
		defer f.Close()

		// Gather all the runs of 40 capitalized hex characters.
		br := bufio.NewReader(f)
		var hexBuf bytes.Buffer
		for {
			b, err := br.ReadByte()
			isHex := ('A' <= b && b <= 'F') || ('0' <= b && b <= '9')
			if isHex {
				hexBuf.WriteByte(b)
			} else {
				if hexBuf.Len() == 40 {
					set[hexBuf.String()] = true
				}
				hexBuf.Reset()
			}
			if err == io.EOF {
				break
			}
			if err != nil {
				return err
			}
		}

		return nil
	}
	if err := run("user", "trust-settings-export"); err != nil {
		return nil, fmt.Errorf("dump-trust-settings (user): %v", err)
	}
	if err := run("admin", "trust-settings-export", "-d"); err != nil {
		return nil, fmt.Errorf("dump-trust-settings (admin): %v", err)
	}
	return set, nil
}
