| Index: net/base/public_key_hashes_check.go
|
| diff --git a/net/base/public_key_hashes_check.go b/net/base/public_key_hashes_check.go
|
| deleted file mode 100644
|
| index 61b4bcdda3c1e5166accca33f6be376fdd9b6e62..0000000000000000000000000000000000000000
|
| --- a/net/base/public_key_hashes_check.go
|
| +++ /dev/null
|
| @@ -1,235 +0,0 @@
|
| -// Copyright (c) 2011 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.
|
| -
|
| -// public_key_hashes_check.go runs tests on public_key_hashes.h. It's not run
|
| -// automatically, but rather as part of the process of manually updating
|
| -// public_key_hashes.h
|
| -//
|
| -// It verifies that each hash in the file is correct given the preceeding
|
| -// certificate and that the name of the variable matches the name given in the
|
| -// certifiate.
|
| -//
|
| -// Compile and run with:
|
| -// % cd net/base
|
| -// % 6g public_key_hashes_check.go && 6l public_key_hashes_check.6 && ./6.out ./public_key_hashes.h
|
| -
|
| -package main
|
| -
|
| -import (
|
| - "bufio"
|
| - "bytes"
|
| - "crypto/sha1"
|
| - "crypto/x509"
|
| - "encoding/base64"
|
| - "encoding/pem"
|
| - "errors"
|
| - "fmt"
|
| - "io"
|
| - "os"
|
| - "strings"
|
| -)
|
| -
|
| -const (
|
| - PRECERT = iota
|
| - INCERT = iota
|
| - POSTCERT = iota
|
| - POSTDECL = iota
|
| -)
|
| -
|
| -var newLine = []byte("\n")
|
| -var startOfCert = []byte("-----BEGIN CERTIFICATE")
|
| -var endOfCert = []byte("-----END CERTIFICATE")
|
| -var hashDecl = []byte("static const char kSPKIHash_")
|
| -
|
| -// matchNames returns true if the given variable 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 pos := strings.Index(firstWord, "."); pos != -1 {
|
| - firstWord = firstWord[:pos]
|
| - }
|
| - if pos := strings.Index(firstWord, "-"); pos != -1 {
|
| - firstWord = firstWord[:pos]
|
| - }
|
| - if !strings.HasPrefix(v, 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
|
| -}
|
| -
|
| -func main() {
|
| - if len(os.Args) < 2 {
|
| - fmt.Fprintf(os.Stderr, "Usage: %s <public_key_hashes.h>\n", os.Args[0])
|
| - return
|
| - }
|
| -
|
| - inFile, err := os.Open(os.Args[1])
|
| - if err != nil {
|
| - fmt.Fprintf(os.Stderr, "Failed to open input file: %s\n", err.Error())
|
| - return
|
| - }
|
| -
|
| - in := bufio.NewReader(inFile)
|
| - defer inFile.Close()
|
| -
|
| - lineNo := 0
|
| - var cert []byte
|
| - state := PRECERT
|
| - var x509Cert *x509.Certificate
|
| - seenHashes := make(map[string]bool)
|
| -
|
| - for {
|
| - lineNo++
|
| - line, isPrefix, err := in.ReadLine()
|
| - if isPrefix {
|
| - fmt.Fprintf(os.Stderr, "Line %d is too long to process\n", lineNo)
|
| - return
|
| - }
|
| - if err == io.EOF {
|
| - return
|
| - }
|
| - if err != nil {
|
| - fmt.Fprintf(os.Stderr, "Error reading from input: %s\n", err.Error())
|
| - return
|
| - }
|
| -
|
| - switch state {
|
| - case INCERT:
|
| - cert = append(cert, line...)
|
| - cert = append(cert, newLine...)
|
| - case POSTDECL:
|
| - trimmed := bytes.TrimSpace(line)
|
| - if len(trimmed) < 8 || !bytes.HasPrefix(trimmed, []byte("\"sha1/")) {
|
| - fmt.Fprintf(os.Stderr, "Line %d is immediately after a declation, but failed to find a hash on it\n", lineNo)
|
| - return
|
| - }
|
| - trimmed = trimmed[6 : len(trimmed)-2]
|
| - h := sha1.New()
|
| - h.Write(x509Cert.RawSubjectPublicKeyInfo)
|
| - shouldBe := base64.StdEncoding.EncodeToString(h.Sum(nil))
|
| - if shouldBe != string(trimmed) {
|
| - fmt.Fprintf(os.Stderr, "Line %d: hash should be %s, but found %s\n", lineNo, shouldBe, trimmed)
|
| - return
|
| - }
|
| - if _, ok := seenHashes[shouldBe]; ok {
|
| - fmt.Fprintf(os.Stderr, "Line %d: duplicated hash\n", lineNo)
|
| - return
|
| - }
|
| - seenHashes[shouldBe] = true
|
| - state = PRECERT
|
| - x509Cert = nil
|
| - }
|
| -
|
| - if bytes.HasPrefix(line, startOfCert) {
|
| - switch state {
|
| - case PRECERT:
|
| - cert = append(cert, line...)
|
| - cert = append(cert, newLine...)
|
| - state = INCERT
|
| - case INCERT:
|
| - fmt.Fprintf(os.Stderr, "Found start of certificate while in certificate at line %d\n", lineNo)
|
| - return
|
| - case POSTCERT:
|
| - fmt.Fprintf(os.Stderr, "Found start of certificate while while looking for hash at line %d\n", lineNo)
|
| - return
|
| - case POSTDECL:
|
| - fmt.Fprintf(os.Stderr, "Found start of certificate while while looking for hash string at line %d\n", lineNo)
|
| - return
|
| - default:
|
| - panic("bad state")
|
| - }
|
| - } else if bytes.HasPrefix(line, endOfCert) {
|
| - switch state {
|
| - case PRECERT:
|
| - fmt.Fprintf(os.Stderr, "Found end of certificate without certificate at line %d\n", lineNo)
|
| - return
|
| - case INCERT:
|
| - block, _ := pem.Decode(cert)
|
| - if block == nil {
|
| - fmt.Fprintf(os.Stderr, "Failed to decode certificate ending on line %d\n", lineNo)
|
| - return
|
| - }
|
| - if x509Cert, err = x509.ParseCertificate(block.Bytes); err != nil {
|
| - fmt.Fprintf(os.Stderr, "Failed to parse certificate ending on line %d: %s\n", lineNo, err.Error())
|
| - return
|
| - }
|
| - cert = nil
|
| - state = POSTCERT
|
| - case POSTCERT:
|
| - fmt.Fprintf(os.Stderr, "Found end of certificate while while looking for hash at line %d\n", lineNo)
|
| - return
|
| - case POSTDECL:
|
| - fmt.Fprintf(os.Stderr, "Found end of certificate while while looking for hash string at line %d\n", lineNo)
|
| - return
|
| - default:
|
| - panic("bad state")
|
| - }
|
| - } else if bytes.HasPrefix(line, hashDecl) {
|
| - switch state {
|
| - case PRECERT:
|
| - // No problem here. Not all declations need a certificate
|
| - case INCERT:
|
| - fmt.Fprintf(os.Stderr, "Found declation at line %d, but missed the end of the certificate\n", lineNo)
|
| - return
|
| - case POSTCERT:
|
| - varName := line[len(hashDecl):]
|
| - for i, c := range varName {
|
| - if c == '[' {
|
| - varName = varName[:i]
|
| - break
|
| - }
|
| - }
|
| - name := x509Cert.Subject.CommonName
|
| - if len(name) == 0 {
|
| - name = x509Cert.Subject.Organization[0] + " " + x509Cert.Subject.OrganizationalUnit[0]
|
| - }
|
| - if err := matchNames(name, string(varName)); err != nil {
|
| - fmt.Fprintf(os.Stderr, "Name failure on line %d: %s\n%s -> %s\n", lineNo, err, name, varName)
|
| - return
|
| - }
|
| -
|
| - state = POSTDECL
|
| - case POSTDECL:
|
| - fmt.Fprintf(os.Stderr, "Found declation at line %d, but missed the hash value of the previous one\n", lineNo)
|
| - return
|
| - default:
|
| - panic("bad state")
|
| - }
|
| - }
|
| - }
|
| -}
|
|
|