summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-11 18:56:44 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-11 18:56:44 +0000
commit7f82d4bb6f981a3149ba9f79b51fd5fd7e9b77a8 (patch)
tree030b59d231331d5a4319534224a77232fbb99e9a /net
parente13e2b7514ba4be99aaf6ae415f03cf4dcb9cb2d (diff)
downloadchromium_src-7f82d4bb6f981a3149ba9f79b51fd5fd7e9b77a8.zip
chromium_src-7f82d4bb6f981a3149ba9f79b51fd5fd7e9b77a8.tar.gz
chromium_src-7f82d4bb6f981a3149ba9f79b51fd5fd7e9b77a8.tar.bz2
Move tools out of Chromium repo
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@156081 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/base/ssl_cipher_suite_names_generate.go189
-rw-r--r--net/base/transport_security_state_static_generate.go586
2 files changed, 0 insertions, 775 deletions
diff --git a/net/base/ssl_cipher_suite_names_generate.go b/net/base/ssl_cipher_suite_names_generate.go
deleted file mode 100644
index 6366c1f..0000000
--- a/net/base/ssl_cipher_suite_names_generate.go
+++ /dev/null
@@ -1,189 +0,0 @@
-// This program reads in the contents of [1] from /tmp/tls-parameters.xml and
-// writes out a compact form the ciphersuite information found there in.
-// It's used to generate the tables in net/base/ssl_cipher_suite_names.cc
-//
-// [1] http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
-package main
-
-import (
- "encoding/xml"
- "fmt"
- "os"
- "sort"
- "strings"
-)
-
-// Structures for parsing the XML
-
-type TLSRegistry struct {
- Registry []Registry `xml:"registry"`
-}
-
-type Registry struct {
- Id string `xml:"id,attr"`
- Title string `xml:"title"`
- Record []Record `xml:"record"`
-}
-
-type Record struct {
- Value string `xml:"value"`
- Description string `xml:"description"`
-}
-
-type CipherSuite struct {
- value uint16
- kx string
- cipher string
- mac string
-}
-
-func fromHex(c byte) int {
- if c >= '0' && c <= '9' {
- return int(c - '0')
- }
- if c >= 'a' && c <= 'f' {
- return int(c - 'a' + 10)
- }
- if c >= 'A' && c <= 'F' {
- return int(c - 'A' + 10)
- }
- panic("Bad char passed to fromHex")
-}
-
-type TLSValue struct {
- v int
- name string
-}
-
-type TLSMapping []TLSValue
-
-func (m TLSMapping) Len() int {
- return len(m)
-}
-
-func (m TLSMapping) Less(i, j int) bool {
- return m[i].v < m[j].v
-}
-
-func (m TLSMapping) Swap(i, j int) {
- m[i], m[j] = m[j], m[i]
-}
-
-func printDict(d map[string]int, name string) {
- a := make([]TLSValue, len(d))
-
- maxLen := 0
- i := 0
- for k, v := range d {
- if len(k) > maxLen {
- maxLen = len(k)
- }
- a[i].v = v
- a[i].name = k
- i++
- }
-
- sort.Sort(TLSMapping(a))
-
- fmt.Printf("static const struct {\n char name[%d];\n} %s[%d] = {\n", maxLen+1, name, len(d))
- for _, m := range a {
- fmt.Printf(" {\"%s\"}, // %d\n", m.name, m.v)
- }
-
- fmt.Printf("};\n\n")
-}
-
-func parseCipherSuiteString(s string) (kx, cipher, mac string) {
- s = s[4:]
- i := strings.Index(s, "_WITH_")
- kx = s[0:i]
- s = s[i+6:]
- i = strings.LastIndex(s, "_")
- cipher = s[0:i]
- mac = s[i+1:]
- return
-}
-
-func main() {
- infile, err := os.Open("/tmp/tls-parameters.xml")
- if err != nil {
- fmt.Printf("Cannot open input: %s\n", err)
- return
- }
-
- var input TLSRegistry
- err = xml.NewDecoder(infile).Decode(&input)
- if err != nil {
- fmt.Printf("Error parsing XML: %s\n", err)
- return
- }
-
- var cipherSuitesRegistry *Registry
- for _, r := range input.Registry {
- if r.Id == "tls-parameters-4" {
- cipherSuitesRegistry = &r
- break
- }
- }
-
- if cipherSuitesRegistry == nil {
- fmt.Printf("Didn't find tls-parameters-4 registry\n")
- }
-
- kxs := make(map[string]int)
- next_kx := 0
- ciphers := make(map[string]int)
- next_cipher := 0
- macs := make(map[string]int)
- next_mac := 0
- lastValue := uint16(0)
-
- fmt.Printf("struct CipherSuite {\n uint16 cipher_suite, encoded;\n};\n\n")
- fmt.Printf("static const struct CipherSuite kCipherSuites[] = {\n")
-
- for _, r := range cipherSuitesRegistry.Record {
- if strings.Index(r.Description, "_WITH_") == -1 {
- continue
- }
-
- value := uint16(fromHex(r.Value[2])<<12 | fromHex(r.Value[3])<<8 | fromHex(r.Value[7])<<4 | fromHex(r.Value[8]))
- kx, cipher, mac := parseCipherSuiteString(r.Description)
-
- if value < lastValue {
- panic("Input isn't sorted")
- }
- lastValue = value
-
- var kx_n, cipher_n, mac_n int
- var ok bool
-
- if kx_n, ok = kxs[kx]; !ok {
- kxs[kx] = next_kx
- kx_n = next_kx
- next_kx++
- }
- if cipher_n, ok = ciphers[cipher]; !ok {
- ciphers[cipher] = next_cipher
- cipher_n = next_cipher
- next_cipher++
- }
- if mac_n, ok = macs[mac]; !ok {
- macs[mac] = next_mac
- mac_n = next_mac
- next_mac++
- }
-
- if kx_n > 32 || cipher_n > 15 || mac_n > 7 {
- panic("Need to shift bit boundaries")
- }
-
- encoded := (kx_n << 7) | (cipher_n << 3) | mac_n
- fmt.Printf(" {0x%x, 0x%x}, // %s\n", value, encoded, r.Description)
- }
-
- fmt.Printf("};\n\n")
-
- printDict(kxs, "kKeyExchangeNames")
- printDict(ciphers, "kCipherNames")
- printDict(macs, "kMacNames")
-}
diff --git a/net/base/transport_security_state_static_generate.go b/net/base/transport_security_state_static_generate.go
deleted file mode 100644
index cb2154f..0000000
--- a/net/base/transport_security_state_static_generate.go
+++ /dev/null
@@ -1,586 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This program converts the information in
-// transport_security_state_static.json and
-// transport_security_state_static.certs into
-// transport_security_state_static.h. The input files contain information about
-// public key pinning and HTTPS-only sites that is compiled into Chromium.
-
-// Run as:
-// % go run transport_security_state_static_generate.go transport_security_state_static.json transport_security_state_static.certs
-//
-// It will write transport_security_state_static.h
-
-package main
-
-import (
- "bufio"
- "bytes"
- "crypto/sha1"
- "crypto/x509"
- "encoding/base64"
- "encoding/json"
- "encoding/pem"
- "errors"
- "fmt"
- "io"
- "os"
- "regexp"
- "strings"
-)
-
-// A pin represents an entry in transport_security_state_static.certs. It's a
-// name associated with a SubjectPublicKeyInfo hash and, optionally, a
-// certificate.
-type pin struct {
- name string
- cert *x509.Certificate
- spkiHash []byte
- spkiHashFunc string // i.e. "sha1"
-}
-
-// preloaded represents the information contained in the
-// transport_security_state_static.json file. This structure and the two
-// following are used by the "json" package to parse the file. See the comments
-// in transport_security_state_static.json for details.
-type preloaded struct {
- Pinsets []pinset `json:"pinsets"`
- Entries []hsts `json:"entries"`
-}
-
-type pinset struct {
- Name string `json:"name"`
- Include []string `json:"static_spki_hashes"`
- Exclude []string `json:"bad_static_spki_hashes"`
-}
-
-type hsts struct {
- Name string `json:"name"`
- Subdomains bool `json:"include_subdomains"`
- Mode string `json:"mode"`
- Pins string `json:"pins"`
- SNIOnly bool `json:"snionly"`
-}
-
-func main() {
- if len(os.Args) != 3 {
- fmt.Fprintf(os.Stderr, "Usage: %s <json file> <certificates file>\n", os.Args[0])
- os.Exit(1)
- }
-
- if err := process(os.Args[1], os.Args[2]); err != nil {
- fmt.Fprintf(os.Stderr, "Conversion failed: %s\n", err.Error())
- os.Exit(1)
- }
-}
-
-func process(jsonFileName, certsFileName string) error {
- jsonFile, err := os.Open(jsonFileName)
- if err != nil {
- return fmt.Errorf("failed to open input file: %s\n", err.Error())
- }
- defer jsonFile.Close()
-
- jsonBytes, err := removeComments(jsonFile)
- if err != nil {
- return fmt.Errorf("failed to remove comments from JSON: %s\n", err.Error())
- }
-
- var preloaded preloaded
- if err := json.Unmarshal(jsonBytes, &preloaded); err != nil {
- return fmt.Errorf("failed to parse JSON: %s\n", err.Error())
- }
-
- certsFile, err := os.Open(certsFileName)
- if err != nil {
- return fmt.Errorf("failed to open input file: %s\n", err.Error())
- }
- defer certsFile.Close()
-
- pins, err := parseCertsFile(certsFile)
- if err != nil {
- return fmt.Errorf("failed to parse certificates file: %s\n", err)
- }
-
- if err := checkDuplicatePins(pins); err != nil {
- return err
- }
-
- if err := checkCertsInPinsets(preloaded.Pinsets, pins); err != nil {
- return err
- }
-
- if err := checkNoopEntries(preloaded.Entries); err != nil {
- return err
- }
-
- if err := checkDuplicateEntries(preloaded.Entries); err != nil {
- return err
- }
-
- outFile, err := os.OpenFile("transport_security_state_static.h", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0644)
- if err != nil {
- return err
- }
- defer outFile.Close()
-
- out := bufio.NewWriter(outFile)
- writeHeader(out)
- writeCertsOutput(out, pins)
- writeHSTSOutput(out, preloaded)
- writeFooter(out)
- out.Flush()
-
- return nil
-}
-
-var newLine = []byte("\n")
-var startOfCert = []byte("-----BEGIN CERTIFICATE")
-var endOfCert = []byte("-----END CERTIFICATE")
-var startOfSHA1 = []byte("sha1/")
-
-// nameRegexp matches valid pin names: an uppercase letter followed by zero or
-// more letters and digits.
-var nameRegexp = regexp.MustCompile("[A-Z][a-zA-Z0-9_]*")
-
-// commentRegexp matches lines that optionally start with whitespace
-// followed by "//".
-var commentRegexp = regexp.MustCompile("^[ \t]*//")
-
-// removeComments reads the contents of |r| and removes any lines beginning
-// with optional whitespace followed by "//"
-func removeComments(r io.Reader) ([]byte, error) {
- var buf bytes.Buffer
- in := bufio.NewReader(r)
-
- for {
- line, isPrefix, err := in.ReadLine()
- if isPrefix {
- return nil, errors.New("line too long in JSON")
- }
- if err == io.EOF {
- break
- }
- if err != nil {
- return nil, err
- }
- if commentRegexp.Match(line) {
- continue
- }
- buf.Write(line)
- buf.Write(newLine)
- }
-
- return buf.Bytes(), nil
-}
-
-// parseCertsFile parses |inFile|, in the format of
-// transport_security_state_static.certs. See the comments at the top of that
-// file for details of the format.
-func parseCertsFile(inFile io.Reader) ([]pin, error) {
- const (
- PRENAME = iota
- POSTNAME = iota
- INCERT = iota
- )
-
- in := bufio.NewReader(inFile)
-
- lineNo := 0
- var pemCert []byte
- state := PRENAME
- var name string
- var pins []pin
-
- for {
- lineNo++
- line, isPrefix, err := in.ReadLine()
- if isPrefix {
- return nil, fmt.Errorf("line %d is too long to process\n", lineNo)
- }
- if err == io.EOF {
- break
- }
- if err != nil {
- return nil, fmt.Errorf("error reading from input: %s\n", err.Error())
- }
-
- if len(line) == 0 || line[0] == '#' {
- continue
- }
-
- switch state {
- case PRENAME:
- name = string(line)
- if !nameRegexp.MatchString(name) {
- return nil, fmt.Errorf("invalid name on line %d\n", lineNo)
- }
- state = POSTNAME
- case POSTNAME:
- switch {
- case bytes.HasPrefix(line, startOfSHA1):
- hash, err := base64.StdEncoding.DecodeString(string(line[len(startOfSHA1):]))
- if err != nil {
- return nil, fmt.Errorf("failed to decode hash on line %d: %s\n", lineNo, err)
- }
- if len(hash) != 20 {
- return nil, fmt.Errorf("bad SHA1 hash length on line %d: %s\n", lineNo, err)
- }
- pins = append(pins, pin{
- name: name,
- spkiHashFunc: "sha1",
- spkiHash: hash,
- })
- state = PRENAME
- continue
- case bytes.HasPrefix(line, startOfCert):
- pemCert = pemCert[:0]
- pemCert = append(pemCert, line...)
- pemCert = append(pemCert, '\n')
- state = INCERT
- default:
- return nil, fmt.Errorf("line %d, after a name, is not a hash nor a certificate\n", lineNo)
- }
- case INCERT:
- pemCert = append(pemCert, line...)
- pemCert = append(pemCert, '\n')
- if !bytes.HasPrefix(line, endOfCert) {
- continue
- }
-
- block, _ := pem.Decode(pemCert)
- if block == nil {
- return nil, fmt.Errorf("failed to decode certificate ending on line %d\n", lineNo)
- }
- cert, err := x509.ParseCertificate(block.Bytes)
- if err != nil {
- return nil, fmt.Errorf("failed to parse certificate ending on line %d: %s\n", lineNo, err.Error())
- }
- certName := cert.Subject.CommonName
- if len(certName) == 0 {
- certName = cert.Subject.Organization[0] + " " + cert.Subject.OrganizationalUnit[0]
- }
- if err := matchNames(certName, name); err != nil {
- return nil, fmt.Errorf("name failure on line %d: %s\n%s -> %s\n", lineNo, err, certName, name)
- }
- h := sha1.New()
- h.Write(cert.RawSubjectPublicKeyInfo)
- pins = append(pins, pin{
- name: name,
- cert: cert,
- spkiHashFunc: "sha1",
- spkiHash: h.Sum(nil),
- })
- state = PRENAME
- }
- }
-
- return pins, nil
-}
-
-// matchNames returns true if the given pin name is a reasonable match for the
-// given CN.
-func matchNames(name, v string) error {
- words := strings.Split(name, " ")
- if len(words) == 0 {
- return errors.New("no words in certificate name")
- }
- firstWord := words[0]
- if strings.HasSuffix(firstWord, ",") {
- firstWord = firstWord[:len(firstWord)-1]
- }
- if strings.HasPrefix(firstWord, "*.") {
- firstWord = firstWord[2:]
- }
- if pos := strings.Index(firstWord, "."); pos != -1 {
- firstWord = firstWord[:pos]
- }
- if pos := strings.Index(firstWord, "-"); pos != -1 {
- firstWord = firstWord[:pos]
- }
- if len(firstWord) == 0 {
- return errors.New("first word of certificate name is empty")
- }
- firstWord = strings.ToLower(firstWord)
- lowerV := strings.ToLower(v)
- if !strings.HasPrefix(lowerV, firstWord) {
- return errors.New("the first word of the certificate name isn't a prefix of the variable name")
- }
-
- for i, word := range words {
- if word == "Class" && i+1 < len(words) {
- if strings.Index(v, word+words[i+1]) == -1 {
- return errors.New("class specification doesn't appear in the variable name")
- }
- } else if len(word) == 1 && word[0] >= '0' && word[0] <= '9' {
- if strings.Index(v, word) == -1 {
- return errors.New("number doesn't appear in the variable name")
- }
- } else if isImportantWordInCertificateName(word) {
- if strings.Index(v, word) == -1 {
- return errors.New(word + " doesn't appear in the variable name")
- }
- }
- }
-
- return nil
-}
-
-// isImportantWordInCertificateName returns true if w must be found in any
-// corresponding variable name.
-func isImportantWordInCertificateName(w string) bool {
- switch w {
- case "Universal", "Global", "EV", "G1", "G2", "G3", "G4", "G5":
- return true
- }
- return false
-}
-
-// checkDuplicatePins returns an error if any pins have the same name or the same hash.
-func checkDuplicatePins(pins []pin) error {
- seenNames := make(map[string]bool)
- seenHashes := make(map[string]string)
-
- for _, pin := range pins {
- if _, ok := seenNames[pin.name]; ok {
- return fmt.Errorf("duplicate name: %s", pin.name)
- }
- seenNames[pin.name] = true
-
- strHash := string(pin.spkiHash)
- if otherName, ok := seenHashes[strHash]; ok {
- return fmt.Errorf("duplicate hash for %s and %s", pin.name, otherName)
- }
- seenHashes[strHash] = pin.name
- }
-
- return nil
-}
-
-// checkCertsInPinsets returns an error if
-// a) unknown pins are mentioned in |pinsets|
-// b) unused pins are given in |pins|
-// c) a pinset name is used twice
-func checkCertsInPinsets(pinsets []pinset, pins []pin) error {
- pinNames := make(map[string]bool)
- for _, pin := range pins {
- pinNames[pin.name] = true
- }
-
- usedPinNames := make(map[string]bool)
- pinsetNames := make(map[string]bool)
-
- for _, pinset := range pinsets {
- if _, ok := pinsetNames[pinset.Name]; ok {
- return fmt.Errorf("duplicate pinset name: %s", pinset.Name)
- }
- pinsetNames[pinset.Name] = true
-
- var allPinNames []string
- allPinNames = append(allPinNames, pinset.Include...)
- allPinNames = append(allPinNames, pinset.Exclude...)
-
- for _, pinName := range allPinNames {
- if _, ok := pinNames[pinName]; !ok {
- return fmt.Errorf("unknown pin: %s", pinName)
- }
- usedPinNames[pinName] = true
- }
- }
-
- for pinName := range pinNames {
- if _, ok := usedPinNames[pinName]; !ok {
- return fmt.Errorf("unused pin: %s", pinName)
- }
- }
-
- return nil
-}
-
-func checkNoopEntries(entries []hsts) error {
- for _, e := range entries {
- if len(e.Mode) == 0 && len(e.Pins) == 0 {
- switch e.Name {
- // This entry is deliberately used as an exclusion.
- case "learn.doubleclick.net":
- continue
- default:
- return errors.New("Entry for " + e.Name + " has no mode and no pins")
- }
- }
- }
-
- return nil
-}
-
-func checkDuplicateEntries(entries []hsts) error {
- seen := make(map[string]bool)
-
- for _, e := range entries {
- if _, ok := seen[e.Name]; ok {
- return errors.New("Duplicate entry for " + e.Name)
- }
- seen[e.Name] = true
- }
-
- return nil
-}
-
-func writeHeader(out *bufio.Writer) {
- out.WriteString(`// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is automatically generated by transport_security_state_static_generate.go
-
-#ifndef NET_BASE_TRANSPORT_SECURITY_STATE_STATIC_H_
-#define NET_BASE_TRANSPORT_SECURITY_STATE_STATIC_H_
-
-`)
-
-}
-
-func writeFooter(out *bufio.Writer) {
- out.WriteString("#endif // NET_BASE_TRANSPORT_SECURITY_STATE_STATIC_H_\n")
-}
-
-func writeCertsOutput(out *bufio.Writer, pins []pin) {
- out.WriteString(`// These are SubjectPublicKeyInfo hashes for public key pinning. The
-// hashes are base64 encoded, SHA1 digests.
-
-`)
-
- for _, pin := range pins {
- fmt.Fprintf(out, "static const char kSPKIHash_%s[] =\n", pin.name)
- fmt.Fprintf(out, " \"%s/%s\";\n\n", pin.spkiHashFunc, base64.StdEncoding.EncodeToString(pin.spkiHash))
- }
-}
-
-// uppercaseFirstLetter returns s with the first letter uppercased.
-func uppercaseFirstLetter(s string) string {
- // We need to find the index of the second code-point, which may not be
- // one.
- for i := range s {
- if i == 0 {
- continue
- }
- return strings.ToUpper(s[:i]) + s[i:]
- }
- return strings.ToUpper(s)
-}
-
-func writeListOfPins(w io.Writer, name string, pinNames []string) {
- fmt.Fprintf(w, "static const char* const %s[] = {\n", name)
- for _, pinName := range pinNames {
- fmt.Fprintf(w, " kSPKIHash_%s,\n", pinName)
- }
- fmt.Fprintf(w, " NULL,\n};\n")
-}
-
-// toDNS returns a string converts the domain name |s| into C-escaped,
-// length-prefixed form and also returns the length of the interpreted string.
-// i.e. for an input "example.com" it will return "\\007example\\003com", 13.
-func toDNS(s string) (string, int) {
- labels := strings.Split(s, ".")
-
- var name string
- var l int
- for _, label := range labels {
- if len(label) > 63 {
- panic("DNS label too long")
- }
- name += fmt.Sprintf("\\%03o", len(label))
- name += label
- l += len(label) + 1
- }
- l += 1 // For the length of the root label.
-
- return name, l
-}
-
-// domainConstant converts the domain name |s| into a string of the form
-// "DOMAIN_" + uppercase last two labels.
-func domainConstant(s string) string {
- labels := strings.Split(s, ".")
- gtld := strings.ToUpper(labels[len(labels)-1])
- domain := strings.Replace(strings.ToUpper(labels[len(labels)-2]), "-", "_", -1)
-
- return fmt.Sprintf("DOMAIN_%s_%s", domain, gtld)
-}
-
-func writeHSTSEntry(out *bufio.Writer, entry hsts) {
- dnsName, dnsLen := toDNS(entry.Name)
- domain := "DOMAIN_NOT_PINNED"
- pinsetName := "kNoPins"
- if len(entry.Pins) > 0 {
- pinsetName = fmt.Sprintf("k%sPins", uppercaseFirstLetter(entry.Pins))
- domain = domainConstant(entry.Name)
- }
- fmt.Fprintf(out, " {%d, %t, \"%s\", %t, %s, %s },\n", dnsLen, entry.Subdomains, dnsName, entry.Mode == "force-https", pinsetName, domain)
-}
-
-func writeHSTSOutput(out *bufio.Writer, hsts preloaded) error {
- out.WriteString(`// The following is static data describing the hosts that are hardcoded with
-// certificate pins or HSTS information.
-
-// kNoRejectedPublicKeys is a placeholder for when no public keys are rejected.
-static const char* const kNoRejectedPublicKeys[] = {
- NULL,
-};
-
-`)
-
- for _, pinset := range hsts.Pinsets {
- name := uppercaseFirstLetter(pinset.Name)
- acceptableListName := fmt.Sprintf("k%sAcceptableCerts", name)
- writeListOfPins(out, acceptableListName, pinset.Include)
-
- rejectedListName := "kNoRejectedPublicKeys"
- if len(pinset.Exclude) > 0 {
- rejectedListName = fmt.Sprintf("k%sRejectedCerts", name)
- writeListOfPins(out, rejectedListName, pinset.Exclude)
- }
- fmt.Fprintf(out, `#define k%sPins { \
- %s, \
- %s, \
-}
-
-`, name, acceptableListName, rejectedListName)
- }
-
- out.WriteString(`#define kNoPins {\
- NULL, NULL, \
-}
-
-static const struct HSTSPreload kPreloadedSTS[] = {
-`)
-
- for _, entry := range hsts.Entries {
- if entry.SNIOnly {
- continue
- }
- writeHSTSEntry(out, entry)
- }
-
- out.WriteString(`};
-static const size_t kNumPreloadedSTS = ARRAYSIZE_UNSAFE(kPreloadedSTS);
-
-static const struct HSTSPreload kPreloadedSNISTS[] = {
-`)
-
- for _, entry := range hsts.Entries {
- if !entry.SNIOnly {
- continue
- }
- writeHSTSEntry(out, entry)
- }
-
- out.WriteString(`};
-static const size_t kNumPreloadedSNISTS = ARRAYSIZE_UNSAFE(kPreloadedSNISTS);
-
-`)
-
- return nil
-}