| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- package main
- import (
- "encoding/csv"
- "io"
- "net/http"
- "os"
- "path/filepath"
- "strings"
- "github.com/sagernet/sing-box/log"
- "golang.org/x/exp/slices"
- )
- func main() {
- err := updateMozillaIncludedRootCAs()
- if err != nil {
- log.Error(err)
- }
- err = updateChromeIncludedRootCAs()
- if err != nil {
- log.Error(err)
- }
- }
- func updateMozillaIncludedRootCAs() error {
- response, err := http.Get("https://ccadb.my.salesforce-sites.com/mozilla/IncludedCACertificateReportPEMCSV")
- if err != nil {
- return err
- }
- defer response.Body.Close()
- reader := csv.NewReader(response.Body)
- header, err := reader.Read()
- if err != nil {
- return err
- }
- geoIndex := slices.Index(header, "Geographic Focus")
- certIndex := slices.Index(header, "PEM Info")
- pemBundle := strings.Builder{}
- for {
- record, err := reader.Read()
- if err == io.EOF {
- break
- } else if err != nil {
- return err
- }
- if record[geoIndex] == "China" {
- continue
- }
- cert := record[certIndex]
- cert = cert[1 : len(cert)-1]
- pemBundle.WriteString(cert)
- pemBundle.WriteString("\n")
- }
- return writeGeneratedCertificateBundle("mozilla", "mozillaIncluded", pemBundle.String())
- }
- func fetchChinaFingerprints() (map[string]bool, error) {
- response, err := http.Get("https://ccadb.my.salesforce-sites.com/ccadb/AllCertificateRecordsCSVFormatv4")
- if err != nil {
- return nil, err
- }
- defer response.Body.Close()
- reader := csv.NewReader(response.Body)
- header, err := reader.Read()
- if err != nil {
- return nil, err
- }
- countryIndex := slices.Index(header, "Country")
- fingerprintIndex := slices.Index(header, "SHA-256 Fingerprint")
- chinaFingerprints := make(map[string]bool)
- for {
- record, err := reader.Read()
- if err == io.EOF {
- break
- } else if err != nil {
- return nil, err
- }
- if record[countryIndex] == "China" {
- chinaFingerprints[record[fingerprintIndex]] = true
- }
- }
- return chinaFingerprints, nil
- }
- func updateChromeIncludedRootCAs() error {
- chinaFingerprints, err := fetchChinaFingerprints()
- if err != nil {
- return err
- }
- response, err := http.Get("https://ccadb.my.salesforce-sites.com/ccadb/RootCACertificatesIncludedByRSReportCSV")
- if err != nil {
- return err
- }
- defer response.Body.Close()
- reader := csv.NewReader(response.Body)
- header, err := reader.Read()
- if err != nil {
- return err
- }
- statusIndex := slices.Index(header, "Google Chrome Status")
- certIndex := slices.Index(header, "X.509 Certificate (PEM)")
- fingerprintIndex := slices.Index(header, "SHA-256 Fingerprint")
- pemBundle := strings.Builder{}
- for {
- record, err := reader.Read()
- if err == io.EOF {
- break
- } else if err != nil {
- return err
- }
- if record[statusIndex] != "Included" {
- continue
- }
- if chinaFingerprints[record[fingerprintIndex]] {
- continue
- }
- cert := record[certIndex]
- if len(cert) > 0 && cert[0] == '\'' {
- cert = cert[1 : len(cert)-1]
- }
- pemBundle.WriteString(cert)
- pemBundle.WriteString("\n")
- }
- return writeGeneratedCertificateBundle("chrome", "chromeIncluded", pemBundle.String())
- }
- func writeGeneratedCertificateBundle(name string, variableName string, pemBundle string) error {
- goSource := `// Code generated by 'make update_certificates'. DO NOT EDIT.
- package certificate
- import (
- "crypto/x509"
- _ "embed"
- )
- //go:embed ` + name + `.pem
- var ` + variableName + `PEM string
- var ` + variableName + ` *x509.CertPool
- func init() {
- ` + variableName + ` = x509.NewCertPool()
- ` + variableName + `.AppendCertsFromPEM([]byte(` + variableName + `PEM))
- }
- `
- err := os.WriteFile(filepath.Join("common/certificate", name+".pem"), []byte(pemBundle), 0o644)
- if err != nil {
- return err
- }
- return os.WriteFile(filepath.Join("common/certificate", name+".go"), []byte(goSource), 0o644)
- }
|