From 9c52bb0e1caf280e43db10f18dbfc5362bf577b1 Mon Sep 17 00:00:00 2001 From: asraa Date: Fri, 30 Sep 2022 16:09:37 -0500 Subject: [PATCH] fix: make client shard aware when verifying entries on inactive shards (#278) Signed-off-by: Asra Ali Signed-off-by: Asra Ali --- main_test.go | 4 ++-- pkg/provenance.go | 27 ++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/main_test.go b/main_test.go index bdedc1b..4e86bd1 100644 --- a/main_test.go +++ b/main_test.go @@ -309,7 +309,7 @@ func Test_runVerify(t *testing.T) { name: "rekor upload bypassed", artifact: "binary-linux-amd64-no-tlog-upload", source: "github.com/slsa-framework/example-package", - err: pkg.ErrorRekorSearch, + err: pkg.ErrorNoValidRekorEntries, noversion: true, }, { @@ -323,7 +323,7 @@ func Test_runVerify(t *testing.T) { name: "malicious: invalid signature expired certificate", artifact: "binary-linux-amd64-expired-cert", source: "github.com/slsa-framework/example-package", - err: pkg.ErrorRekorSearch, + err: pkg.ErrorNoValidRekorEntries, noversion: true, }, } diff --git a/pkg/provenance.go b/pkg/provenance.go index 166ce0a..d4a9c18 100644 --- a/pkg/provenance.go +++ b/pkg/provenance.go @@ -36,6 +36,7 @@ import ( "github.com/sigstore/rekor/pkg/generated/client/index" "github.com/sigstore/rekor/pkg/generated/client/tlog" "github.com/sigstore/rekor/pkg/generated/models" + "github.com/sigstore/rekor/pkg/sharding" "github.com/sigstore/rekor/pkg/types" intotod "github.com/sigstore/rekor/pkg/types/intoto/v0.0.1" "github.com/sigstore/rekor/pkg/util" @@ -188,7 +189,10 @@ func GetRekorEntriesWithCert(rClient *client.Rekor, artifactHash string, provena return env, certs[0], nil } -func verifyRootHash(ctx context.Context, rekorClient *client.Rekor, proof *models.InclusionProof, pub *ecdsa.PublicKey) error { +func verifyRootHash(ctx context.Context, rekorClient *client.Rekor, + treeID int64, + proof *models.InclusionProof, pub *ecdsa.PublicKey) error { + treeIDString := fmt.Sprintf("%d", treeID) infoParams := tlog.NewGetLogInfoParamsWithContext(ctx) result, err := rekorClient.Tlog.GetLogInfo(infoParams) if err != nil { @@ -201,6 +205,13 @@ func verifyRootHash(ctx context.Context, rekorClient *client.Rekor, proof *model if err := sth.UnmarshalText([]byte(*logInfo.SignedTreeHead)); err != nil { return err } + for _, inactiveShard := range logInfo.InactiveShards { + if *inactiveShard.TreeID == treeIDString { + if err := sth.UnmarshalText([]byte(*inactiveShard.SignedTreeHead)); err != nil { + return err + } + } + } verifier, err := signature.LoadVerifier(pub, crypto.SHA256) if err != nil { @@ -263,11 +274,20 @@ func verifyTlogEntryByUUID(ctx context.Context, rekorClient *client.Rekor, uuid return verifyTlogEntry(ctx, rekorClient, params.EntryUUID, e) } -func verifyTlogEntry(ctx context.Context, rekorClient *client.Rekor, uuid string, e models.LogEntryAnon) (*models.LogEntryAnon, error) { +func verifyTlogEntry(ctx context.Context, rekorClient *client.Rekor, entryUUID string, e models.LogEntryAnon) (*models.LogEntryAnon, error) { if e.Verification == nil || e.Verification.InclusionProof == nil { return nil, errors.New("inclusion proof not provided") } + uuid, err := sharding.GetUUIDFromIDString(entryUUID) + if err != nil { + return nil, fmt.Errorf("%w: retrieving uuid from entry uuid", err) + } + treeID, err := sharding.TreeID(entryUUID) + if err != nil { + return nil, fmt.Errorf("%w: retrieving tree ID", err) + } + hashes := [][]byte{} for _, h := range e.Verification.InclusionProof.Hashes { hb, err := hex.DecodeString(h) @@ -295,7 +315,8 @@ func verifyTlogEntry(ctx context.Context, rekorClient *client.Rekor, uuid string var entryVerError error for _, pubKey := range pubs { // Verify inclusion against the signed tree head - entryVerError = verifyRootHash(ctx, rekorClient, e.Verification.InclusionProof, pubKey.PubKey) + entryVerError = verifyRootHash(ctx, rekorClient, treeID, + e.Verification.InclusionProof, pubKey.PubKey) if entryVerError == nil { break }