Skip to content

Commit

Permalink
Switch canonical json libraries
Browse files Browse the repository at this point in the history
Per CNAB Spec cnabio/cnab-spec#414, we want to
support numbers in our canonical json representation.

The library we are currently using, github.com/docker/go/json, does not support this.
So I am migrating us to the library mentioned in the spec as being
compliant. This is the same library used by cnab-go.

I was not able to completely remove the import of the old library
because TUF uses its RawMessage struct, which is a very simple wrapper
around a byte array.

If we are intersted we can try to get TUF to use an interface instead
of a hard-coded struct type so that we can drop the
dependency on the other canonical json library.

Signed-off-by: Carolyn Van Slyck <me@carolynvanslyck.com>
  • Loading branch information
carolynvs committed May 19, 2021
1 parent 7cb67b9 commit 6739584
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 12 deletions.
4 changes: 2 additions & 2 deletions cmd/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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")
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
29 changes: 29 additions & 0 deletions pkg/canonical_json/canonical_json.go
Original file line number Diff line number Diff line change
@@ -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
}
8 changes: 4 additions & 4 deletions pkg/intoto/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
}
9 changes: 5 additions & 4 deletions pkg/tuf/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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)
}
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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:", "")
Expand Down
4 changes: 2 additions & 2 deletions pkg/tuf/verify.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand All @@ -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
Expand Down

0 comments on commit 6739584

Please sign in to comment.