sumdb/tlog: set the hash of the empty tree according to RFC 6962
Updates FiloSottile/sunlight#14
Change-Id: I712ea53fd3a17b66ec310d8f48de44416d0054cc
Reviewed-on: https://go-review.googlesource.com/c/mod/+/590715
Reviewed-by: Russ Cox <rsc@golang.org>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Joedian Reid <joedian@google.com>
diff --git a/sumdb/client.go b/sumdb/client.go
index 04c6e24..04dbdfe 100644
--- a/sumdb/client.go
+++ b/sumdb/client.go
@@ -142,6 +142,14 @@
c.verifiers = note.VerifierList(verifier)
c.name = verifier.Name()
+ if c.latest.N == 0 {
+ c.latest.Hash, err = tlog.TreeHash(0, nil)
+ if err != nil {
+ c.initErr = err
+ return
+ }
+ }
+
data, err := c.ops.ReadConfig(c.name + "/latest")
if err != nil {
c.initErr = err
diff --git a/sumdb/tlog/tlog.go b/sumdb/tlog/tlog.go
index 6a11a75..f7ea753 100644
--- a/sumdb/tlog/tlog.go
+++ b/sumdb/tlog/tlog.go
@@ -234,14 +234,22 @@
return f(indexes)
}
+// emptyHash is the hash of the empty tree, per RFC 6962, Section 2.1.
+// It is the hash of the empty string.
+var emptyHash = Hash{
+ 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14,
+ 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24,
+ 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c,
+ 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55,
+}
+
// TreeHash computes the hash for the root of the tree with n records,
// using the HashReader to obtain previously stored hashes
// (those returned by StoredHashes during the writes of those n records).
// TreeHash makes a single call to ReadHash requesting at most 1 + logâ‚‚ n hashes.
-// The tree of size zero is defined to have an all-zero Hash.
func TreeHash(n int64, r HashReader) (Hash, error) {
if n == 0 {
- return Hash{}, nil
+ return emptyHash, nil
}
indexes := subTreeIndex(0, n, nil)
hashes, err := r.ReadHashes(indexes)
diff --git a/sumdb/tlog/tlog_test.go b/sumdb/tlog/tlog_test.go
index 584e728..79db244 100644
--- a/sumdb/tlog/tlog_test.go
+++ b/sumdb/tlog/tlog_test.go
@@ -6,6 +6,7 @@
import (
"bytes"
+ "crypto/sha256"
"fmt"
"testing"
)
@@ -267,3 +268,13 @@
}
}
}
+
+func TestEmptyTree(t *testing.T) {
+ h, err := TreeHash(0, nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if h != sha256.Sum256(nil) {
+ t.Fatalf("TreeHash(0) = %x, want SHA-256('')", h)
+ }
+}