sumdb/note: catch a Verifiers that returns the wrong Verifier

The Verifier method gets the name and hash of the signature, and is
supposed to only return a Verifier for that name and hash. If it
doesn't, we can catch it by double checking the KeyHash and Name method
return values against the signature.

Change-Id: I39b2e3616ac389718ebc7eaa6263a43b9152b2fa
Reviewed-on: https://go-review.googlesource.com/c/mod/+/364854
Trust: Filippo Valsorda <filippo@golang.org>
Run-TryBot: Filippo Valsorda <filippo@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Al Cutter <alcutter@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/sumdb/note/note.go b/sumdb/note/note.go
index 467d25e..ebfbe34 100644
--- a/sumdb/note/note.go
+++ b/sumdb/note/note.go
@@ -496,8 +496,9 @@
 }
 
 var (
-	errMalformedNote = errors.New("malformed note")
-	errInvalidSigner = errors.New("invalid signer")
+	errMalformedNote      = errors.New("malformed note")
+	errInvalidSigner      = errors.New("invalid signer")
+	errMismatchedVerifier = errors.New("verifier name or hash doesn't match signature")
 
 	sigSplit  = []byte("\n\n")
 	sigPrefix = []byte("— ")
@@ -589,6 +590,11 @@
 			return nil, err
 		}
 
+		// Check that known.Verifier returned the right verifier.
+		if v.Name() != name || v.KeyHash() != hash {
+			return nil, errMismatchedVerifier
+		}
+
 		// Drop repeated signatures by a single verifier.
 		if seen[nameHash{name, hash}] {
 			continue
diff --git a/sumdb/note/note_test.go b/sumdb/note/note_test.go
index 96c8c91..04efaf2 100644
--- a/sumdb/note/note_test.go
+++ b/sumdb/note/note_test.go
@@ -297,6 +297,12 @@
 	return nil, errSurprise
 }
 
+type fixedVerifier struct{ v Verifier }
+
+func (v fixedVerifier) Verifier(name string, hash uint32) (Verifier, error) {
+	return v.v, nil
+}
+
 func TestOpen(t *testing.T) {
 	peterKey := "PeterNeumann+c74f20a3+ARpc2QcUPDhMQegwxbzhKqiBfsVkmqq/LDE4izWy10TW"
 	peterVerifier, err := NewVerifier(peterKey)
@@ -427,6 +433,18 @@
 			t.Fatalf("Open bad msg = %v, %v, want nil, malformed note error\nmsg:\n%s", n, err, msg)
 		}
 	}
+
+	// Verifiers returns a Verifier for the wrong name or hash.
+	misnamedSig := strings.Replace(peterSig, "PeterNeumann", "CarmenSandiego", -1)
+	_, err = Open([]byte(text+"\n"+misnamedSig), fixedVerifier{peterVerifier})
+	if err != errMismatchedVerifier {
+		t.Fatalf("Open with wrong Verifier, err=%v, want errMismatchedVerifier", err)
+	}
+	wrongHash := strings.Replace(peterSig, "x08g", "xxxx", -1)
+	_, err = Open([]byte(text+"\n"+wrongHash), fixedVerifier{peterVerifier})
+	if err != errMismatchedVerifier {
+		t.Fatalf("Open with wrong Verifier, err=%v, want errMismatchedVerifier", err)
+	}
 }
 
 func BenchmarkOpen(b *testing.B) {