From cb2dd07edcd6e9b7a8c50bb084e65b4264c79cd2 Mon Sep 17 00:00:00 2001 From: David Lawrence Date: Wed, 24 Feb 2016 11:13:37 -0800 Subject: [PATCH] the server was not setting the longer snapshot expiry time. When generating a timestamp it was also retriving the snapshot directly from the database and only validating the checksum still matched what was in the timestamp. Due to the addition of consistent downloads, this mean a new snapshot never got generated. It is necessary for GetOrCreateTimestamp to call GetOrCreateSnapshot to ensure a new snapshot is generated as and when required Signed-off-by: David Lawrence (github: endophage) --- client/client.go | 8 +------- const.go | 23 +++++++++++++++++++++++ server/server.go | 7 ++----- server/timestamp/timestamp.go | 3 ++- server/timestamp/timestamp_test.go | 18 +++++++++++++++--- tuf/data/types.go | 21 +++++++++++---------- 6 files changed, 54 insertions(+), 26 deletions(-) diff --git a/client/client.go b/client/client.go index 29404971b..cbb497713 100644 --- a/client/client.go +++ b/client/client.go @@ -27,13 +27,7 @@ import ( ) func init() { - data.SetDefaultExpiryTimes( - map[string]int{ - "root": 3650, - "targets": 1095, - "snapshot": 1095, - }, - ) + data.SetDefaultExpiryTimes(notary.NotaryDefaultExpiries) } // ErrRepoNotInitialized is returned when trying to publish an uninitialized diff --git a/const.go b/const.go index bb1d01c80..566c7f0fb 100644 --- a/const.go +++ b/const.go @@ -1,5 +1,9 @@ package notary +import ( + "time" +) + // application wide constants const ( // MaxDownloadSize is the maximum size we'll download for metadata if no limit is given @@ -24,4 +28,23 @@ const ( RootKeysSubdir = "root_keys" // NonRootKeysSubdir is the subdirectory under PrivDir where non-root private keys are stored NonRootKeysSubdir = "tuf_keys" + + // Day is a duration of one day + Day = 24 * time.Hour + Year = 365 * Day + + // NotaryRootExpiry is the duration representing the expiry time of the Root role + NotaryRootExpiry = 10 * Year + NotaryTargetsExpiry = 3 * Year + NotarySnapshotExpiry = 3 * Year + NotaryTimestampExpiry = 14 * Day ) + +// NotaryDefaultExpiries is the construct used to configure the default expiry times of +// the various role files. +var NotaryDefaultExpiries = map[string]time.Duration{ + "root": NotaryRootExpiry, + "targets": NotaryTargetsExpiry, + "snapshot": NotarySnapshotExpiry, + "timestamp": NotaryTimestampExpiry, +} diff --git a/server/server.go b/server/server.go index 98d1d9c68..2f7ccb580 100644 --- a/server/server.go +++ b/server/server.go @@ -9,6 +9,7 @@ import ( "github.com/Sirupsen/logrus" "github.com/docker/distribution/health" "github.com/docker/distribution/registry/auth" + "github.com/docker/notary" "github.com/docker/notary/server/handlers" "github.com/docker/notary/tuf/data" "github.com/docker/notary/tuf/signed" @@ -19,11 +20,7 @@ import ( ) func init() { - data.SetDefaultExpiryTimes( - map[string]int{ - "timestamp": 14, - }, - ) + data.SetDefaultExpiryTimes(notary.NotaryDefaultExpiries) } func prometheusOpts(operation string) prometheus.SummaryOpts { diff --git a/server/timestamp/timestamp.go b/server/timestamp/timestamp.go index c3aaf9971..2322c11cc 100644 --- a/server/timestamp/timestamp.go +++ b/server/timestamp/timestamp.go @@ -8,6 +8,7 @@ import ( "github.com/docker/notary/tuf/signed" "github.com/Sirupsen/logrus" + "github.com/docker/notary/server/snapshot" "github.com/docker/notary/server/storage" ) @@ -49,7 +50,7 @@ func GetOrCreateTimestampKey(gun string, store storage.MetaStore, crypto signed. // a new timestamp is generated either because none exists, or because the current // one has expired. Once generated, the timestamp is saved in the store. func GetOrCreateTimestamp(gun string, store storage.MetaStore, cryptoService signed.CryptoService) ([]byte, error) { - snapshot, err := store.GetCurrent(gun, "snapshot") + snapshot, err := snapshot.GetOrCreateSnapshot(gun, store, cryptoService) if err != nil { return nil, err } diff --git a/server/timestamp/timestamp_test.go b/server/timestamp/timestamp_test.go index acdf7fe97..fe67456e1 100644 --- a/server/timestamp/timestamp_test.go +++ b/server/timestamp/timestamp_test.go @@ -52,7 +52,11 @@ func TestGetTimestamp(t *testing.T) { store := storage.NewMemStorage() crypto := signed.NewEd25519() - snapshot := &data.SignedSnapshot{} + snapshot := &data.SignedSnapshot{ + Signed: data.Snapshot{ + Expires: data.DefaultExpires(data.CanonicalSnapshotRole), + }, + } snapJSON, _ := json.Marshal(snapshot) store.UpdateCurrent("gun", storage.MetaUpdate{Role: "snapshot", Version: 0, Data: snapJSON}) @@ -68,7 +72,11 @@ func TestGetTimestampNewSnapshot(t *testing.T) { store := storage.NewMemStorage() crypto := signed.NewEd25519() - snapshot := data.SignedSnapshot{} + snapshot := &data.SignedSnapshot{ + Signed: data.Snapshot{ + Expires: data.DefaultExpires(data.CanonicalSnapshotRole), + }, + } snapshot.Signed.Version = 0 snapJSON, _ := json.Marshal(snapshot) @@ -80,7 +88,11 @@ func TestGetTimestampNewSnapshot(t *testing.T) { ts1, err := GetOrCreateTimestamp("gun", store, crypto) assert.Nil(t, err, "GetTimestamp errored") - snapshot = data.SignedSnapshot{} + snapshot = &data.SignedSnapshot{ + Signed: data.Snapshot{ + Expires: data.DefaultExpires(data.CanonicalSnapshotRole), + }, + } snapshot.Signed.Version = 1 snapJSON, _ = json.Marshal(snapshot) diff --git a/tuf/data/types.go b/tuf/data/types.go index 6459b8e66..4de55c4e1 100644 --- a/tuf/data/types.go +++ b/tuf/data/types.go @@ -12,6 +12,7 @@ import ( "github.com/Sirupsen/logrus" "github.com/docker/go/canonical/json" + "github.com/docker/notary" ) // SigAlgorithm for types of signatures @@ -171,16 +172,16 @@ func NewDelegations() *Delegations { } } -// defines number of days in which something should expire -var defaultExpiryTimes = map[string]int{ - CanonicalRootRole: 365, - CanonicalTargetsRole: 90, - CanonicalSnapshotRole: 7, - CanonicalTimestampRole: 1, +// These values are recommended TUF expiry times. +var defaultExpiryTimes = map[string]time.Duration{ + CanonicalRootRole: notary.Year, + CanonicalTargetsRole: 90 * notary.Day, + CanonicalSnapshotRole: 7 * notary.Day, + CanonicalTimestampRole: notary.Day, } // SetDefaultExpiryTimes allows one to change the default expiries. -func SetDefaultExpiryTimes(times map[string]int) { +func SetDefaultExpiryTimes(times map[string]time.Duration) { for key, value := range times { if _, ok := defaultExpiryTimes[key]; !ok { logrus.Errorf("Attempted to set default expiry for an unknown role: %s", key) @@ -192,10 +193,10 @@ func SetDefaultExpiryTimes(times map[string]int) { // DefaultExpires gets the default expiry time for the given role func DefaultExpires(role string) time.Time { - var t time.Time - if t, ok := defaultExpiryTimes[role]; ok { - return time.Now().AddDate(0, 0, t) + if d, ok := defaultExpiryTimes[role]; ok { + return time.Now().Add(d) } + var t time.Time return t.UTC().Round(time.Second) }