// 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.

//go:build ignore
// +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"
	"log"
	"net/http"
	"os"
	"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 := os.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
}
`
