package main import ( "log" "sync" "time" "git.sr.ht/~benburwell/gosumdbaudit/sumdb" ) func main() { dbs := []*database{ &database{ host: "sum.golang.org", key: "sum.golang.org+033de0ae+Ac4zctda0e5eza+HJyk9SxEdh+s3Ux18htTTAD8OuAn8", // key: "sum.golang.org+033de0ae+BADBADBADBADBADBADBADBADBADBADBADBADBADBADBA", pollInterval: 10 * time.Second, }, } var wg sync.WaitGroup wg.Add(len(dbs)) for _, db := range dbs { go func(db *database) { defer wg.Done() if err := monitor(db); err != nil { log.Printf("AUDIT FAILED: %s", err.Error()) return } }(db) } wg.Wait() } func monitor(db *database) error { log.Printf("starting monitor for %s", db.host) client := sumdb.NewClient(db) lines, err := client.Lookup("golang.org/x/text", "v0.3.0") if err != nil { return err } log.Printf("got lines: %s", lines) // fetch & verify current STH // latest, err := client.Latest() // if err != nil { // return err // } // fetch all entries in the tree according to the STH // entries := client.Entries(nil, latest) // confirm the tree made from the entries produces the same hash as the STH // IF NOT: the server has signed invalid data // prev := latest for { // await a new STH // prev = latest time.Sleep(db.pollInterval) log.Printf("checking %s for new STH...", db.host) // awaitNewSTH() // latest, err := client.Latest() // if err != nil { // return err // } // fetch all NEW entries between prev and latest // if unavailable for an extended period, this should be viewed as misbehavior // entries := client.Entries(prev, latest) // fetch a consistency proof for the new STH with the previous STH // verify consistency proof // verify the new entries generate the corresponding elements in the consistency proof } }