x509roots/fallback: store bundle certs directly in DER
goos: linux
goarch: amd64
pkg: golang.org/x/crypto/x509roots/fallback
cpu: AMD Ryzen 5 4600G with Radeon Graphics
│ /tmp/before │ /tmp/after │
│ sec/op │ sec/op vs base │
InitTime-12 1.726m ± 0% 1.101m ± 1% -36.20% (p=0.000 n=30)
│ /tmp/before │ /tmp/after │
│ B/op │ B/op vs base │
InitTime-12 1178.2Ki ± 0% 779.8Ki ± 0% -33.81% (p=0.000 n=30)
│ /tmp/before │ /tmp/after │
│ allocs/op │ allocs/op vs base │
InitTime-12 11.35k ± 0% 10.64k ± 0% -6.32% (p=0.000 n=30)
Updates golang/go#73691
Change-Id: Ic33f2fdfc65001c41afeb3b6af8a383288d10de6
Reviewed-on: https://go-review.googlesource.com/c/crypto/+/676217
Reviewed-by: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Mark Freeman <mark@golang.org>
This commit is contained in:
committed by
Sean Liao
parent
1fda73153f
commit
c247dead11
Binary file not shown.
+750
-4189
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
package fallback
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"crypto/x509"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBundle(t *testing.T) {
|
||||
for i, unparsed := range unparsedCertificates {
|
||||
cert, err := x509.ParseCertificate(rawCerts[unparsed.certStartOff : unparsed.certStartOff+unparsed.certLength])
|
||||
if err != nil {
|
||||
t.Errorf("ParseCertificate(unparsedCertificates[%v]) unexpected error: %v", i, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if unparsed.cn != cert.Subject.String() {
|
||||
t.Errorf("unparsedCertificates[%v].cn = %q; want = %q", i, unparsed.cn, cert.Subject.String())
|
||||
}
|
||||
|
||||
sum := sha256.Sum256(cert.Raw)
|
||||
sumHex := hex.EncodeToString(sum[:])
|
||||
if sumHex != unparsed.sha256Hash {
|
||||
t.Errorf("unparsedCertificates[%v].sha256Hash = %q; want = %q", i, unparsed.sha256Hash, sumHex)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,11 +20,14 @@ package fallback
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
//go:embed bundle.der
|
||||
var rawCerts []byte
|
||||
|
||||
func init() {
|
||||
x509.SetFallbackRoots(newFallbackCertPool())
|
||||
}
|
||||
@@ -49,9 +52,10 @@ func newFallbackCertPool() *x509.CertPool {
|
||||
}
|
||||
|
||||
type unparsedCertificate struct {
|
||||
cn string
|
||||
sha256Hash string
|
||||
pem string
|
||||
cn string
|
||||
sha256Hash string
|
||||
certStartOff int
|
||||
certLength int
|
||||
|
||||
// possible constraints
|
||||
distrustAfter string
|
||||
@@ -63,19 +67,9 @@ type parsedCertificate struct {
|
||||
}
|
||||
|
||||
func mustParse(unparsedCerts []unparsedCertificate) []parsedCertificate {
|
||||
var b []parsedCertificate
|
||||
b := make([]parsedCertificate, 0, len(unparsedCerts))
|
||||
for _, unparsed := range unparsedCerts {
|
||||
block, rest := pem.Decode([]byte(unparsed.pem))
|
||||
if block == nil {
|
||||
panic(fmt.Sprintf("unexpected nil PEM block for %q", unparsed.cn))
|
||||
}
|
||||
if len(rest) != 0 {
|
||||
panic(fmt.Sprintf("unexpected trailing data in PEM for %q", unparsed.cn))
|
||||
}
|
||||
if block.Type != "CERTIFICATE" {
|
||||
panic(fmt.Sprintf("unexpected PEM block type for %q: %s", unparsed.cn, block.Type))
|
||||
}
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
cert, err := x509.ParseCertificate(rawCerts[unparsed.certStartOff : unparsed.certStartOff+unparsed.certLength])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/pem"
|
||||
"flag"
|
||||
"fmt"
|
||||
"go/format"
|
||||
@@ -37,6 +36,7 @@ var (
|
||||
certDataURL = flag.String("certdata-url", "https://hg.mozilla.org/mozilla-central/raw-file/tip/security/nss/lib/ckfw/builtins/certdata.txt", "URL to the raw certdata.txt file to parse (certdata-path overrides this, if provided)")
|
||||
certDataPath = flag.String("certdata-path", "", "Path to the NSS certdata.txt file to parse (this overrides certdata-url, if provided)")
|
||||
output = flag.String("output", "fallback/bundle.go", "Path to file to write output to")
|
||||
derOutput = flag.String("deroutput", "fallback/bundle.der", "Path to file to write output to (DER certificate bundle)")
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -92,8 +92,9 @@ func main() {
|
||||
return subjI < subjJ
|
||||
})
|
||||
|
||||
b := new(bytes.Buffer)
|
||||
b.WriteString(tmpl)
|
||||
rawCertsData := new(bytes.Buffer)
|
||||
goSrcOut := new(bytes.Buffer)
|
||||
goSrcOut.WriteString(tmpl)
|
||||
for _, c := range certs {
|
||||
var constraints []string
|
||||
var skip bool
|
||||
@@ -110,19 +111,24 @@ func main() {
|
||||
if skip {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(b, "{\ncn: %q,\nsha256Hash: \"%x\",\npem: `%s`,\n",
|
||||
|
||||
off := rawCertsData.Len()
|
||||
rawCertsData.Write(c.X509.Raw)
|
||||
|
||||
fmt.Fprintf(goSrcOut, "{\ncn: %q,\nsha256Hash: \"%x\",\ncertStartOff: %v,\ncertLength: %v,\n",
|
||||
c.X509.Subject.String(),
|
||||
sha256.Sum256(c.X509.Raw),
|
||||
string(pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: c.X509.Raw})),
|
||||
off,
|
||||
len(c.X509.Raw),
|
||||
)
|
||||
for _, constraint := range constraints {
|
||||
fmt.Fprintln(b, constraint)
|
||||
fmt.Fprintln(goSrcOut, constraint)
|
||||
}
|
||||
fmt.Fprintln(b, "},")
|
||||
fmt.Fprintln(goSrcOut, "},")
|
||||
}
|
||||
fmt.Fprintln(b, "}")
|
||||
fmt.Fprintln(goSrcOut, "}")
|
||||
|
||||
formatted, err := format.Source(b.Bytes())
|
||||
formatted, err := format.Source(goSrcOut.Bytes())
|
||||
if err != nil {
|
||||
log.Fatalf("failed to format source: %s", err)
|
||||
}
|
||||
@@ -130,4 +136,8 @@ func main() {
|
||||
if err := os.WriteFile(*output, formatted, 0644); err != nil {
|
||||
log.Fatalf("failed to write to %q: %s", *output, err)
|
||||
}
|
||||
|
||||
if err := os.WriteFile(*derOutput, rawCertsData.Bytes(), 0644); err != nil {
|
||||
log.Fatalf("failed to write to %q: %s", *output, err)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user