Save consistency proof along with evidence of misbehavior
Although the consistency proof is neither necessary nor sufficient to prove misbehavior by a log, this will help with debugging if a log returns a bogus consistency proof erroneously (which seems to be happening with the Rocketeer log lately...).
This commit is contained in:
parent
db2cd2c458
commit
e091186d83
|
@ -84,20 +84,25 @@ func defangLogUri (logUri string) string {
|
||||||
return strings.Replace(strings.Replace(logUri, "://", "_", 1), "/", "_", -1)
|
return strings.Replace(strings.Replace(logUri, "://", "_", 1), "/", "_", -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveEvidence (logUri string, firstSTH *ct.SignedTreeHead, secondSTH *ct.SignedTreeHead) (string, string, error) {
|
func saveEvidence (logUri string, firstSTH *ct.SignedTreeHead, secondSTH *ct.SignedTreeHead, proof ct.ConsistencyProof) (string, string, string, error) {
|
||||||
now := strconv.FormatInt(time.Now().Unix(), 10)
|
now := strconv.FormatInt(time.Now().Unix(), 10)
|
||||||
|
|
||||||
firstFilename := filepath.Join(stateDir, "evidence", defangLogUri(logUri) + ".inconsistent." + now + ".first")
|
firstFilename := filepath.Join(stateDir, "evidence", defangLogUri(logUri) + ".inconsistent." + now + ".first")
|
||||||
if err := ctwatch.WriteSTHFile(firstFilename, firstSTH); err != nil {
|
if err := ctwatch.WriteSTHFile(firstFilename, firstSTH); err != nil {
|
||||||
return "", "", err
|
return "", "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
secondFilename := filepath.Join(stateDir, "evidence", defangLogUri(logUri) + ".inconsistent." + now + ".second")
|
secondFilename := filepath.Join(stateDir, "evidence", defangLogUri(logUri) + ".inconsistent." + now + ".second")
|
||||||
if err := ctwatch.WriteSTHFile(secondFilename, secondSTH); err != nil {
|
if err := ctwatch.WriteSTHFile(secondFilename, secondSTH); err != nil {
|
||||||
return "", "", err
|
return "", "", "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return firstFilename, secondFilename, nil
|
proofFilename := filepath.Join(stateDir, "evidence", defangLogUri(logUri) + ".inconsistent." + now + ".proof")
|
||||||
|
if err := ctwatch.WriteProofFile(proofFilename, proof); err != nil {
|
||||||
|
return "", "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return firstFilename, secondFilename, proofFilename, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Main (argStateDir string, processCallback ctwatch.ProcessCallback) {
|
func Main (argStateDir string, processCallback ctwatch.ProcessCallback) {
|
||||||
|
@ -200,18 +205,19 @@ func Main (argStateDir string, processCallback ctwatch.ProcessCallback) {
|
||||||
if prevSTH != nil {
|
if prevSTH != nil {
|
||||||
var valid bool
|
var valid bool
|
||||||
var err error
|
var err error
|
||||||
valid, treeBuilder, err = scanner.CheckConsistency(prevSTH, latestSTH)
|
var proof ct.ConsistencyProof
|
||||||
|
valid, treeBuilder, proof, err = scanner.CheckConsistency(prevSTH, latestSTH)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error fetching consistency proof: %s\n", err)
|
log.Printf("Error fetching consistency proof: %s\n", err)
|
||||||
exitCode |= 4
|
exitCode |= 4
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !valid {
|
if !valid {
|
||||||
firstFilename, secondFilename, err := saveEvidence(logUri, prevSTH, latestSTH)
|
firstFilename, secondFilename, proofFilename, err := saveEvidence(logUri, prevSTH, latestSTH, proof)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Consistency proof failed - the log has misbehaved! Saving evidence of misbehavior failed: %s\n", err)
|
log.Printf("Consistency proof failed - the log has misbehaved! Saving evidence of misbehavior failed: %s\n", err)
|
||||||
} else {
|
} else {
|
||||||
log.Printf("Consistency proof failed - the log has misbehaved! Evidence of misbehavior has been saved to '%s' and '%s'.\n", firstFilename, secondFilename)
|
log.Printf("Consistency proof failed - the log has misbehaved! Evidence of misbehavior has been saved to '%s' and '%s' (with proof in '%s').\n", firstFilename, secondFilename, proofFilename)
|
||||||
}
|
}
|
||||||
exitCode |= 8
|
exitCode |= 8
|
||||||
continue
|
continue
|
||||||
|
|
|
@ -46,6 +46,15 @@ func WriteSTHFile (path string, sth *ct.SignedTreeHead) error {
|
||||||
return ioutil.WriteFile(path, sthJson, 0666)
|
return ioutil.WriteFile(path, sthJson, 0666)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func WriteProofFile (path string, proof ct.ConsistencyProof) error {
|
||||||
|
proofJson, err := json.MarshalIndent(proof, "", "\t")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
proofJson = append(proofJson, byte('\n'))
|
||||||
|
return ioutil.WriteFile(path, proofJson, 0666)
|
||||||
|
}
|
||||||
|
|
||||||
func IsPrecert (entry *ct.LogEntry) bool {
|
func IsPrecert (entry *ct.LogEntry) bool {
|
||||||
return entry.Leaf.TimestampedEntry.EntryType == ct.PrecertLogEntryType
|
return entry.Leaf.TimestampedEntry.EntryType == ct.PrecertLogEntryType
|
||||||
}
|
}
|
||||||
|
|
|
@ -202,12 +202,12 @@ func (s *Scanner) GetSTH() (*ct.SignedTreeHead, error) {
|
||||||
return latestSth, nil
|
return latestSth, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Scanner) CheckConsistency(first *ct.SignedTreeHead, second *ct.SignedTreeHead) (bool, *MerkleTreeBuilder, error) {
|
func (s *Scanner) CheckConsistency(first *ct.SignedTreeHead, second *ct.SignedTreeHead) (bool, *MerkleTreeBuilder, ct.ConsistencyProof, error) {
|
||||||
var proof ct.ConsistencyProof
|
var proof ct.ConsistencyProof
|
||||||
|
|
||||||
if first.TreeSize > second.TreeSize {
|
if first.TreeSize > second.TreeSize {
|
||||||
// No way this can be valid
|
// No way this can be valid
|
||||||
return false, nil, nil
|
return false, nil, nil, nil
|
||||||
} else if first.TreeSize == second.TreeSize {
|
} else if first.TreeSize == second.TreeSize {
|
||||||
// The proof *should* be empty, so don't bother contacting the server.
|
// The proof *should* be empty, so don't bother contacting the server.
|
||||||
// This is necessary because the digicert server returns a 400 error if first==second.
|
// This is necessary because the digicert server returns a 400 error if first==second.
|
||||||
|
@ -216,12 +216,12 @@ func (s *Scanner) CheckConsistency(first *ct.SignedTreeHead, second *ct.SignedTr
|
||||||
var err error
|
var err error
|
||||||
proof, err = s.logClient.GetConsistencyProof(int64(first.TreeSize), int64(second.TreeSize))
|
proof, err = s.logClient.GetConsistencyProof(int64(first.TreeSize), int64(second.TreeSize))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil, err
|
return false, nil, nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
valid, treeBuilder := VerifyConsistencyProof(proof, first, second)
|
valid, treeBuilder := VerifyConsistencyProof(proof, first, second)
|
||||||
return valid, treeBuilder, nil
|
return valid, treeBuilder, proof, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Scanner) Scan(startIndex int64, endIndex int64, processCert ProcessCallback, treeBuilder *MerkleTreeBuilder) error {
|
func (s *Scanner) Scan(startIndex int64, endIndex int64, processCert ProcessCallback, treeBuilder *MerkleTreeBuilder) error {
|
||||||
|
|
Loading…
Reference in New Issue