From 2820d69bb6233f0416d2d5576148463c95b823f3 Mon Sep 17 00:00:00 2001 From: Martin Hutchinson Date: Wed, 22 Jul 2026 14:28:11 +0000 Subject: [PATCH] [VIndex] Allow input log origin to be configured separately This allows the client to verify checkpoints from logs where the checkpoint origin string does not match the verifier key name (e.g., MTC logs). Removed the hack for SumDB now that origin is properly routed. --- vindex/client/client.go | 34 +++++++++++++++++++++------------- vindex/cmd/client/client.go | 2 +- vindex/map_test.go | 10 +++++----- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/vindex/client/client.go b/vindex/client/client.go index 9201a7e..e9b339b 100644 --- a/vindex/client/client.go +++ b/vindex/client/client.go @@ -39,7 +39,7 @@ import ( "filippo.io/torchwood/mpt" ) -func VerifyLookupResponse(keyHash [sha256.Size]byte, resp api.LookupResponse, inV, outV note.Verifier) ([]uint64, []byte, error) { +func VerifyLookupResponse(keyHash [sha256.Size]byte, resp api.LookupResponse, inV, outV note.Verifier, inLogOrigin string) ([]uint64, []byte, error) { // Currently the response contains the RFC6962 style response type; leaf, proof, etc. // What if we flip this all around, and the OutputLog part of the response // only returns an index into the output log, and the client has to look up @@ -72,11 +72,9 @@ func VerifyLookupResponse(keyHash [sha256.Size]byte, resp api.LookupResponse, in } vindexLeafHash := idxLeafHash.Sum(nil) - origin := inV.Name() - // Hack for sumDB - it's the only major log with a different origin than verifier string. - // It's easier to have a special case here, than to route through options to allow overriding. - if origin == "sum.golang.org" { - origin = "go.sum database tree" + origin := inLogOrigin + if origin == "" { + origin = inV.Name() } ilcp, _, _, err := log.ParseCheckpoint(inCp, origin, inV) if err != nil { @@ -104,6 +102,13 @@ func VerifyLookupResponse(keyHash [sha256.Size]byte, resp api.LookupResponse, in // given base URL, using the supplied verifier to check checkpoint signatures on the output // log. func NewVIndexClient(vindexUrl string, inV, outV note.Verifier) (*VIndexClient, error) { + return NewVIndexClientWithOrigin(vindexUrl, inV, outV, "") +} + +// NewVIndexClientWithOrigin returns a client that can perform verified lookups into the index +// at the given base URL, using the supplied verifier to check checkpoint signatures on the +// output log, and the supplied origin to verify the input log checkpoint. +func NewVIndexClientWithOrigin(vindexUrl string, inV, outV note.Verifier, inLogOrigin string) (*VIndexClient, error) { viu, err := url.Parse(vindexUrl) if err != nil { return nil, fmt.Errorf("failed to parse URL: %v", err) @@ -111,16 +116,18 @@ func NewVIndexClient(vindexUrl string, inV, outV note.Verifier) (*VIndexClient, lookupURL := viu.JoinPath(api.PathLookup) return &VIndexClient{ - lookupURL: lookupURL, - inV: inV, - outV: outV, + lookupURL: lookupURL, + inV: inV, + outV: outV, + inLogOrigin: inLogOrigin, }, nil } // VIndexClient allows verified lookups into a verifiable index. type VIndexClient struct { - lookupURL *url.URL - inV, outV note.Verifier + lookupURL *url.URL + inV, outV note.Verifier + inLogOrigin string } // Lookup returns all indices, in ascending order, where the given key appears in the Input Log. @@ -141,7 +148,7 @@ func (c VIndexClient) Lookup(ctx context.Context, key string) ([]uint64, []byte, return nil, nil, fmt.Errorf("lookup failed: %v", err) } - return VerifyLookupResponse(kh, resp, c.inV, c.outV) + return VerifyLookupResponse(kh, resp, c.inV, c.outV, c.inLogOrigin) } func (c VIndexClient) lookupUnverified(ctx context.Context, kh [sha256.Size]byte) (api.LookupResponse, error) { @@ -166,7 +173,8 @@ func (c VIndexClient) lookupUnverified(ctx context.Context, kh [sha256.Size]byte }() if resp.StatusCode != http.StatusOK { - return lookupResp, fmt.Errorf("got non-200 status code: %d", resp.StatusCode) + body, _ := io.ReadAll(resp.Body) + return lookupResp, fmt.Errorf("got non-200 status code: %d, body: %s", resp.StatusCode, string(body)) } body, err := io.ReadAll(resp.Body) diff --git a/vindex/cmd/client/client.go b/vindex/cmd/client/client.go index 2902f70..bef7b9c 100644 --- a/vindex/cmd/client/client.go +++ b/vindex/cmd/client/client.go @@ -113,7 +113,7 @@ func newVIndexClientFromFlags() *client.VIndexClient { if err != nil { klog.Exitf("failed to construct output log verifier: %v", err) } - c, err := client.NewVIndexClient(*vindexBaseURL, inV, outV) + c, err := client.NewVIndexClientWithOrigin(*vindexBaseURL, inV, outV, *inLogOrigin) if err != nil { klog.Exitf("failed to construct VIndex Client: %v", err) } diff --git a/vindex/map_test.go b/vindex/map_test.go index 7f633b5..aa8e1db 100644 --- a/vindex/map_test.go +++ b/vindex/map_test.go @@ -111,7 +111,7 @@ func TestVerifiableIndex(t *testing.T) { if err != nil { t.Fatal(err) } - indices, _, err := client.VerifyLookupResponse(kh, resp, v, v) + indices, _, err := client.VerifyLookupResponse(kh, resp, v, v, "") if err != nil { t.Fatalf("failed to verify vindex response: %v", err) } @@ -124,7 +124,7 @@ func TestVerifiableIndex(t *testing.T) { if err != nil { t.Fatal(err) } - indices, _, err = client.VerifyLookupResponse(kh, resp, v, v) + indices, _, err = client.VerifyLookupResponse(kh, resp, v, v, "") if err != nil { t.Fatalf("failed to verify vindex response: %v", err) } @@ -137,7 +137,7 @@ func TestVerifiableIndex(t *testing.T) { if err != nil { t.Fatal(err) } - indices, _, err = client.VerifyLookupResponse(kh, resp, v, v) + indices, _, err = client.VerifyLookupResponse(kh, resp, v, v, "") if err != nil { t.Fatalf("failed to verify vindex response: %v", err) } @@ -265,7 +265,7 @@ func TestVerifiableIndex_concurrency(t *testing.T) { if err != nil { return err } - indices, _, err = client.VerifyLookupResponse(kh, resp, v, v) + indices, _, err = client.VerifyLookupResponse(kh, resp, v, v, "") if err != nil { return fmt.Errorf("failed to verify vindex response: %v", err) } @@ -278,7 +278,7 @@ func TestVerifiableIndex_concurrency(t *testing.T) { if err != nil { return err } - indices, _, err = client.VerifyLookupResponse(kh, resp, v, v) + indices, _, err = client.VerifyLookupResponse(kh, resp, v, v, "") if err != nil { return fmt.Errorf("failed to verify vindex response: %v", err) }