diff --git a/Dockerfile b/Dockerfile index db5f784f3b..78a986b3db 100644 --- a/Dockerfile +++ b/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" \ diff --git a/api/client/trust.go b/api/client/trust.go index 4ce4d35b5c..256ea5b913 100644 --- a/api/client/trust.go +++ b/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) } diff --git a/hack/vendor.sh b/hack/vendor.sh index 8f57660eb0..8efac86626 100755 --- a/hack/vendor.sh +++ b/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 diff --git a/integration-cli/docker_cli_build_test.go b/integration-cli/docker_cli_build_test.go index 9e0da6d0fa..2560e61450 100644 --- a/integration-cli/docker_cli_build_test.go +++ b/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) } } diff --git a/integration-cli/docker_cli_create_test.go b/integration-cli/docker_cli_create_test.go index cd6f254053..4cb1ed19a4 100644 --- a/integration-cli/docker_cli_create_test.go +++ b/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)) } diff --git a/integration-cli/docker_cli_pull_trusted_test.go b/integration-cli/docker_cli_pull_trusted_test.go index d209a3e35f..024108110f 100644 --- a/integration-cli/docker_cli_pull_trusted_test.go +++ b/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) { diff --git a/integration-cli/docker_cli_run_test.go b/integration-cli/docker_cli_run_test.go index 0efa11249b..f6af44449f 100644 --- a/integration-cli/docker_cli_run_test.go +++ b/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) } } diff --git a/vendor/src/github.com/docker/notary/Dockerfile.signer b/vendor/src/github.com/docker/notary/Dockerfile.signer index 81ce64729e..3ff8523448 100644 --- a/vendor/src/github.com/docker/notary/Dockerfile.signer +++ b/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 diff --git a/vendor/src/github.com/docker/notary/client/client.go b/vendor/src/github.com/docker/notary/client/client.go index 26aeea8f1c..07edc6e972 100644 --- a/vendor/src/github.com/docker/notary/client/client.go +++ b/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,19 +420,11 @@ 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() + _, err := r.Update() if err != nil { return nil, err } - err = c.Update() - if err != nil { - if err, ok := err.(signed.ErrExpired); ok { - return nil, ErrExpired{err} - } - return nil, err - } - if len(roles) == 0 { roles = []string{data.CanonicalTargetsRole} } @@ -487,19 +480,11 @@ 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() + c, err := r.Update() if err != nil { return nil, err } - err = c.Update() - if err != nil { - if err, ok := err.(signed.ErrExpired); ok { - return nil, ErrExpired{err} - } - return nil, err - } - if len(roles) == 0 { roles = append(roles, data.CanonicalTargetsRole) } @@ -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 } diff --git a/vendor/src/github.com/docker/notary/client/helpers.go b/vendor/src/github.com/docker/notary/client/helpers.go index 23b9249561..ddc606e0af 100644 --- a/vendor/src/github.com/docker/notary/client/helpers.go +++ b/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) } diff --git a/vendor/src/github.com/docker/notary/trustmanager/yubikey/pkcs11_linux.go b/vendor/src/github.com/docker/notary/trustmanager/yubikey/pkcs11_linux.go index 61c7f14810..9967e89e19 100644 --- a/vendor/src/github.com/docker/notary/trustmanager/yubikey/pkcs11_linux.go +++ b/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", } diff --git a/vendor/src/github.com/docker/notary/tuf/client/client.go b/vendor/src/github.com/docker/notary/tuf/client/client.go index bc60b8dc77..9d28a8c129 100644 --- a/vendor/src/github.com/docker/notary/tuf/client/client.go +++ b/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} } diff --git a/vendor/src/github.com/docker/notary/tuf/data/roles.go b/vendor/src/github.com/docker/notary/tuf/data/roles.go index 823105c4e5..25e9ba4572 100644 --- a/vendor/src/github.com/docker/notary/tuf/data/roles.go +++ b/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 diff --git a/vendor/src/github.com/docker/notary/tuf/data/snapshot.go b/vendor/src/github.com/docker/notary/tuf/data/snapshot.go index 2535e8c05d..2d02cf1ec0 100644 --- a/vendor/src/github.com/docker/notary/tuf/data/snapshot.go +++ b/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 diff --git a/vendor/src/github.com/docker/notary/tuf/data/timestamp.go b/vendor/src/github.com/docker/notary/tuf/data/timestamp.go index 912682a2e3..68d0b9f558 100644 --- a/vendor/src/github.com/docker/notary/tuf/data/timestamp.go +++ b/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 diff --git a/vendor/src/github.com/docker/notary/tuf/data/types.go b/vendor/src/github.com/docker/notary/tuf/data/types.go index 94614804e7..61a311664f 100644 --- a/vendor/src/github.com/docker/notary/tuf/data/types.go +++ b/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 diff --git a/vendor/src/github.com/docker/notary/tuf/store/errors.go b/vendor/src/github.com/docker/notary/tuf/store/errors.go index 902edf8c08..a7f63d6bbd 100644 --- a/vendor/src/github.com/docker/notary/tuf/store/errors.go +++ b/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) } diff --git a/vendor/src/github.com/docker/notary/tuf/store/filestore.go b/vendor/src/github.com/docker/notary/tuf/store/filestore.go index 7e7ea02f8c..6ce39ed3ec 100644 --- a/vendor/src/github.com/docker/notary/tuf/store/filestore.go +++ b/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 } diff --git a/vendor/src/github.com/docker/notary/tuf/store/memorystore.go b/vendor/src/github.com/docker/notary/tuf/store/memorystore.go index 0e17889891..5d3e44beb3 100644 --- a/vendor/src/github.com/docker/notary/tuf/store/memorystore.go +++ b/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 { diff --git a/vendor/src/github.com/docker/notary/tuf/tuf.go b/vendor/src/github.com/docker/notary/tuf/tuf.go index 09b8bb6b1c..39d7aa6bf5 100644 --- a/vendor/src/github.com/docker/notary/tuf/tuf.go +++ b/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