diff options
author | Cherry Zhang <cherryyz@google.com> | 2020-10-28 09:12:20 -0400 |
---|---|---|
committer | Cherry Zhang <cherryyz@google.com> | 2020-10-28 09:12:20 -0400 |
commit | a16e30d162c1c7408db7821e7b9513cefa09c6ca (patch) | |
tree | af752ba9ba44c547df39bb0af9bff79f610ba9d5 /src/crypto/x509/root_ios_gen.go | |
parent | 91e4d2d57bc341dd82c98247117114c851380aef (diff) | |
parent | cf6cfba4d5358404dd890f6025e573a4b2156543 (diff) | |
download | go-git-dev.link.tar.gz |
[dev.link] all: merge branch 'master' into dev.linkdev.link
Clean merge.
Change-Id: Ia7b2808bc649790198d34c226a61d9e569084dc5
Diffstat (limited to 'src/crypto/x509/root_ios_gen.go')
-rw-r--r-- | src/crypto/x509/root_ios_gen.go | 179 |
1 files changed, 179 insertions, 0 deletions
diff --git a/src/crypto/x509/root_ios_gen.go b/src/crypto/x509/root_ios_gen.go new file mode 100644 index 0000000000..0641c073ea --- /dev/null +++ b/src/crypto/x509/root_ios_gen.go @@ -0,0 +1,179 @@ +// Copyright 2015 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. + +// +build ignore + +// Generates root_ios.go. +// +// As of iOS 13, there is no API for querying the system trusted X.509 root +// certificates. +// +// Apple publishes the trusted root certificates for iOS and macOS on +// opensource.apple.com so we embed them into the x509 package. +// +// Note that this ignores distrusted and revoked certificates. +package main + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "crypto/sha256" + "crypto/tls" + "crypto/x509" + "encoding/pem" + "flag" + "fmt" + "go/format" + "io" + "io/ioutil" + "log" + "net/http" + "path" + "sort" + "strings" + "time" +) + +func main() { + var output = flag.String("output", "root_ios.go", "file name to write") + var version = flag.String("version", "", "security_certificates version") + flag.Parse() + if *version == "" { + log.Fatal("Select the latest security_certificates version from " + + "https://opensource.apple.com/source/security_certificates/") + } + + url := "https://opensource.apple.com/tarballs/security_certificates/security_certificates-%s.tar.gz" + hc := &http.Client{Timeout: 1 * time.Minute} + resp, err := hc.Get(fmt.Sprintf(url, *version)) + if err != nil { + log.Fatal(err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + log.Fatalf("HTTP status not OK: %s", resp.Status) + } + + zr, err := gzip.NewReader(resp.Body) + if err != nil { + log.Fatal(err) + } + defer zr.Close() + + var certs []*x509.Certificate + pool := x509.NewCertPool() + + tr := tar.NewReader(zr) + for { + hdr, err := tr.Next() + if err == io.EOF { + break + } + if err != nil { + log.Fatal(err) + } + + rootsDirectory := fmt.Sprintf("security_certificates-%s/certificates/roots/", *version) + if dir, file := path.Split(hdr.Name); hdr.Typeflag != tar.TypeReg || + dir != rootsDirectory || strings.HasPrefix(file, ".") { + continue + } + + der, err := io.ReadAll(tr) + if err != nil { + log.Fatal(err) + } + + c, err := x509.ParseCertificate(der) + if err != nil { + log.Printf("Failed to parse certificate %q: %v", hdr.Name, err) + continue + } + + certs = append(certs, c) + pool.AddCert(c) + } + + // Quick smoke test to check the pool is well formed, and that we didn't end + // up trusting roots in the removed folder. + for _, c := range certs { + if c.Subject.CommonName == "Symantec Class 2 Public Primary Certification Authority - G4" { + log.Fatal("The pool includes a removed root!") + } + } + conn, err := tls.Dial("tcp", "mail.google.com:443", &tls.Config{ + RootCAs: pool, + }) + if err != nil { + log.Fatal(err) + } + conn.Close() + + certName := func(c *x509.Certificate) string { + if c.Subject.CommonName != "" { + return c.Subject.CommonName + } + if len(c.Subject.OrganizationalUnit) > 0 { + return c.Subject.OrganizationalUnit[0] + } + return c.Subject.Organization[0] + } + sort.Slice(certs, func(i, j int) bool { + if strings.ToLower(certName(certs[i])) != strings.ToLower(certName(certs[j])) { + return strings.ToLower(certName(certs[i])) < strings.ToLower(certName(certs[j])) + } + return certs[i].NotBefore.Before(certs[j].NotBefore) + }) + + out := new(bytes.Buffer) + fmt.Fprintf(out, header, *version) + fmt.Fprintf(out, "const systemRootsPEM = `\n") + + for _, c := range certs { + fmt.Fprintf(out, "# %q\n", certName(c)) + h := sha256.Sum256(c.Raw) + fmt.Fprintf(out, "# % X\n", h[:len(h)/2]) + fmt.Fprintf(out, "# % X\n", h[len(h)/2:]) + b := &pem.Block{ + Type: "CERTIFICATE", + Bytes: c.Raw, + } + if err := pem.Encode(out, b); err != nil { + log.Fatal(err) + } + } + + fmt.Fprintf(out, "`") + + source, err := format.Source(out.Bytes()) + if err != nil { + log.Fatal(err) + } + if err := ioutil.WriteFile(*output, source, 0644); err != nil { + log.Fatal(err) + } +} + +const header = `// Code generated by root_ios_gen.go -version %s; DO NOT EDIT. +// Update the version in root.go and regenerate with "go generate". + +// +build ios +// +build !x509omitbundledroots + +package x509 + +func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { + return nil, nil +} + +// loadSystemRootsWithCgo is not available on iOS. +var loadSystemRootsWithCgo func() (*CertPool, error) + +func loadSystemRoots() (*CertPool, error) { + p := NewCertPool() + p.AppendCertsFromPEM([]byte(systemRootsPEM)) + return p, nil +} +` |