From 2ef1544c44047f2046bfd1cf1e52e03e5a4dbeab Mon Sep 17 00:00:00 2001 From: Zachary Newman Date: Sun, 17 Apr 2022 19:39:03 -0400 Subject: [PATCH] Ensure that output is canonicalized --- repo.go | 14 ++++++++++---- repo_test.go | 9 +++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/repo.go b/repo.go index c2d7a407..c6a92d91 100644 --- a/repo.go +++ b/repo.go @@ -12,6 +12,7 @@ import ( "strings" "time" + "github.com/secure-systems-lab/go-securesystemslib/cjson" "github.com/theupdateframework/go-tuf/data" "github.com/theupdateframework/go-tuf/internal/roles" "github.com/theupdateframework/go-tuf/internal/signer" @@ -508,12 +509,12 @@ func (r *Repo) setTopLevelMeta(roleFilename string, meta interface{}) error { return r.local.SetMeta(roleFilename, b) } -// SignPayload signs the payload in signed to sign the keys associated with role. +// SignPayload signs the given payload using the key(s) associated with role. // // It returns the total number of keys used for signing, 0 (along with // ErrInsufficientKeys) if no keys were found, or -1 (along with an error) in // error cases. -func (r *Repo) SignPayload(role string, signed *data.Signed) (int, error) { +func (r *Repo) SignPayload(role string, payload *data.Signed) (int, error) { if !roles.IsTopLevelRole(role) { return -1, ErrInvalidRole{role, "only signing top-level metadata supported"} } @@ -526,7 +527,7 @@ func (r *Repo) SignPayload(role string, signed *data.Signed) (int, error) { return 0, ErrInsufficientKeys{role} } for _, k := range keys { - if err = sign.Sign(signed, k); err != nil { + if err = sign.Sign(payload, k); err != nil { return -1, err } } @@ -1080,5 +1081,10 @@ func (r *Repo) Payload(roleFilename string) ([]byte, error) { return nil, err } - return s.Signed, nil + p, err := cjson.EncodeCanonical(s.Signed) + if err != nil { + return nil, err + } + + return p, nil } diff --git a/repo_test.go b/repo_test.go index ccee49ff..0a9c60dc 100644 --- a/repo_test.go +++ b/repo_test.go @@ -1,6 +1,7 @@ package tuf import ( + "bytes" "crypto" "crypto/rand" "encoding/hex" @@ -1894,6 +1895,14 @@ func (rs *RepoSuite) TestOfflineFlow(c *C) { payload, err := r.Payload("root.json") c.Assert(err, IsNil) + root, err := r.SignedMeta("root.json") + c.Assert(err, IsNil) + rootCanonical, err := cjson.EncodeCanonical(root.Signed) + c.Assert(err, IsNil) + if !bytes.Equal(payload, rootCanonical) { + c.Fatalf("Payload(): not canonical.\n%s\n%s", string(payload), string(rootCanonical)) + } + // Sign the payload signed := data.Signed{Signed: payload} _, err = r.SignPayload("badrole", &signed)