Просмотр исходного кода

update tests and error messages, revendor notary with tag

Signed-off-by: Riyaz Faizullabhoy <riyaz.faizullabhoy@docker.com>
Riyaz Faizullabhoy 9 лет назад
Родитель
Сommit
1c32a66877

+ 2 - 2
Dockerfile

@@ -153,11 +153,11 @@ RUN set -x \
 	&& rm -rf "$GOPATH"
 
 # Install notary server
-ENV NOTARY_COMMIT 30c488b3b4c62fdbc2c1eae7cf3b62ca73f95fad
+ENV NOTARY_VERSION docker-v1.10-1
 RUN set -x \
 	&& export GOPATH="$(mktemp -d)" \
 	&& git clone https://github.com/docker/notary.git "$GOPATH/src/github.com/docker/notary" \
-	&& (cd "$GOPATH/src/github.com/docker/notary" && git checkout -q "$NOTARY_COMMIT") \
+	&& (cd "$GOPATH/src/github.com/docker/notary" && git checkout -q "$NOTARY_VERSION") \
 	&& GOPATH="$GOPATH/src/github.com/docker/notary/Godeps/_workspace:$GOPATH" \
 		go build -o /usr/local/bin/notary-server github.com/docker/notary/cmd/notary-server \
 	&& GOPATH="$GOPATH/src/github.com/docker/notary/Godeps/_workspace:$GOPATH" \

+ 9 - 7
api/client/trust.go

@@ -278,22 +278,24 @@ func notaryError(repoName string, err error) error {
 	case *json.SyntaxError:
 		logrus.Debugf("Notary syntax error: %s", err)
 		return fmt.Errorf("Error: no trust data available for remote repository %s. Try running notary server and setting DOCKER_CONTENT_TRUST_SERVER to its HTTPS address?", repoName)
-	case client.ErrExpired:
+	case signed.ErrExpired:
 		return fmt.Errorf("Error: remote repository %s out-of-date: %v", repoName, err)
 	case trustmanager.ErrKeyNotFound:
 		return fmt.Errorf("Error: signing keys for remote repository %s not found: %v", repoName, err)
 	case *net.OpError:
 		return fmt.Errorf("Error: error contacting notary server: %v", err)
 	case store.ErrMetaNotFound:
-		return fmt.Errorf("Error: trust data missing for remote repository %s: %v", repoName, err)
+		return fmt.Errorf("Error: trust data missing for remote repository %s or remote repository not found: %v", repoName, err)
 	case signed.ErrInvalidKeyType:
-		return fmt.Errorf("Error: trust data mismatch for remote repository %s, could be malicious behavior: %v", repoName, err)
+		return fmt.Errorf("Warning: potential malicious behavior - trust data mismatch for remote repository %s: %v", repoName, err)
 	case signed.ErrNoKeys:
 		return fmt.Errorf("Error: could not find signing keys for remote repository %s: %v", repoName, err)
 	case signed.ErrLowVersion:
-		return fmt.Errorf("Error: trust data version is lower than expected for remote repository %s, could be malicious behavior: %v", repoName, err)
+		return fmt.Errorf("Warning: potential malicious behavior - trust data version is lower than expected for remote repository %s: %v", repoName, err)
 	case signed.ErrInsufficientSignatures:
-		return fmt.Errorf("Error: trust data has insufficient signatures for remote repository %s, could be malicious behavior: %v", repoName, err)
+		return fmt.Errorf("Warning: potential malicious behavior - trust data has insufficient signatures for remote repository %s: %v", repoName, err)
+	case client.ErrRepositoryNotExist:
+		return fmt.Errorf("Error: remote trust data repository not initialized for %s: %v", repoName, err)
 	}
 
 	return err
