PR c++/86342 - -Wdeprecated-copy and system headers.
[official-gcc.git] / libgo / go / crypto / x509 / root_darwin_arm_gen.go
blobb5580d6f02a3b97375e232bd7f5c3e55e8ab60af
1 // Copyright 2015 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // +build ignore
7 // Generates root_darwin_armx.go.
8 //
9 // As of iOS 8, there is no API for querying the system trusted X.509 root
10 // certificates. We could use SecTrustEvaluate to verify that a trust chain
11 // exists for a certificate, but the x509 API requires returning the entire
12 // chain.
14 // Apple publishes the list of trusted root certificates for iOS on
15 // support.apple.com. So we parse the list and extract the certificates from
16 // an OS X machine and embed them into the x509 package.
17 package main
19 import (
20 "bytes"
21 "crypto/sha256"
22 "crypto/x509"
23 "encoding/hex"
24 "encoding/pem"
25 "flag"
26 "fmt"
27 "go/format"
28 "io/ioutil"
29 "log"
30 "net/http"
31 "os/exec"
32 "regexp"
33 "strings"
36 var output = flag.String("output", "root_darwin_armx.go", "file name to write")
38 func main() {
39 certs, err := selectCerts()
40 if err != nil {
41 log.Fatal(err)
44 buf := new(bytes.Buffer)
46 fmt.Fprintf(buf, "// Code generated by root_darwin_arm_gen --output %s; DO NOT EDIT.\n", *output)
47 fmt.Fprintf(buf, "%s", header)
49 fmt.Fprintf(buf, "const systemRootsPEM = `\n")
50 for _, cert := range certs {
51 b := &pem.Block{
52 Type: "CERTIFICATE",
53 Bytes: cert.Raw,
55 if err := pem.Encode(buf, b); err != nil {
56 log.Fatal(err)
59 fmt.Fprintf(buf, "`")
61 source, err := format.Source(buf.Bytes())
62 if err != nil {
63 log.Fatal("source format error:", err)
65 if err := ioutil.WriteFile(*output, source, 0644); err != nil {
66 log.Fatal(err)
70 func selectCerts() ([]*x509.Certificate, error) {
71 ids, err := fetchCertIDs()
72 if err != nil {
73 return nil, err
76 scerts, err := sysCerts()
77 if err != nil {
78 return nil, err
81 var certs []*x509.Certificate
82 for _, id := range ids {
83 if c, ok := scerts[id.fingerprint]; ok {
84 certs = append(certs, c)
85 } else {
86 fmt.Printf("WARNING: cannot find certificate: %s (fingerprint: %s)\n", id.name, id.fingerprint)
89 return certs, nil
92 func sysCerts() (certs map[string]*x509.Certificate, err error) {
93 cmd := exec.Command("/usr/bin/security", "find-certificate", "-a", "-p", "/System/Library/Keychains/SystemRootCertificates.keychain")
94 data, err := cmd.Output()
95 if err != nil {
96 return nil, err
98 certs = make(map[string]*x509.Certificate)
99 for len(data) > 0 {
100 var block *pem.Block
101 block, data = pem.Decode(data)
102 if block == nil {
103 break
105 if block.Type != "CERTIFICATE" || len(block.Headers) != 0 {
106 continue
109 cert, err := x509.ParseCertificate(block.Bytes)
110 if err != nil {
111 continue
114 fingerprint := sha256.Sum256(cert.Raw)
115 certs[hex.EncodeToString(fingerprint[:])] = cert
117 return certs, nil
120 type certID struct {
121 name string
122 fingerprint string
125 // fetchCertIDs fetches IDs of iOS X509 certificates from apple.com.
126 func fetchCertIDs() ([]certID, error) {
127 // Download the iOS 11 support page. The index for all iOS versions is here:
128 // https://support.apple.com/en-us/HT204132
129 resp, err := http.Get("https://support.apple.com/en-us/HT208125")
130 if err != nil {
131 return nil, err
133 defer resp.Body.Close()
134 body, err := ioutil.ReadAll(resp.Body)
135 if err != nil {
136 return nil, err
138 text := string(body)
139 text = text[strings.Index(text, "<div id=trusted"):]
140 text = text[:strings.Index(text, "</div>")]
142 var ids []certID
143 cols := make(map[string]int)
144 for i, rowmatch := range regexp.MustCompile("(?s)<tr>(.*?)</tr>").FindAllStringSubmatch(text, -1) {
145 row := rowmatch[1]
146 if i == 0 {
147 // Parse table header row to extract column names
148 for i, match := range regexp.MustCompile("(?s)<th>(.*?)</th>").FindAllStringSubmatch(row, -1) {
149 cols[match[1]] = i
151 continue
154 values := regexp.MustCompile("(?s)<td>(.*?)</td>").FindAllStringSubmatch(row, -1)
155 name := values[cols["Certificate name"]][1]
156 fingerprint := values[cols["Fingerprint (SHA-256)"]][1]
157 fingerprint = strings.Replace(fingerprint, "<br>", "", -1)
158 fingerprint = strings.Replace(fingerprint, "\n", "", -1)
159 fingerprint = strings.Replace(fingerprint, " ", "", -1)
160 fingerprint = strings.ToLower(fingerprint)
162 ids = append(ids, certID{
163 name: name,
164 fingerprint: fingerprint,
167 return ids, nil
170 const header = `
171 // Copyright 2015 The Go Authors. All rights reserved.
172 // Use of this source code is governed by a BSD-style
173 // license that can be found in the LICENSE file.
175 // +build cgo
176 // +build darwin
177 // +build arm arm64 ios
179 package x509
181 func loadSystemRoots() (*CertPool, error) {
182 p := NewCertPool()
183 p.AppendCertsFromPEM([]byte(systemRootsPEM))
184 return p, nil