// 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]))
		}
		if !certs[i].NotBefore.Equal(certs[j].NotBefore) {
			return certs[i].NotBefore.Before(certs[j].NotBefore)
		}
		fi, fj := sha256.Sum256(certs[i].Raw), sha256.Sum256(certs[j].Raw)
		return bytes.Compare(fi[:], fj[:]) < 0
	})

	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
}

func loadSystemRoots() (*CertPool, error) {
	p := NewCertPool()
	p.AppendCertsFromPEM([]byte(systemRootsPEM))
	return p, nil
}
`
