diff --git a/auditing.go b/auditing.go index 94b8c9f..a301f6c 100644 --- a/auditing.go +++ b/auditing.go @@ -132,7 +132,7 @@ func hashChildren(left ct.MerkleTreeNode, right ct.MerkleTreeNode) ct.MerkleTree return hasher.Sum(nil) } -type MerkleTreeBuilder struct { +type CollapsedMerkleTree struct { stack []ct.MerkleTreeNode numLeaves uint64 // number of hashes added so far } @@ -145,69 +145,69 @@ func calculateStackSize (numLeaves uint64) int { } return stackSize } -func EmptyMerkleTreeBuilder () *MerkleTreeBuilder { - return &MerkleTreeBuilder{} +func EmptyCollapsedMerkleTree () *CollapsedMerkleTree { + return &CollapsedMerkleTree{} } -func NewMerkleTreeBuilder (stack []ct.MerkleTreeNode, numLeaves uint64) (*MerkleTreeBuilder, error) { +func NewCollapsedMerkleTree (stack []ct.MerkleTreeNode, numLeaves uint64) (*CollapsedMerkleTree, error) { if len(stack) != calculateStackSize(numLeaves) { - return nil, errors.New("NewMerkleTreeBuilder: incorrect stack size") + return nil, errors.New("NewCollapsedMerkleTree: incorrect stack size") } - return &MerkleTreeBuilder{stack: stack, numLeaves: numLeaves}, nil + return &CollapsedMerkleTree{stack: stack, numLeaves: numLeaves}, nil } -func CloneMerkleTreeBuilder (source *MerkleTreeBuilder) *MerkleTreeBuilder { +func CloneCollapsedMerkleTree (source *CollapsedMerkleTree) *CollapsedMerkleTree { stack := make([]ct.MerkleTreeNode, len(source.stack)) copy(stack, source.stack) - return &MerkleTreeBuilder{stack: stack, numLeaves: source.numLeaves} + return &CollapsedMerkleTree{stack: stack, numLeaves: source.numLeaves} } -func (builder *MerkleTreeBuilder) Add(hash ct.MerkleTreeNode) { - builder.stack = append(builder.stack, hash) - builder.numLeaves++ - numLeaves := builder.numLeaves +func (tree *CollapsedMerkleTree) Add(hash ct.MerkleTreeNode) { + tree.stack = append(tree.stack, hash) + tree.numLeaves++ + numLeaves := tree.numLeaves for numLeaves%2 == 0 { - left, right := builder.stack[len(builder.stack)-2], builder.stack[len(builder.stack)-1] - builder.stack = builder.stack[:len(builder.stack)-2] - builder.stack = append(builder.stack, hashChildren(left, right)) + left, right := tree.stack[len(tree.stack)-2], tree.stack[len(tree.stack)-1] + tree.stack = tree.stack[:len(tree.stack)-2] + tree.stack = append(tree.stack, hashChildren(left, right)) numLeaves /= 2 } } -func (builder *MerkleTreeBuilder) CalculateRoot() ct.MerkleTreeNode { - if len(builder.stack) == 0 { +func (tree *CollapsedMerkleTree) CalculateRoot() ct.MerkleTreeNode { + if len(tree.stack) == 0 { return hashNothing() } - i := len(builder.stack) - 1 - hash := builder.stack[i] + i := len(tree.stack) - 1 + hash := tree.stack[i] for i > 0 { i -= 1 - hash = hashChildren(builder.stack[i], hash) + hash = hashChildren(tree.stack[i], hash) } return hash } -func (builder *MerkleTreeBuilder) GetNumLeaves() uint64 { - return builder.numLeaves +func (tree *CollapsedMerkleTree) GetNumLeaves() uint64 { + return tree.numLeaves } -func (builder *MerkleTreeBuilder) MarshalJSON() ([]byte, error) { +func (tree *CollapsedMerkleTree) MarshalJSON() ([]byte, error) { return json.Marshal(map[string]interface{}{ - "stack": builder.stack, - "num_leaves": builder.numLeaves, + "stack": tree.stack, + "num_leaves": tree.numLeaves, }) } -func (builder *MerkleTreeBuilder) UnmarshalJSON(b []byte) error { - var rawBuilder struct { +func (tree *CollapsedMerkleTree) UnmarshalJSON(b []byte) error { + var rawTree struct { Stack []ct.MerkleTreeNode `json:"stack"` NumLeaves uint64 `json:"num_leaves"` } - if err := json.Unmarshal(b, &rawBuilder); err != nil { - return errors.New("Failed to unmarshal MerkleTreeBuilder: " + err.Error()) + if err := json.Unmarshal(b, &rawTree); err != nil { + return errors.New("Failed to unmarshal CollapsedMerkleTree: " + err.Error()) } - if len(rawBuilder.Stack) != calculateStackSize(rawBuilder.NumLeaves) { - return errors.New("Failed to unmarshal MerkleTreeBuilder: invalid stack size") + if len(rawTree.Stack) != calculateStackSize(rawTree.NumLeaves) { + return errors.New("Failed to unmarshal CollapsedMerkleTree: invalid stack size") } - builder.numLeaves = rawBuilder.NumLeaves - builder.stack = rawBuilder.Stack + tree.numLeaves = rawTree.NumLeaves + tree.stack = rawTree.Stack return nil } diff --git a/cmd/common.go b/cmd/common.go index 3cddc6d..047a339 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -97,7 +97,7 @@ func loadLogList () ([]certspotter.LogInfo, error) { type logHandle struct { scanner *certspotter.Scanner state *LogState - position *certspotter.MerkleTreeBuilder + position *certspotter.CollapsedMerkleTree verifiedSTH *ct.SignedTreeHead } @@ -134,7 +134,7 @@ func makeLogHandle(logInfo *certspotter.LogInfo) (*logHandle, error) { } if legacySTH != nil { log.Printf("Initializing log state from legacy state directory") - ctlog.position, err = ctlog.scanner.MakeMerkleTreeBuilder(legacySTH) + ctlog.position, err = ctlog.scanner.MakeCollapsedMerkleTree(legacySTH) if err != nil { return nil, fmt.Errorf("Error reconstructing Merkle Tree for legacy STH: %s", err) } @@ -226,18 +226,18 @@ func (ctlog *logHandle) scan (processCallback certspotter.ProcessCallback) error endIndex := int64(ctlog.verifiedSTH.TreeSize) if endIndex > startIndex { - treeBuilder := certspotter.CloneMerkleTreeBuilder(ctlog.position) + tree := certspotter.CloneCollapsedMerkleTree(ctlog.position) - if err := ctlog.scanner.Scan(startIndex, endIndex, processCallback, treeBuilder); err != nil { + if err := ctlog.scanner.Scan(startIndex, endIndex, processCallback, tree); err != nil { return fmt.Errorf("Error scanning log (if this error persists, it should be construed as misbehavior by the log): %s", err) } - rootHash := treeBuilder.CalculateRoot() + rootHash := tree.CalculateRoot() if !bytes.Equal(rootHash, ctlog.verifiedSTH.SHA256RootHash[:]) { return fmt.Errorf("Log has misbehaved: log entries at tree size %d do not correspond to signed tree root", ctlog.verifiedSTH.TreeSize) } - ctlog.position = treeBuilder + ctlog.position = tree if err := ctlog.state.StoreLogPosition(ctlog.position); err != nil { return fmt.Errorf("Error storing log position: %s", err) } @@ -266,7 +266,7 @@ func processLog(logInfo* certspotter.LogInfo, processCallback certspotter.Proces } if *allTime { - ctlog.position = certspotter.EmptyMerkleTreeBuilder() + ctlog.position = certspotter.EmptyCollapsedMerkleTree() if *verbose { log.Printf("Scanning all %d entries in the log because -all_time option specified", ctlog.verifiedSTH.TreeSize) } @@ -275,7 +275,7 @@ func processLog(logInfo* certspotter.LogInfo, processCallback certspotter.Proces log.Printf("Existing log; scanning %d new entries since previous scan", ctlog.verifiedSTH.TreeSize-ctlog.position.GetNumLeaves()) } } else if state.IsFirstRun() { - ctlog.position, err = ctlog.scanner.MakeMerkleTreeBuilder(ctlog.verifiedSTH) + ctlog.position, err = ctlog.scanner.MakeCollapsedMerkleTree(ctlog.verifiedSTH) if err != nil { log.Printf("Error reconstructing Merkle Tree: %s", err) return 1 @@ -284,7 +284,7 @@ func processLog(logInfo* certspotter.LogInfo, processCallback certspotter.Proces log.Printf("First run of Cert Spotter; not scanning %d existing entries because -all_time option not specified", ctlog.verifiedSTH.TreeSize) } } else { - ctlog.position = certspotter.EmptyMerkleTreeBuilder() + ctlog.position = certspotter.EmptyCollapsedMerkleTree() if *verbose { log.Printf("New log; scanning all %d entries in the log", ctlog.verifiedSTH.TreeSize) } diff --git a/cmd/log_state.go b/cmd/log_state.go index aeba9ba..c6b5277 100644 --- a/cmd/log_state.go +++ b/cmd/log_state.go @@ -128,18 +128,18 @@ func (logState *LogState) RemoveUnverifiedSTH (sth *ct.SignedTreeHead) error { return nil } -func (logState *LogState) GetLogPosition () (*certspotter.MerkleTreeBuilder, error) { - builder := new(certspotter.MerkleTreeBuilder) - if err := readJSONFile(filepath.Join(logState.path, "position"), builder); err != nil { +func (logState *LogState) GetLogPosition () (*certspotter.CollapsedMerkleTree, error) { + tree := new(certspotter.CollapsedMerkleTree) + if err := readJSONFile(filepath.Join(logState.path, "position"), tree); err != nil { if os.IsNotExist(err) { return nil, nil } else { return nil, err } } - return builder, nil + return tree, nil } -func (logState *LogState) StoreLogPosition (builder *certspotter.MerkleTreeBuilder) error { - return writeJSONFile(filepath.Join(logState.path, "position"), builder, 0666) +func (logState *LogState) StoreLogPosition (tree *certspotter.CollapsedMerkleTree) error { + return writeJSONFile(filepath.Join(logState.path, "position"), tree, 0666) } diff --git a/scanner.go b/scanner.go index 462fa78..c50c161 100644 --- a/scanner.go +++ b/scanner.go @@ -91,7 +91,7 @@ func (s *Scanner) processerJob(id int, entries <-chan ct.LogEntry, processCert P wg.Done() } -func (s *Scanner) fetch(r fetchRange, entries chan<- ct.LogEntry, treeBuilder *MerkleTreeBuilder) error { +func (s *Scanner) fetch(r fetchRange, entries chan<- ct.LogEntry, tree *CollapsedMerkleTree) error { success := false retries := FETCH_RETRIES retryWait := FETCH_RETRY_WAIT @@ -113,8 +113,8 @@ func (s *Scanner) fetch(r fetchRange, entries chan<- ct.LogEntry, treeBuilder *M retries = FETCH_RETRIES retryWait = FETCH_RETRY_WAIT for _, logEntry := range logEntries { - if treeBuilder != nil { - treeBuilder.Add(hashLeaf(logEntry.LeafBytes)) + if tree != nil { + tree.Add(hashLeaf(logEntry.LeafBytes)) } logEntry.Index = r.start entries <- logEntry @@ -234,9 +234,9 @@ func (s *Scanner) CheckConsistency(first *ct.SignedTreeHead, second *ct.SignedTr return VerifyConsistencyProof(proof, first, second), nil } -func (s *Scanner) MakeMerkleTreeBuilder(sth *ct.SignedTreeHead) (*MerkleTreeBuilder, error) { +func (s *Scanner) MakeCollapsedMerkleTree(sth *ct.SignedTreeHead) (*CollapsedMerkleTree, error) { if sth.TreeSize == 0 { - return &MerkleTreeBuilder{}, nil + return &CollapsedMerkleTree{}, nil } entries, err := s.logClient.GetEntries(int64(sth.TreeSize - 1), int64(sth.TreeSize - 1)) @@ -248,30 +248,30 @@ func (s *Scanner) MakeMerkleTreeBuilder(sth *ct.SignedTreeHead) (*MerkleTreeBuil } leafHash := hashLeaf(entries[0].LeafBytes) - var builder *MerkleTreeBuilder + var tree *CollapsedMerkleTree if sth.TreeSize > 1 { auditPath, _, err := s.logClient.GetAuditProof(leafHash, sth.TreeSize) if err != nil { return nil, err } reverseHashes(auditPath) - builder, err = NewMerkleTreeBuilder(auditPath, sth.TreeSize - 1) + tree, err = NewCollapsedMerkleTree(auditPath, sth.TreeSize - 1) if err != nil { return nil, fmt.Errorf("Error returned bad audit proof for %x to %d", leafHash, sth.TreeSize) } } else { - builder = EmptyMerkleTreeBuilder() + tree = EmptyCollapsedMerkleTree() } - builder.Add(leafHash) - if !bytes.Equal(builder.CalculateRoot(), sth.SHA256RootHash[:]) { + tree.Add(leafHash) + if !bytes.Equal(tree.CalculateRoot(), sth.SHA256RootHash[:]) { return nil, fmt.Errorf("Calculated root hash does not match signed tree head at size %d", sth.TreeSize) } - return builder, nil + return tree, nil } -func (s *Scanner) Scan(startIndex int64, endIndex int64, processCert ProcessCallback, treeBuilder *MerkleTreeBuilder) error { +func (s *Scanner) Scan(startIndex int64, endIndex int64, processCert ProcessCallback, tree *CollapsedMerkleTree) error { s.Log("Starting scan...") s.certsProcessed = 0 @@ -300,7 +300,7 @@ func (s *Scanner) Scan(startIndex int64, endIndex int64, processCert ProcessCall for start := startIndex; start < int64(endIndex); { end := min(start+int64(s.opts.BatchSize), int64(endIndex)) - 1 - if err := s.fetch(fetchRange{start, end}, jobs, treeBuilder); err != nil { + if err := s.fetch(fetchRange{start, end}, jobs, tree); err != nil { return err } start = end + 1