diff --git a/cmd/sign.go b/cmd/sign.go index b2ad06c..4d60143 100644 --- a/cmd/sign.go +++ b/cmd/sign.go @@ -4,10 +4,10 @@ import ( "encoding/hex" "fmt" - canonicaljson "github.com/docker/go/canonical/json" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "github.com/cnabio/signy/pkg/canonical_json" "github.com/cnabio/signy/pkg/cnab" "github.com/cnabio/signy/pkg/intoto" "github.com/cnabio/signy/pkg/tuf" @@ -89,7 +89,7 @@ INFO[0001] Pushed successfully, with digest "sha256:b4936e42304c184bafc9b06dde9e } func (s *signCmd) run() error { - var cm *canonicaljson.RawMessage + var cm *canonical_json.RawMessage if s.intoto { if s.layout == "" || s.layoutKey == "" || s.linkDir == "" { return fmt.Errorf("required in-toto metadata not found") diff --git a/go.mod b/go.mod index a0ec49b..58d9db6 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/containerd/cgroups v1.0.1 // indirect github.com/containerd/containerd v1.3.0 github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6 // indirect + github.com/cyberphone/json-canonicalization v0.0.0-20210303052042-6bc126869bf4 github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017 github.com/docker/cnab-to-oci v0.3.0-beta4 github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible diff --git a/go.sum b/go.sum index 81d06eb..5ed6328 100644 --- a/go.sum +++ b/go.sum @@ -96,6 +96,8 @@ github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+ github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cyberphone/json-canonicalization v0.0.0-20210303052042-6bc126869bf4 h1:7AjYfmq7AmviXsuZjV5DcE7PuhJ4dWMi8gLllpLVDQY= +github.com/cyberphone/json-canonicalization v0.0.0-20210303052042-6bc126869bf4/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/pkg/canonical_json/canonical_json.go b/pkg/canonical_json/canonical_json.go new file mode 100644 index 0000000..1cae8be --- /dev/null +++ b/pkg/canonical_json/canonical_json.go @@ -0,0 +1,29 @@ +package canonical_json + +import ( + "encoding/json" + + canonicaljson "github.com/cyberphone/json-canonicalization/go/src/webpki.org/jsoncanonicalizer" + rawmessage "github.com/docker/go/canonical/json" // We are only using this library for the RawMessage type that TUF uses, the actual marshaling is done by the webpki.org/jsoncanonicalizer library +) + +// define a type alias for raw message in this package +// so that outside of this package we only import a single canonical json library. +type RawMessage = rawmessage.RawMessage + +// Marshal returns the canonical json encoded value of v. +func Marshal(v interface{}) ([]byte, error) { + b, err := json.Marshal(v) + if err != nil { + return nil, err + } + return canonicaljson.Transform(b) +} + +func MarshalToRawMessage(v interface{}) (rawmessage.RawMessage, error) { + b, err := Marshal(v) + if err != nil { + return nil, err + } + return b, nil +} diff --git a/pkg/intoto/metadata.go b/pkg/intoto/metadata.go index 70f6722..c8766cb 100644 --- a/pkg/intoto/metadata.go +++ b/pkg/intoto/metadata.go @@ -6,7 +6,7 @@ import ( "path/filepath" "strings" - canonicaljson "github.com/docker/go/canonical/json" + "github.com/cnabio/signy/pkg/canonical_json" ) // Metadata represents the In-Toto metadata stored in TUF. @@ -52,7 +52,7 @@ func WriteMetadataFiles(m *Metadata, dir string) error { // // TODO: layout signing key should not be passed by the library. // Layouts should be signed with the targets key used to sign the TUF collection. -func GetMetadataRawMessage(layout string, linkDir string, layoutKey string) (canonicaljson.RawMessage, error) { +func GetMetadataRawMessage(layout string, linkDir string, layoutKey string) (canonical_json.RawMessage, error) { k, err := ioutil.ReadFile(layoutKey) if err != nil { return nil, fmt.Errorf("cannot get canonical JSON from file %v: %v", layoutKey, err) @@ -88,10 +88,10 @@ func GetMetadataRawMessage(layout string, linkDir string, layoutKey string) (can Links: links, } - raw, err := canonicaljson.MarshalCanonical(m) + raw, err := canonical_json.Marshal(m) if err != nil { return nil, fmt.Errorf("cannot encode in-toto metadata into canonical json %v: %v", m, err) } - return canonicaljson.RawMessage(raw), nil + return raw, nil } diff --git a/pkg/tuf/sign.go b/pkg/tuf/sign.go index a7296bb..4727823 100644 --- a/pkg/tuf/sign.go +++ b/pkg/tuf/sign.go @@ -6,11 +6,12 @@ import ( "strings" "github.com/docker/docker/api/types" - canonicaljson "github.com/docker/go/canonical/json" "github.com/theupdateframework/notary" "github.com/theupdateframework/notary/client" "github.com/theupdateframework/notary/trustpinning" "github.com/theupdateframework/notary/tuf/data" + + "github.com/cnabio/signy/pkg/canonical_json" ) // clearChangelist clears the notary staging changelist @@ -23,7 +24,7 @@ func clearChangeList(notaryRepo client.Repository) error { } // SignAndPublish signs an artifact, then publishes the metadata to a trust server -func SignAndPublish(trustDir, trustServer, ref, file, tlscacert, rootKey, timeout string, custom *canonicaljson.RawMessage) (*client.Target, error) { +func SignAndPublish(trustDir, trustServer, ref, file, tlscacert, rootKey, timeout string, custom *canonical_json.RawMessage) (*client.Target, error) { if err := EnsureTrustDir(trustDir); err != nil { return nil, fmt.Errorf("cannot ensure trust directory: %v", err) } @@ -101,7 +102,7 @@ func SignAndPublish(trustDir, trustServer, ref, file, tlscacert, rootKey, timeou } // SignAndPublish signs a Docker Image, then publishes the metadata to a trust server -func SignAndPublishWithImagePushResult(trustDir, trustServer, ref string, pushResult types.PushResult, tlscacert, rootKey, timeout string, custom *canonicaljson.RawMessage) (*client.Target, error) { +func SignAndPublishWithImagePushResult(trustDir, trustServer, ref string, pushResult types.PushResult, tlscacert, rootKey, timeout string, custom *canonical_json.RawMessage) (*client.Target, error) { if err := EnsureTrustDir(trustDir); err != nil { return nil, fmt.Errorf("cannot ensure trust directory: %v", err) } @@ -178,7 +179,7 @@ func SignAndPublishWithImagePushResult(trustDir, trustServer, ref string, pushRe return target, err } -func NewTargetFromPushResult(targetName string, pushResult types.PushResult, targetCustom *canonicaljson.RawMessage) (*client.Target, error) { +func NewTargetFromPushResult(targetName string, pushResult types.PushResult, targetCustom *canonical_json.RawMessage) (*client.Target, error) { meta := pushResult.Digest meta = strings.ReplaceAll(meta, "sha256:", "") diff --git a/pkg/tuf/verify.go b/pkg/tuf/verify.go index 28a933d..b40fcc8 100644 --- a/pkg/tuf/verify.go +++ b/pkg/tuf/verify.go @@ -6,10 +6,10 @@ import ( "fmt" "io/ioutil" - "github.com/docker/go/canonical/json" log "github.com/sirupsen/logrus" "github.com/theupdateframework/notary/client" + "github.com/cnabio/signy/pkg/canonical_json" "github.com/cnabio/signy/pkg/cnab" ) @@ -24,7 +24,7 @@ func GetThinBundle(ref string) ([]byte, error) { if err != nil { return nil, err } - return json.MarshalCanonical(bun) + return canonical_json.Marshal(bun) } // VerifyTrust ensures the trust metadata for a given GUN matches the metadata of the pushed bundle