@@ -432,7 +434,7 @@ func (cli *DockerCli) trustedPush(repoInfo *registry.RepositoryInfo, tag string,
 
 	repo, err := cli.getNotaryRepository(repoInfo, authConfig)
 	if err != nil {
-		fmt.Fprintf(cli.out, "Error establishing connection to notary repository, has a notary server been setup and pointed to by the DOCKER_CONTENT_TRUST_SERVER environment variable?: %s\n", err)
+		fmt.Fprintf(cli.out, "Error establishing connection to notary repository: %s\n", err)
 		return err
 	}
 
@@ -454,7 +456,7 @@ func (cli *DockerCli) trustedPush(repoInfo *registry.RepositoryInfo, tag string,
 	}
 
 	err = repo.Publish()
-	if _, ok := err.(*client.ErrRepoNotInitialized); !ok {
+	if _, ok := err.(client.ErrRepoNotInitialized); !ok {
 		return notaryError(repoInfo.FullName(), err)
 	}
 

+ 1 - 1
hack/vendor.sh

@@ -47,7 +47,7 @@ clone git github.com/docker/distribution 568bf038af6d65b376165d02886b1c7fcaef1f6
 clone git github.com/vbatts/tar-split v0.9.11
 
 # get desired notary commit, might also need to be updated in Dockerfile
-clone git github.com/docker/notary 30c488b3b4c62fdbc2c1eae7cf3b62ca73f95fad
+clone git github.com/docker/notary docker-v1.10-1
 
 clone git google.golang.org/grpc 174192fc93efcb188fc8f46ca447f0da606b6885 https://github.com/grpc/grpc-go.git
 clone git github.com/miekg/pkcs11 80f102b5cac759de406949c47f0928b99bd64cdf

+ 1 - 1
integration-cli/docker_cli_build_test.go

@@ -5805,7 +5805,7 @@ func (s *DockerTrustSuite) TestTrustedBuildUntrustedTag(c *check.C) {
 		c.Fatalf("Expected error on trusted build with untrusted tag: %s\n%s", err, out)
 	}
 
-	if !strings.Contains(out, fmt.Sprintf("trust data unavailable")) {
+	if !strings.Contains(out, "does not have trust data for") {
 		c.Fatalf("Unexpected output on trusted build with untrusted tag:\n%s", out)
 	}
 }

+ 1 - 1
integration-cli/docker_cli_create_test.go

@@ -312,7 +312,7 @@ func (s *DockerTrustSuite) TestUntrustedCreate(c *check.C) {
 	s.trustedCmd(createCmd)
 	out, _, err := runCommandWithOutput(createCmd)
 	c.Assert(err, check.Not(check.IsNil))
-	c.Assert(string(out), checker.Contains, "trust data unavailable", check.Commentf("Missing expected output on trusted create:\n%s", out))
+	c.Assert(string(out), checker.Contains, "does not have trust data for", check.Commentf("Missing expected output on trusted create:\n%s", out))
 
 }
 

+ 1 - 1
integration-cli/docker_cli_pull_trusted_test.go

@@ -58,7 +58,7 @@ func (s *DockerTrustSuite) TestUntrustedPull(c *check.C) {
 	out, _, err := runCommandWithOutput(pullCmd)
 
 	c.Assert(err, check.NotNil, check.Commentf(out))
-	c.Assert(string(out), checker.Contains, "trust data unavailable", check.Commentf(out))
+	c.Assert(string(out), checker.Contains, "Error: remote trust data repository not initialized", check.Commentf(out))
 }
 
 func (s *DockerTrustSuite) TestPullWhenCertExpired(c *check.C) {

+ 1 - 1
integration-cli/docker_cli_run_test.go

@@ -3087,7 +3087,7 @@ func (s *DockerTrustSuite) TestUntrustedRun(c *check.C) {
 		c.Fatalf("Error expected when running trusted run with:\n%s", out)
 	}
 
-	if !strings.Contains(string(out), "trust data unavailable") {
+	if !strings.Contains(string(out), "does not have trust data for") {
 		c.Fatalf("Missing expected output on trusted run:\n%s", out)
 	}
 }

+ 1 - 1
vendor/src/github.com/docker/notary/Dockerfile.signer

@@ -23,7 +23,7 @@ RUN softhsm2-util --init-token --slot 0 --label "test_token" --pin $NOTARY_SIGNE
 ENV NOTARYPKG github.com/docker/notary
 ENV GOPATH /go/src/${NOTARYPKG}/Godeps/_workspace:$GOPATH
 
-EXPOSE 4443
+EXPOSE 4444
 
 # Copy the local repo to the expected go path
 COPY . /go/src/github.com/docker/notary

+ 54 - 61
vendor/src/github.com/docker/notary/client/client.go

@@ -2,17 +2,18 @@ package client
 
 import (
 	"bytes"
-	"encoding/json"
-	"errors"
 	"fmt"
 	"io/ioutil"
 	"net/http"
+	"net/url"
 	"os"
 	"path/filepath"
 	"strings"
 	"time"
 
 	"github.com/Sirupsen/logrus"
+	"github.com/jfrazelle/go/canonical/json"
+
 	"github.com/docker/notary/certs"
 	"github.com/docker/notary/client/changelist"
 	"github.com/docker/notary/cryptoservice"
@@ -39,19 +40,12 @@ func init() {
 	)
 }
 
-// ErrRepoNotInitialized is returned when trying to can publish on an uninitialized
+// ErrRepoNotInitialized is returned when trying to publish an uninitialized
 // notary repository
 type ErrRepoNotInitialized struct{}
 
-// ErrRepoNotInitialized is returned when trying to can publish on an uninitialized
-// notary repository
-func (err *ErrRepoNotInitialized) Error() string {
-	return "Repository has not been initialized"
-}
-
-// ErrExpired is returned when the metadata for a role has expired
-type ErrExpired struct {
-	signed.ErrExpired
+func (err ErrRepoNotInitialized) Error() string {
+	return "repository has not been initialized"
 }
 
 // ErrInvalidRemoteRole is returned when the server is requested to manage
@@ -65,14 +59,21 @@ func (e ErrInvalidRemoteRole) Error() string {
 		"notary does not support the server managing the %s key", e.Role)
 }
 
+// ErrRepositoryNotExist is returned when an action is taken on a remote
+// repository that doesn't exist
+type ErrRepositoryNotExist struct {
+	remote string
+	gun    string
+}
+
+func (err ErrRepositoryNotExist) Error() string {
+	return fmt.Sprintf("%s does not have trust data for %s", err.remote, err.gun)
+}
+
 const (
 	tufDir = "tuf"
 )
 
-// ErrRepositoryNotExist gets returned when trying to make an action over a repository
-/// that doesn't exist.
-var ErrRepositoryNotExist = errors.New("repository does not exist")
-
 // NotaryRepository stores all the information needed to operate on a notary
 // repository.
 type NotaryRepository struct {
@@ -323,7 +324,7 @@ func (r *NotaryRepository) AddDelegation(name string, threshold int,
 	logrus.Debugf(`Adding delegation "%s" with threshold %d, and %d keys\n`,
 		name, threshold, len(delegationKeys))
 
-	tdJSON, err := json.Marshal(&changelist.TufDelegation{
+	tdJSON, err := json.MarshalCanonical(&changelist.TufDelegation{
 		NewThreshold: threshold,
 		AddKeys:      data.KeyList(delegationKeys),
 		AddPaths:     paths,
@@ -385,7 +386,7 @@ func (r *NotaryRepository) AddTarget(target *Target, roles ...string) error {
 	logrus.Debugf("Adding target \"%s\" with sha256 \"%x\" and size %d bytes.\n", target.Name, target.Hashes["sha256"], target.Length)
 
 	meta := data.FileMeta{Length: target.Length, Hashes: target.Hashes}
-	metaJSON, err := json.Marshal(meta)
+	metaJSON, err := json.MarshalCanonical(meta)
 	if err != nil {
 		return err
 	}
@@ -419,16 +420,8 @@ func (r *NotaryRepository) RemoveTarget(targetName string, roles ...string) erro
 // subtree and also the "targets/x" subtree, as we will defer parsing it until
 // we explicitly reach it in our iteration of the provided list of roles.
 func (r *NotaryRepository) ListTargets(roles ...string) ([]*TargetWithRole, error) {
-	c, err := r.bootstrapClient()
-	if err != nil {
-		return nil, err
-	}
-
-	err = c.Update()
+	_, err := r.Update()
 	if err != nil {
-		if err, ok := err.(signed.ErrExpired); ok {
-			return nil, ErrExpired{err}
-		}
 		return nil, err
 	}
 
@@ -487,16 +480,8 @@ func (r *NotaryRepository) listSubtree(targets map[string]*TargetWithRole, role
 // will be returned
 // See the IMPORTANT section on ListTargets above. Those roles also apply here.
 func (r *NotaryRepository) GetTargetByName(name string, roles ...string) (*TargetWithRole, error) {
-	c, err := r.bootstrapClient()
-	if err != nil {
-		return nil, err
-	}
-
-	err = c.Update()
+	c, err := r.Update()
 	if err != nil {
-		if err, ok := err.(signed.ErrExpired); ok {
-			return nil, ErrExpired{err}
-		}
 		return nil, err
 	}
 
@@ -529,47 +514,33 @@ func (r *NotaryRepository) GetChangelist() (changelist.Changelist, error) {
 // Conceptually it performs an operation similar to a `git rebase`
 func (r *NotaryRepository) Publish() error {
 	var initialPublish bool
-	// attempt to initialize the repo from the remote store
-	c, err := r.bootstrapClient()
+	// update first before publishing
+	_, err := r.Update()
 	if err != nil {
-		if _, ok := err.(store.ErrMetaNotFound); ok {
-			// if the remote store return a 404 (translated into ErrMetaNotFound),
-			// there is no trust data for yet. Attempt to load it from disk.
+		// If the remote is not aware of the repo, then this is being published
+		// for the first time.  Try to load from disk instead for publishing.
+		if _, ok := err.(ErrRepositoryNotExist); ok {
 			err := r.bootstrapRepo()
 			if err != nil {
-				// There are lots of reasons there might be an error, such as
-				// corrupt metadata.  We need better errors from bootstrapRepo.
 				logrus.Debugf("Unable to load repository from local files: %s",
 					err.Error())
 				if _, ok := err.(store.ErrMetaNotFound); ok {
-					return &ErrRepoNotInitialized{}
+					return ErrRepoNotInitialized{}
 				}
 				return err
 			}
-			// We had local data but the server doesn't know about the repo yet,
-			// ensure we will push the initial root and targets file.  Either or
+			// Ensure we will push the initial root and targets file.  Either or
 			// both of the root and targets may not be marked as Dirty, since
 			// there may not be any changes that update them, so use a
 			// different boolean.
 			initialPublish = true
 		} else {
-			// The remote store returned an error other than 404. We're
-			// unable to determine if the repo has been initialized or not.
+			// We could not update, so we cannot publish.
 			logrus.Error("Could not publish Repository: ", err.Error())
 			return err
 		}
-	} else {
-		// If we were successfully able to bootstrap the client (which only pulls
-		// root.json), update it with the rest of the tuf metadata in
-		// preparation for applying the changelist.
-		err = c.Update()
-		if err != nil {
-			if err, ok := err.(signed.ErrExpired); ok {
-				return ErrExpired{err}
-			}
-			return err
-		}
 	}
+
 	cl, err := r.GetChangelist()
 	if err != nil {
 		return err
@@ -719,7 +690,7 @@ func (r *NotaryRepository) saveMetadata(ignoreSnapshot bool) error {
 		if err != nil {
 			return err
 		}
-		targetsJSON, err := json.Marshal(signedTargets)
+		targetsJSON, err := json.MarshalCanonical(signedTargets)
 		if err != nil {
 			return err
 		}
@@ -744,6 +715,28 @@ func (r *NotaryRepository) saveMetadata(ignoreSnapshot bool) error {
 	return r.fileStore.SetMeta(data.CanonicalSnapshotRole, snapshotJSON)
 }
 
+// Update bootstraps a trust anchor (root.json) before updating all the
+// metadata from the repo.
+func (r *NotaryRepository) Update() (*tufclient.Client, error) {
+	c, err := r.bootstrapClient()
+	if err != nil {
+		if _, ok := err.(store.ErrMetaNotFound); ok {
+			host := r.baseURL
+			parsed, err := url.Parse(r.baseURL)
+			if err == nil {
+				host = parsed.Host // try to exclude the scheme and any paths
+			}
+			return nil, ErrRepositoryNotExist{remote: host, gun: r.gun}
+		}
+		return nil, err
+	}
+	err = c.Update()
+	if err != nil {
+		return nil, err
+	}
+	return c, nil
+}
+
 func (r *NotaryRepository) bootstrapClient() (*tufclient.Client, error) {
 	var rootJSON []byte
 	remote, err := getRemoteStore(r.baseURL, r.gun, r.roundTrip)
@@ -845,7 +838,7 @@ func (r *NotaryRepository) rootFileKeyChange(role, action string, key data.Publi
 		RoleName: role,
 		Keys:     kl,
 	}
-	metaJSON, err := json.Marshal(meta)
+	metaJSON, err := json.MarshalCanonical(meta)
 	if err != nil {
 		return err
 	}

+ 3 - 2
vendor/src/github.com/docker/notary/client/helpers.go

@@ -1,13 +1,14 @@
 package client
 
 import (
-	"encoding/json"
 	"fmt"
 	"net/http"
 	"path"
 	"time"
 
 	"github.com/Sirupsen/logrus"
+	"github.com/jfrazelle/go/canonical/json"
+
 	"github.com/docker/notary/client/changelist"
 	tuf "github.com/docker/notary/tuf"
 	"github.com/docker/notary/tuf/data"
@@ -261,5 +262,5 @@ func serializeCanonicalRole(tufRepo *tuf.Repo, role string) (out []byte, err err
 		return
 	}
 
-	return json.Marshal(s)
+	return json.MarshalCanonical(s)
 }

+ 1 - 0
vendor/src/github.com/docker/notary/trustmanager/yubikey/pkcs11_linux.go

@@ -4,6 +4,7 @@ package yubikey
 
 var possiblePkcs11Libs = []string{
 	"/usr/lib/libykcs11.so",
+	"/usr/lib64/libykcs11.so",
 	"/usr/lib/x86_64-linux-gnu/libykcs11.so",
 	"/usr/local/lib/libykcs11.so",
 }

+ 5 - 6
vendor/src/github.com/docker/notary/tuf/client/client.go

@@ -97,7 +97,7 @@ func (c *Client) update() error {
 // hash and size in snapshot are unchanged but the root file has expired,
 // there is little expectation that the situation can be remedied.
 func (c Client) checkRoot() error {
-	role := data.RoleName("root")
+	role := data.CanonicalRootRole
 	size := c.local.Snapshot.Signed.Meta[role].Length
 	hashSha256 := c.local.Snapshot.Signed.Meta[role].Hashes["sha256"]
 
@@ -129,7 +129,7 @@ func (c Client) checkRoot() error {
 
 // downloadRoot is responsible for downloading the root.json
 func (c *Client) downloadRoot() error {
-	role := data.RoleName("root")
+	role := data.CanonicalRootRole
 	size := maxSize
 	var expectedSha256 []byte
 	if c.local.Snapshot != nil {
@@ -241,7 +241,7 @@ func (c Client) verifyRoot(role string, s *data.Signed, minVersion int) error {
 // use cache if the download fails (and the cache is still valid).
 func (c *Client) downloadTimestamp() error {
 	logrus.Debug("downloadTimestamp")
-	role := data.RoleName("timestamp")
+	role := data.CanonicalTimestampRole
 
 	// We may not have a cached timestamp if this is the first time
 	// we're interacting with the repo. This will result in the
@@ -272,7 +272,7 @@ func (c *Client) downloadTimestamp() error {
 			if err == nil {
 				// couldn't retrieve data from server and don't have valid
 				// data in cache.
-				return store.ErrMetaNotFound{}
+				return store.ErrMetaNotFound{Resource: data.CanonicalTimestampRole}
 			}
 			return err
 		}
@@ -300,7 +300,7 @@ func (c *Client) downloadTimestamp() error {
 // downloadSnapshot is responsible for downloading the snapshot.json
 func (c *Client) downloadSnapshot() error {
 	logrus.Debug("downloadSnapshot")
-	role := data.RoleName("snapshot")
+	role := data.CanonicalSnapshotRole
 	if c.local.Timestamp == nil {
 		return ErrMissingMeta{role: "snapshot"}
 	}
@@ -379,7 +379,6 @@ func (c *Client) downloadTargets(role string) error {
 		if err != nil {
 			return err
 		}
-		role = data.RoleName(role) // this will really only do something for base targets role
 		if c.local.Snapshot == nil {
 			return ErrMissingMeta{role: role}
 		}

+ 12 - 59
vendor/src/github.com/docker/notary/tuf/data/roles.go

@@ -15,17 +15,18 @@ const (
 	CanonicalTimestampRole = "timestamp"
 )
 
-// ValidRoles holds an overrideable mapping of canonical role names
-// to any custom roles names a user wants to make use of. This allows
-// us to be internally consistent while using different roles in the
-// public TUF files.
-var ValidRoles = map[string]string{
-	CanonicalRootRole:      CanonicalRootRole,
-	CanonicalTargetsRole:   CanonicalTargetsRole,
-	CanonicalSnapshotRole:  CanonicalSnapshotRole,
-	CanonicalTimestampRole: CanonicalTimestampRole,
+// BaseRoles is an easy to iterate list of the top level
+// roles.
+var BaseRoles = []string{
+	CanonicalRootRole,
+	CanonicalTargetsRole,
+	CanonicalSnapshotRole,
+	CanonicalTimestampRole,
 }
 
+// Regex for validating delegation names
+var delegationRegexp = regexp.MustCompile("^[-a-z0-9_/]+$")
+
 // ErrNoSuchRole indicates the roles doesn't exist
 type ErrNoSuchRole struct {
 	Role string
@@ -50,62 +51,15 @@ func (e ErrInvalidRole) Error() string {
 	return fmt.Sprintf("tuf: invalid role %s.", e.Role)
 }
 
-// SetValidRoles is a utility function to override some or all of the roles
-func SetValidRoles(rs map[string]string) {
-	// iterate ValidRoles
-	for k := range ValidRoles {
-		if v, ok := rs[k]; ok {
-			ValidRoles[k] = v
-		}
-	}
-}
-
-// RoleName returns the (possibly overridden) role name for the provided
-// canonical role name
-func RoleName(canonicalRole string) string {
-	if r, ok := ValidRoles[canonicalRole]; ok {
-		return r
-	}
-	return canonicalRole
-}
-
-// CanonicalRole does a reverse lookup to get the canonical role name
-// from the (possibly overridden) role name
-func CanonicalRole(role string) string {
-	name := strings.ToLower(role)
-	if _, ok := ValidRoles[name]; ok {
-		// The canonical version is always lower case
-		// se ensure we return name, not role
-		return name
-	}
-	targetsBase := fmt.Sprintf("%s/", ValidRoles[CanonicalTargetsRole])
-	if strings.HasPrefix(name, targetsBase) {
-		role = strings.TrimPrefix(role, targetsBase)
-		role = fmt.Sprintf("%s/%s", CanonicalTargetsRole, role)
-		return role
-	}
-	for r, v := range ValidRoles {
-		if role == v {
-			return r
-		}
-	}
-	return ""
-}
-
 // ValidRole only determines the name is semantically
 // correct. For target delegated roles, it does NOT check
 // the the appropriate parent roles exist.
 func ValidRole(name string) bool {
-	name = strings.ToLower(name)
-	if v, ok := ValidRoles[name]; ok {
-		return name == v
-	}
-
 	if IsDelegation(name) {
 		return true
 	}
 
-	for _, v := range ValidRoles {
+	for _, v := range BaseRoles {
 		if name == v {
 			return true
 		}
@@ -115,9 +69,8 @@ func ValidRole(name string) bool {
 
 // IsDelegation checks if the role is a delegation or a root role
 func IsDelegation(role string) bool {
-	targetsBase := ValidRoles[CanonicalTargetsRole] + "/"
+	targetsBase := CanonicalTargetsRole + "/"
 
-	delegationRegexp := regexp.MustCompile("^[-a-z0-9_/]+$")
 	whitelistedChars := delegationRegexp.MatchString(role)
 
 	// Limit size of full role string to 255 chars for db column size limit

+ 4 - 4
vendor/src/github.com/docker/notary/tuf/data/snapshot.go

@@ -27,12 +27,12 @@ type Snapshot struct {
 // and targets objects
 func NewSnapshot(root *Signed, targets *Signed) (*SignedSnapshot, error) {
 	logrus.Debug("generating new snapshot...")
-	targetsJSON, err := json.Marshal(targets)
+	targetsJSON, err := json.MarshalCanonical(targets)
 	if err != nil {
 		logrus.Debug("Error Marshalling Targets")
 		return nil, err
 	}
-	rootJSON, err := json.Marshal(root)
+	rootJSON, err := json.MarshalCanonical(root)
 	if err != nil {
 		logrus.Debug("Error Marshalling Root")
 		return nil, err
@@ -52,8 +52,8 @@ func NewSnapshot(root *Signed, targets *Signed) (*SignedSnapshot, error) {
 			Version: 0,
 			Expires: DefaultExpires("snapshot"),
 			Meta: Files{
-				ValidRoles["root"]:    rootMeta,
-				ValidRoles["targets"]: targetsMeta,
+				CanonicalRootRole:    rootMeta,
+				CanonicalTargetsRole: targetsMeta,
 			},
 		},
 	}, nil

+ 2 - 2
vendor/src/github.com/docker/notary/tuf/data/timestamp.go

@@ -24,7 +24,7 @@ type Timestamp struct {
 
 // NewTimestamp initializes a timestamp with an existing snapshot
 func NewTimestamp(snapshot *Signed) (*SignedTimestamp, error) {
-	snapshotJSON, err := json.Marshal(snapshot)
+	snapshotJSON, err := json.MarshalCanonical(snapshot)
 	if err != nil {
 		return nil, err
 	}
@@ -39,7 +39,7 @@ func NewTimestamp(snapshot *Signed) (*SignedTimestamp, error) {
 			Version: 0,
 			Expires: DefaultExpires("timestamp"),
 			Meta: Files{
-				ValidRoles["snapshot"]: snapshotMeta,
+				CanonicalSnapshotRole: snapshotMeta,
 			},
 		},
 	}, nil

+ 0 - 1
vendor/src/github.com/docker/notary/tuf/data/types.go

@@ -62,7 +62,6 @@ func ValidTUFType(typ, role string) bool {
 	if ValidRole(role) {
 		// All targets delegation roles must have
 		// the valid type is for targets.
-		role = CanonicalRole(role)
 		if role == "" {
 			// role is unknown and does not map to
 			// a type

+ 2 - 2
vendor/src/github.com/docker/notary/tuf/store/errors.go

@@ -5,9 +5,9 @@ import "fmt"
 // ErrMetaNotFound indicates we did not find a particular piece
 // of metadata in the store
 type ErrMetaNotFound struct {
-	Role string
+	Resource string
 }
 
 func (err ErrMetaNotFound) Error() string {
-	return fmt.Sprintf("%s trust data unavailable", err.Role)
+	return fmt.Sprintf("%s trust data unavailable.  Has a notary repository been initialized?", err.Resource)
 }

+ 1 - 1
vendor/src/github.com/docker/notary/tuf/store/filestore.go

@@ -46,7 +46,7 @@ func (f *FilesystemStore) GetMeta(name string, size int64) ([]byte, error) {
 	meta, err := ioutil.ReadFile(path)
 	if err != nil {
 		if os.IsNotExist(err) {
-			err = ErrMetaNotFound{Role: name}
+			err = ErrMetaNotFound{Resource: name}
 		}
 		return nil, err
 	}

+ 2 - 2
vendor/src/github.com/docker/notary/tuf/store/memorystore.go

@@ -39,7 +39,7 @@ func (m *memoryStore) GetMeta(name string, size int64) ([]byte, error) {
 		}
 		return d[:size], nil
 	}
-	return nil, ErrMetaNotFound{}
+	return nil, ErrMetaNotFound{Resource: name}
 }
 
 func (m *memoryStore) SetMeta(name string, meta []byte) error {
@@ -75,7 +75,7 @@ func (m *memoryStore) WalkStagedTargets(paths []string, targetsFn targetsWalkFun
 	for _, path := range paths {
 		dat, ok := m.files[path]
 		if !ok {
-			return ErrMetaNotFound{}
+			return ErrMetaNotFound{Resource: path}
 		}
 		meta, err := data.NewFileMeta(bytes.NewReader(dat), "sha256")
 		if err != nil {

+ 14 - 13
vendor/src/github.com/docker/notary/tuf/tuf.go

@@ -5,13 +5,14 @@ import (
 	"bytes"
 	"crypto/sha256"
 	"encoding/hex"
-	"encoding/json"
 	"fmt"
 	"path"
 	"strings"
 	"time"
 
 	"github.com/Sirupsen/logrus"
+	"github.com/jfrazelle/go/canonical/json"
+
 	"github.com/docker/notary/tuf/data"
 	"github.com/docker/notary/tuf/keys"
 	"github.com/docker/notary/tuf/signed"
@@ -306,7 +307,7 @@ func (tr *Repo) DeleteDelegation(role data.Role) error {
 	return nil
 }
 
-// InitRepo creates the base files for a repo. It inspects data.ValidRoles and
+// InitRepo creates the base files for a repo. It inspects data.BaseRoles and
 // data.ValidTypes to determine what the role names and filename should be. It
 // also relies on the keysDB having already been populated with the keys and
 // roles.
@@ -328,7 +329,7 @@ func (tr *Repo) InitRepo(consistent bool) error {
 func (tr *Repo) InitRoot(consistent bool) error {
 	rootRoles := make(map[string]*data.RootRole)
 	rootKeys := make(map[string]data.PublicKey)
-	for _, r := range data.ValidRoles {
+	for _, r := range data.BaseRoles {
 		role := tr.keysDB.GetRole(r)
 		if role == nil {
 			return data.ErrInvalidRole{Role: data.CanonicalRootRole, Reason: "root role not initialized in key database"}
@@ -352,14 +353,14 @@ func (tr *Repo) InitRoot(consistent bool) error {
 // InitTargets initializes an empty targets, and returns the new empty target
 func (tr *Repo) InitTargets(role string) (*data.SignedTargets, error) {
 	r := data.Role{Name: role}
-	if !r.IsDelegation() && data.CanonicalRole(role) != data.CanonicalTargetsRole {
+	if !r.IsDelegation() && role != data.CanonicalTargetsRole {
 		return nil, data.ErrInvalidRole{
 			Role:   role,
 			Reason: fmt.Sprintf("role is not a valid targets role name: %s", role),
 		}
 	}
 	targets := data.NewTargets()
-	tr.Targets[data.RoleName(role)] = targets
+	tr.Targets[role] = targets
 	return targets, nil
 }
 
@@ -373,10 +374,10 @@ func (tr *Repo) InitSnapshot() error {
 		return err
 	}
 
-	if _, ok := tr.Targets[data.RoleName(data.CanonicalTargetsRole)]; !ok {
+	if _, ok := tr.Targets[data.CanonicalTargetsRole]; !ok {
 		return ErrNotLoaded{role: "targets"}
 	}
-	targets, err := tr.Targets[data.RoleName(data.CanonicalTargetsRole)].ToSigned()
+	targets, err := tr.Targets[data.CanonicalTargetsRole].ToSigned()
 	if err != nil {
 		return err
 	}
@@ -573,7 +574,7 @@ func (tr *Repo) AddTargets(role string, targets data.Files) (data.Files, error)
 	for path, target := range targets {
 		pathDigest := sha256.Sum256([]byte(path))
 		pathHex := hex.EncodeToString(pathDigest[:])
-		if role == data.ValidRoles["targets"] || (r.CheckPaths(path) || r.CheckPrefixes(pathHex)) {
+		if role == data.CanonicalTargetsRole || (r.CheckPaths(path) || r.CheckPrefixes(pathHex)) {
 			t.Signed.Targets[path] = target
 		} else {
 			invalid[path] = target
@@ -606,7 +607,7 @@ func (tr *Repo) RemoveTargets(role string, targets ...string) error {
 
 // UpdateSnapshot updates the FileMeta for the given role based on the Signed object
 func (tr *Repo) UpdateSnapshot(role string, s *data.Signed) error {
-	jsonData, err := json.Marshal(s)
+	jsonData, err := json.MarshalCanonical(s)
 	if err != nil {
 		return err
 	}
@@ -621,7 +622,7 @@ func (tr *Repo) UpdateSnapshot(role string, s *data.Signed) error {
 
 // UpdateTimestamp updates the snapshot meta in the timestamp based on the Signed object
 func (tr *Repo) UpdateTimestamp(s *data.Signed) error {
-	jsonData, err := json.Marshal(s)
+	jsonData, err := json.MarshalCanonical(s)
 	if err != nil {
 		return err
 	}
@@ -639,7 +640,7 @@ func (tr *Repo) SignRoot(expires time.Time) (*data.Signed, error) {
 	logrus.Debug("signing root...")
 	tr.Root.Signed.Expires = expires
 	tr.Root.Signed.Version++
-	root := tr.keysDB.GetRole(data.ValidRoles["root"])
+	root := tr.keysDB.GetRole(data.CanonicalRootRole)
 	signed, err := tr.Root.ToSigned()
 	if err != nil {
 		return nil, err
@@ -707,7 +708,7 @@ func (tr *Repo) SignSnapshot(expires time.Time) (*data.Signed, error) {
 	if err != nil {
 		return nil, err
 	}
-	snapshot := tr.keysDB.GetRole(data.ValidRoles["snapshot"])
+	snapshot := tr.keysDB.GetRole(data.CanonicalSnapshotRole)
 	signed, err = tr.sign(signed, *snapshot)
 	if err != nil {
 		return nil, err
@@ -733,7 +734,7 @@ func (tr *Repo) SignTimestamp(expires time.Time) (*data.Signed, error) {
 	if err != nil {
 		return nil, err
 	}
-	timestamp := tr.keysDB.GetRole(data.ValidRoles["timestamp"])
+	timestamp := tr.keysDB.GetRole(data.CanonicalTimestampRole)
 	signed, err = tr.sign(signed, *timestamp)
 	if err != nil {
 		return nil, err