mirror of
https://github.com/SagerNet/sing-box.git
synced 2026-04-13 20:28:32 +10:00
159 lines
3.6 KiB
Go
159 lines
3.6 KiB
Go
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)
|
|
}
|