func (ks *Keyserver) verifyUpdateDeterministic(prevUpdate *proto.UpdateRequest, req *proto.UpdateRequest) error { if got, want := vrf.Compute([]byte(req.LookupParameters.UserId), ks.vrfSecret), req.Update.NewEntry.Index; !bytes.Equal(got, want) { return fmt.Errorf("incorrect index for user %s: got %x, expected %x", req.LookupParameters.UserId, got, want) } var prevEntry *proto.Entry if prevUpdate != nil { prevEntry = &prevUpdate.Update.NewEntry.Entry } if err := coname.VerifyUpdate(prevEntry, req.Update); err != nil { return err } return nil }
// step is called by run and changes the in-memory state. No i/o allowed. func (vr *Verifier) step(step *proto.VerifierStep, vs *proto.VerifierState, wb kv.Batch) (deferredIO func()) { // vr: &const // step, vs, wb: &mut switch step.Type.(type) { case *proto.VerifierStep_Update: index := step.GetUpdate().NewEntry.Index prevEntry, err := vr.getEntry(index, vs.NextEpoch) if err := coname.VerifyUpdate(prevEntry, step.GetUpdate()); err != nil { // the keyserver should filter all bad updates log.Panicf("%d: bad update %v: %s", vs.NextIndex, *step, err) } var entryHash [32]byte sha3.ShakeSum256(entryHash[:], step.GetUpdate().NewEntry.Encoding) latestTree := vr.merkletree.GetSnapshot(vs.LatestTreeSnapshot) newTree, err := latestTree.BeginModification() if err != nil { log.Panicf("%d: BeginModification(): %s", vs.NextIndex, err) } if err := newTree.Set(index, entryHash[:]); err != nil { log.Panicf("%d: Set(%x,%x): %s", vs.NextIndex, index, entryHash[:], err) } vs.LatestTreeSnapshot = newTree.Flush(wb).Nr wb.Put(tableEntries(index, vs.NextEpoch), step.GetUpdate().NewEntry.Encoding) case *proto.VerifierStep_Epoch: ok := coname.VerifyPolicy(vr.vs.KeyserverAuth, step.GetEpoch().Head.Encoding, step.GetEpoch().Signatures) // the bad steps here will not get persisted to disk right now. do we want them to? if !ok { log.Panicf("%d: keyserver signature verification failed: %#v", vs.NextIndex, *step) } r := step.GetEpoch().Head if r.Head.Realm != vr.realm { log.Panicf("%d: seh for realm %q, expected %q: %#v", vs.NextEpoch, r.Head.Realm, vr.realm, *step) } if r.Head.Epoch != vs.NextEpoch { log.Panicf("%d: got epoch %d instead: %#v", vs.NextEpoch, r.Head.Epoch, *step) } s := r.Head if !bytes.Equal(s.PreviousSummaryHash, vs.PreviousSummaryHash) { log.Panicf("%d: seh with previous summary hash %q, expected %q: %#v", vs.NextEpoch, s.PreviousSummaryHash, vs.PreviousSummaryHash, *step) } latestTree := vr.merkletree.GetSnapshot(vs.LatestTreeSnapshot) rootHash, err := latestTree.GetRootHash() if err != nil { log.Panicf("GetRootHash() failed: %s", err) } if !bytes.Equal(s.RootHash, rootHash) { log.Panicf("%d: seh with root hash %q, expected %q: %#v", vs.NextEpoch, s.RootHash, rootHash, *step) } seh := &proto.SignedEpochHead{ Head: proto.EncodedTimestampedEpochHead{TimestampedEpochHead: proto.TimestampedEpochHead{ Head: s, Timestamp: proto.Time(time.Now()), }, Encoding: nil}, Signatures: make(map[uint64][]byte, 1), } if vs.PreviousSummaryHash == nil { vs.PreviousSummaryHash = make([]byte, 64) } sha3.ShakeSum256(vs.PreviousSummaryHash[:], seh.Head.Head.Encoding) seh.Head.UpdateEncoding() seh.Signatures[vr.id] = ed25519.Sign(vr.signingKey, proto.MustMarshal(&seh.Head))[:] wb.Put(tableRatifications(vs.NextEpoch, vr.id), proto.MustMarshal(seh)) vs.NextEpoch++ return func() { _, err := vr.keyserver.PushRatification(vr.ctx, seh) if err != nil { log.Printf("PushRatification: %s", err) } } default: log.Panicf("%d: unknown step: %#v", vs.NextIndex, *step) } return }