func main() { if len(os.Args) != 3 { fmt.Fprintf(os.Stderr, "Usage: %s <log nickname> <log entries file>\n", os.Args[0]) fmt.Fprintf(os.Stderr, "Known logs:\n") fmt.Fprintf(os.Stderr, "\taviator\n") fmt.Fprintf(os.Stderr, "\tcertly\n") fmt.Fprintf(os.Stderr, "\tdigicert\n") fmt.Fprintf(os.Stderr, "\tizenpe\n") fmt.Fprintf(os.Stderr, "\tpilot\n") fmt.Fprintf(os.Stderr, "\trocketeer\n") fmt.Fprintf(os.Stderr, "\tsymantec\n") fmt.Fprintf(os.Stderr, "\tvenafi\n") os.Exit(1) } logName := os.Args[1] fileName := os.Args[2] var log *certificatetransparency.Log if logName == "pilot" { log = certificatetransparency.PilotLog } else if logName == "aviator" { log = certificatetransparency.AviatorLog } else if logName == "rocketeer" { log = certificatetransparency.RocketeerLog } else if logName == "symantec" { log = certificatetransparency.SymantecLog } else if logName == "izenpe" { log = certificatetransparency.IzenpeLog } else if logName == "certly" { log = certificatetransparency.CertlyLog } else if logName == "digicert" { log = certificatetransparency.DigiCertLog } else if logName == "venafi" { log = certificatetransparency.VenafiLog } else { fmt.Fprintf(os.Stderr, "Unknown log name '%s'\n", logName) os.Exit(1) } out, err := os.OpenFile(fileName, os.O_RDWR|os.O_CREATE, 0666) if err != nil { fmt.Fprintf(os.Stderr, "Failed to open entries file: %s\n", err) os.Exit(1) } defer out.Close() entriesFile := certificatetransparency.EntriesFile{out} fmt.Printf("Counting existing entries... ") count, err := entriesFile.Count() if err != nil { fmt.Fprintf(os.Stderr, "\nFailed to read entries file: %s\n", err) os.Exit(1) } fmt.Printf("%d\n", count) fmt.Printf("Fetching signed tree head... ") sth, err := log.GetSignedTreeHead() if err != nil { fmt.Fprintf(os.Stderr, "%s\n", err) os.Exit(1) } fmt.Printf("%d total entries at %s\n", sth.Size, sth.Time.Format(time.ANSIC)) if count == sth.Size { fmt.Printf("Nothing to do\n") return } statusChan := make(chan certificatetransparency.OperationStatus, 1) wg := new(sync.WaitGroup) displayProgress(statusChan, wg) _, err = log.DownloadRange(out, statusChan, count, sth.Size) wg.Wait() clearLine() if err != nil { fmt.Fprintf(os.Stderr, "Error while downloading: %s\n", err) os.Exit(1) } fmt.Printf("Hashing tree\n") entriesFile.Seek(0, 0) statusChan = make(chan certificatetransparency.OperationStatus, 1) wg = new(sync.WaitGroup) displayProgress(statusChan, wg) treeHash, err := entriesFile.HashTree(statusChan, sth.Size) wg.Wait() clearLine() if err != nil { fmt.Fprintf(os.Stderr, "Error hashing tree: %s\n", err) os.Exit(1) } if !bytes.Equal(treeHash[:], sth.Hash) { fmt.Fprintf(os.Stderr, "Hashes do not match! Calculated: %x, STH contains %x\n", treeHash, sth.Hash) os.Exit(1) } }