Change minimum required version of metadata to be 1, not 0

Signed-off-by: Ying Li <ying.li@docker.com>
This commit is contained in:
Ying Li 2016-04-22 10:35:15 -07:00
parent 5d1b4bc6ec
commit ab7064ea12
16 changed files with 128 additions and 86 deletions

View File

@ -660,7 +660,7 @@ func (r *NotaryRepository) bootstrapRepo() error {
}
return err
}
if err := b.Load(role, jsonBytes, 0, true); err != nil {
if err := b.Load(role, jsonBytes, 1, true); err != nil {
return err
}
}
@ -769,7 +769,7 @@ func (r *NotaryRepository) Update(forWrite bool) error {
// Returns a tufclient.Client for the remote server, which may not be actually
// operational (if the URL is invalid but a root.json is cached).
func (r *NotaryRepository) bootstrapClient(checkInitialized bool) (*tufclient.Client, error) {
minVersion := 0
minVersion := 1
oldBuilder := tuf.NewRepoBuilder(r.gun, r.CryptoService, r.trustPinning)
var newBuilder tuf.RepoBuilder

View File

@ -44,7 +44,7 @@ func validateUpdate(cs signed.CryptoService, gun string, updates []storage.MetaU
if rootUpdate, ok := roles[data.CanonicalRootRole]; ok {
builder = builder.BootstrapNewBuilder()
if err := builder.Load(data.CanonicalRootRole, rootUpdate.Data, 0, false); err != nil {
if err := builder.Load(data.CanonicalRootRole, rootUpdate.Data, 1, false); err != nil {
return nil, validation.ErrBadRoot{Msg: err.Error()}
}
@ -67,7 +67,7 @@ func validateUpdate(cs signed.CryptoService, gun string, updates []storage.MetaU
// At this point, root and targets must have been loaded into the repo
if snapshotUpdate, ok := roles[data.CanonicalSnapshotRole]; ok {
if err := builder.Load(data.CanonicalSnapshotRole, snapshotUpdate.Data, 0, false); err != nil {
if err := builder.Load(data.CanonicalSnapshotRole, snapshotUpdate.Data, 1, false); err != nil {
return nil, validation.ErrBadSnapshot{Msg: err.Error()}
}
logrus.Debug("Successfully validated snapshot")
@ -131,7 +131,7 @@ func loadAndValidateTargets(gun string, builder tuf.RepoBuilder, roles map[strin
}
}
if err := builder.Load(roleName, roles[roleName].Data, 0, false); err != nil {
if err := builder.Load(roleName, roles[roleName].Data, 1, false); err != nil {
logrus.Error("ErrBadTargets: ", err.Error())
return nil, validation.ErrBadTargets{Msg: err.Error()}
}
@ -223,7 +223,7 @@ func loadFromStore(gun, roleName string, builder tuf.RepoBuilder, store storage.
if err != nil {
return err
}
if err := builder.Load(roleName, metaJSON, 0, true); err != nil {
if err := builder.Load(roleName, metaJSON, 1, true); err != nil {
return err
}
return nil

View File

@ -76,7 +76,7 @@ func GetOrCreateSnapshot(gun, checksum string, store storage.MetaStore, cryptoSe
logrus.Debug("Previous snapshot, but no root for GUN ", gun)
return nil, nil, err
}
if err := builder.Load(data.CanonicalRootRole, rootJSON, 0, false); err != nil {
if err := builder.Load(data.CanonicalRootRole, rootJSON, 1, false); err != nil {
logrus.Debug("Could not load valid previous root for GUN ", gun)
return nil, nil, err
}

View File

@ -144,13 +144,13 @@ func createTimestamp(gun string, prev *data.SignedTimestamp, snapshot []byte, st
logrus.Debug("Previous timestamp, but no root for GUN ", gun)
return nil, err
}
if err := builder.Load(data.CanonicalRootRole, root, 0, false); err != nil {
if err := builder.Load(data.CanonicalRootRole, root, 1, false); err != nil {
logrus.Debug("Could not load valid previous root for GUN ", gun)
return nil, err
}
// load snapshot so we can include it in timestamp
if err := builder.Load(data.CanonicalSnapshotRole, snapshot, 0, false); err != nil {
if err := builder.Load(data.CanonicalSnapshotRole, snapshot, 1, false); err != nil {
logrus.Debug("Could not load valid previous snapshot for GUN ", gun)
return nil, err
}

View File

@ -467,6 +467,7 @@ func TestValidateRootWithPinnedCA(t *testing.T) {
data.CanonicalSnapshotRole: &rootRole.RootRole},
false,
)
testRoot.Signed.Version = 1
require.NoError(t, err, "Failed to create new root")
keyReader, err := os.Open("../fixtures/notary-signer.key")
@ -581,6 +582,7 @@ func testValidateSuccessfulRootRotation(t *testing.T, keyAlg, rootKeyType string
},
false,
)
origTestRoot.Signed.Version = 1
require.NoError(t, err, "Failed to create new root")
signedOrigTestRoot, err := origTestRoot.ToSigned()
@ -607,6 +609,7 @@ func testValidateSuccessfulRootRotation(t *testing.T, keyAlg, rootKeyType string
data.CanonicalSnapshotRole: &rootRole.RootRole},
false,
)
testRoot.Signed.Version = 1
require.NoError(t, err, "Failed to create new root")
signedTestRoot, err := testRoot.ToSigned()
@ -659,6 +662,7 @@ func testValidateRootRotationMissingOrigSig(t *testing.T, keyAlg, rootKeyType st
},
false,
)
origTestRoot.Signed.Version = 1
require.NoError(t, err, "Failed to create new root")
signedOrigTestRoot, err := origTestRoot.ToSigned()
@ -734,6 +738,7 @@ func testValidateRootRotationMissingNewSig(t *testing.T, keyAlg, rootKeyType str
},
false,
)
origTestRoot.Signed.Version = 1
require.NoError(t, err, "Failed to create new root")
signedOrigTestRoot, err := origTestRoot.ToSigned()

View File

@ -166,7 +166,8 @@ func (rb *repoBuilder) IsLoaded(roleName string) bool {
}
}
// GetLoadedVersion returns the metadata version, if it is loaded, or 0 otherwise
// GetLoadedVersion returns the metadata version, if it is loaded, or 1 (the
// minimum valid version number) otherwise
func (rb *repoBuilder) GetLoadedVersion(roleName string) int {
switch {
case roleName == data.CanonicalRootRole && rb.repo.Root != nil:
@ -181,7 +182,7 @@ func (rb *repoBuilder) GetLoadedVersion(roleName string) int {
}
}
return 0
return 1
}
// GetConsistentInfo returns the consistent name and size of a role, if it is known,

View File

@ -40,7 +40,7 @@ func getSampleMeta(t *testing.T) (map[string][]byte, string) {
func TestBuilderLoadsValidRolesOnly(t *testing.T) {
meta, gun := getSampleMeta(t)
builder := tuf.NewRepoBuilder(gun, nil, trustpinning.TrustPinConfig{})
err := builder.Load("NotRoot", meta[data.CanonicalRootRole], 0, false)
err := builder.Load("NotRoot", meta[data.CanonicalRootRole], 1, false)
require.Error(t, err)
require.IsType(t, tuf.ErrInvalidBuilderInput{}, err)
require.Contains(t, err.Error(), "is an invalid role")
@ -52,17 +52,17 @@ func TestBuilderOnlyAcceptsRootFirstWhenLoading(t *testing.T) {
for roleName, content := range meta {
if roleName != data.CanonicalRootRole {
err := builder.Load(roleName, content, 0, true)
err := builder.Load(roleName, content, 1, true)
require.Error(t, err)
require.IsType(t, tuf.ErrInvalidBuilderInput{}, err)
require.Contains(t, err.Error(), "root must be loaded first")
require.False(t, builder.IsLoaded(roleName))
require.Equal(t, 0, builder.GetLoadedVersion(roleName))
require.Equal(t, 1, builder.GetLoadedVersion(roleName))
}
}
// we can load the root
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
require.True(t, builder.IsLoaded(data.CanonicalRootRole))
}
@ -71,31 +71,31 @@ func TestBuilderOnlyAcceptsDelegationsAfterParent(t *testing.T) {
builder := tuf.NewRepoBuilder(gun, nil, trustpinning.TrustPinConfig{})
// load the root
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
// delegations can't be loaded without target
for _, delgName := range []string{"targets/a", "targets/a/b"} {
err := builder.Load(delgName, meta[delgName], 0, false)
err := builder.Load(delgName, meta[delgName], 1, false)
require.Error(t, err)
require.IsType(t, tuf.ErrInvalidBuilderInput{}, err)
require.Contains(t, err.Error(), "targets must be loaded first")
require.False(t, builder.IsLoaded(delgName))
require.Equal(t, 0, builder.GetLoadedVersion(delgName))
require.Equal(t, 1, builder.GetLoadedVersion(delgName))
}
// load the targets
require.NoError(t, builder.Load(data.CanonicalTargetsRole, meta[data.CanonicalTargetsRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalTargetsRole, meta[data.CanonicalTargetsRole], 1, false))
// targets/a/b can't be loaded because targets/a isn't loaded
err := builder.Load("targets/a/b", meta["targets/a/b"], 0, false)
err := builder.Load("targets/a/b", meta["targets/a/b"], 1, false)
require.Error(t, err)
require.IsType(t, data.ErrInvalidRole{}, err)
// targets/a can be loaded now though because targets is loaded
require.NoError(t, builder.Load("targets/a", meta["targets/a"], 0, false))
require.NoError(t, builder.Load("targets/a", meta["targets/a"], 1, false))
// and now targets/a/b can be loaded because targets/a is loaded
require.NoError(t, builder.Load("targets/a/b", meta["targets/a/b"], 0, false))
require.NoError(t, builder.Load("targets/a/b", meta["targets/a/b"], 1, false))
}
func TestBuilderAcceptRoleOnce(t *testing.T) {
@ -104,12 +104,12 @@ func TestBuilderAcceptRoleOnce(t *testing.T) {
for _, roleName := range append(data.BaseRoles, "targets/a", "targets/a/b") {
// first time loading is ok
require.NoError(t, builder.Load(roleName, meta[roleName], 0, false))
require.NoError(t, builder.Load(roleName, meta[roleName], 1, false))
require.True(t, builder.IsLoaded(roleName))
require.Equal(t, 1, builder.GetLoadedVersion(roleName))
// second time loading is not
err := builder.Load(roleName, meta[roleName], 0, false)
err := builder.Load(roleName, meta[roleName], 1, false)
require.Error(t, err)
require.IsType(t, tuf.ErrInvalidBuilderInput{}, err)
require.Contains(t, err.Error(), "has already been loaded")
@ -124,14 +124,14 @@ func TestBuilderStopsAcceptingOrProducingDataOnceDone(t *testing.T) {
builder := tuf.NewRepoBuilder(gun, nil, trustpinning.TrustPinConfig{})
for _, roleName := range data.BaseRoles {
require.NoError(t, builder.Load(roleName, meta[roleName], 0, false))
require.NoError(t, builder.Load(roleName, meta[roleName], 1, false))
require.True(t, builder.IsLoaded(roleName))
}
_, err := builder.Finish()
require.NoError(t, err)
err = builder.Load("targets/a", meta["targets/a"], 0, false)
err = builder.Load("targets/a", meta["targets/a"], 1, false)
require.Error(t, err)
require.Equal(t, tuf.ErrBuildDone, err)
@ -200,7 +200,7 @@ func TestGenerateSnapshotInvalidOperations(t *testing.T) {
// --- we can't generate a snapshot if the targets isn't loaded and we have no previous snapshot,
// --- but if we have a previous snapshot with a valid targets, we're good even if no snapshot
// --- is loaded
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
_, _, err = builder.GenerateSnapshot(prevSnapshot)
if prevSnapshot == nil {
require.IsType(t, tuf.ErrInvalidBuilderInput{}, err)
@ -212,11 +212,11 @@ func TestGenerateSnapshotInvalidOperations(t *testing.T) {
// --- we can't generate a snapshot if we've loaded the timestamp already
builder = tuf.NewRepoBuilder(gun, newCS, trustpinning.TrustPinConfig{})
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
if prevSnapshot == nil {
require.NoError(t, builder.Load(data.CanonicalTargetsRole, meta[data.CanonicalTargetsRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalTargetsRole, meta[data.CanonicalTargetsRole], 1, false))
}
require.NoError(t, builder.Load(data.CanonicalTimestampRole, meta[data.CanonicalTimestampRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalTimestampRole, meta[data.CanonicalTimestampRole], 1, false))
_, _, err = builder.GenerateSnapshot(prevSnapshot)
require.IsType(t, tuf.ErrInvalidBuilderInput{}, err)
@ -225,11 +225,11 @@ func TestGenerateSnapshotInvalidOperations(t *testing.T) {
// --- we cannot generate a snapshot if we've already loaded a snapshot
builder = tuf.NewRepoBuilder(gun, newCS, trustpinning.TrustPinConfig{})
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
if prevSnapshot == nil {
require.NoError(t, builder.Load(data.CanonicalTargetsRole, meta[data.CanonicalTargetsRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalTargetsRole, meta[data.CanonicalTargetsRole], 1, false))
}
require.NoError(t, builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 1, false))
_, _, err = builder.GenerateSnapshot(prevSnapshot)
require.IsType(t, tuf.ErrInvalidBuilderInput{}, err)
@ -239,9 +239,9 @@ func TestGenerateSnapshotInvalidOperations(t *testing.T) {
for i := 0; i < len(snapKeys); i++ {
require.NoError(t, newCS.RemoveKey(snapKeys[i].ID()))
builder = tuf.NewRepoBuilder(gun, newCS, trustpinning.TrustPinConfig{})
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
if prevSnapshot == nil {
require.NoError(t, builder.Load(data.CanonicalTargetsRole, meta[data.CanonicalTargetsRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalTargetsRole, meta[data.CanonicalTargetsRole], 1, false))
}
_, _, err = builder.GenerateSnapshot(prevSnapshot)
@ -251,9 +251,9 @@ func TestGenerateSnapshotInvalidOperations(t *testing.T) {
// --- we cannot generate a snapshot if we don't have a cryptoservice
builder = tuf.NewRepoBuilder(gun, nil, trustpinning.TrustPinConfig{})
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
if prevSnapshot == nil {
require.NoError(t, builder.Load(data.CanonicalTargetsRole, meta[data.CanonicalTargetsRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalTargetsRole, meta[data.CanonicalTargetsRole], 1, false))
}
_, _, err = builder.GenerateSnapshot(prevSnapshot)
@ -265,8 +265,8 @@ func TestGenerateSnapshotInvalidOperations(t *testing.T) {
// --- we can't generate a snapshot if we're given an invalid previous snapshot (for instance, an empty one),
// --- even if we have a targets loaded
builder := tuf.NewRepoBuilder(gun, cs, trustpinning.TrustPinConfig{})
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalTargetsRole, meta[data.CanonicalTargetsRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
require.NoError(t, builder.Load(data.CanonicalTargetsRole, meta[data.CanonicalTargetsRole], 1, false))
_, _, err = builder.GenerateSnapshot(&data.SignedSnapshot{})
require.IsType(t, data.ErrInvalidMetadata{}, err)
@ -302,7 +302,7 @@ func TestGenerateTimestampInvalidOperations(t *testing.T) {
// --- we can't generate a timestamp if the snapshot isn't loaded, no matter if we have a previous
// --- timestamp or not
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
_, _, err = builder.GenerateTimestamp(prevTimestamp)
require.IsType(t, tuf.ErrInvalidBuilderInput{}, err)
require.Contains(t, err.Error(), "snapshot must be loaded first")
@ -310,9 +310,9 @@ func TestGenerateTimestampInvalidOperations(t *testing.T) {
// --- we can't generate a timestamp if we've loaded the timestamp already
builder = tuf.NewRepoBuilder(gun, cs, trustpinning.TrustPinConfig{})
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalTimestampRole, meta[data.CanonicalTimestampRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
require.NoError(t, builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 1, false))
require.NoError(t, builder.Load(data.CanonicalTimestampRole, meta[data.CanonicalTimestampRole], 1, false))
_, _, err = builder.GenerateTimestamp(prevTimestamp)
require.IsType(t, tuf.ErrInvalidBuilderInput{}, err)
@ -322,8 +322,8 @@ func TestGenerateTimestampInvalidOperations(t *testing.T) {
for i := 0; i < len(tsKeys); i++ {
require.NoError(t, cs.RemoveKey(tsKeys[i].ID()))
builder = tuf.NewRepoBuilder(gun, cs, trustpinning.TrustPinConfig{})
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
require.NoError(t, builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 1, false))
_, _, err = builder.GenerateTimestamp(prevTimestamp)
require.IsType(t, signed.ErrInsufficientSignatures{}, err)
@ -332,8 +332,8 @@ func TestGenerateTimestampInvalidOperations(t *testing.T) {
// --- we cannot generate a timestamp if we don't have a cryptoservice
builder = tuf.NewRepoBuilder(gun, nil, trustpinning.TrustPinConfig{})
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
require.NoError(t, builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 1, false))
_, _, err = builder.GenerateTimestamp(prevTimestamp)
require.IsType(t, tuf.ErrInvalidBuilderInput{}, err)
@ -344,8 +344,8 @@ func TestGenerateTimestampInvalidOperations(t *testing.T) {
// --- we can't generate a timsetamp if we're given an invalid previous timestamp (for instance, an empty one),
// --- even if we have a snapshot loaded
builder := tuf.NewRepoBuilder(gun, cs, trustpinning.TrustPinConfig{})
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
require.NoError(t, builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 1, false))
_, _, err = builder.GenerateTimestamp(&data.SignedTimestamp{})
require.IsType(t, data.ErrInvalidMetadata{}, err)
@ -369,11 +369,11 @@ func TestGetConsistentInfo(t *testing.T) {
meta, err := testutils.SignAndSerialize(repo)
require.NoError(t, err)
builder := tuf.NewRepoBuilder(nil, gun, nil, trustpinning.TrustPinConfig{})
builder := tuf.NewRepoBuilder(gun, nil, trustpinning.TrustPinConfig{})
// if neither snapshot nor timestamp are loaded, no matter how much other data is loaded, consistent info
// is empty except for timestamp: timestamps have no checksums, and the length is always -1
for _, roleToLoad := range []string{data.CanonicalRootRole, data.CanonicalTargetsRole} {
require.NoError(t, builder.Load(roleToLoad, meta[roleToLoad], 0, false))
require.NoError(t, builder.Load(roleToLoad, meta[roleToLoad], 1, false))
for _, checkName := range append(data.BaseRoles, extraMeta...) {
ci := builder.GetConsistentInfo(checkName)
require.Equal(t, checkName, ci.ConsistentName())
@ -391,7 +391,7 @@ func TestGetConsistentInfo(t *testing.T) {
}
// once timestamp is loaded, we can get the consistent info for snapshot but nothing else
require.NoError(t, builder.Load(data.CanonicalTimestampRole, meta[data.CanonicalTimestampRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalTimestampRole, meta[data.CanonicalTimestampRole], 1, false))
for _, checkName := range append(data.BaseRoles, extraMeta...) {
ci := builder.GetConsistentInfo(checkName)
@ -416,7 +416,7 @@ func TestGetConsistentInfo(t *testing.T) {
}
// once the snapshot is loaded, we can get real consistent info for all loaded roles
require.NoError(t, builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 1, false))
for _, checkName := range data.BaseRoles {
ci := builder.GetConsistentInfo(checkName)
require.True(t, ci.ChecksumKnown(), "%s's checksum is not known", checkName)
@ -508,35 +508,35 @@ func TestTimestampPreAndPostChecksumming(t *testing.T) {
snapJSON := append(meta[data.CanonicalSnapshotRole], ' ')
// --- load timestamp first
builder := tuf.NewRepoBuilder(nil, gun, nil, trustpinning.TrustPinConfig{})
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
builder := tuf.NewRepoBuilder(gun, nil, trustpinning.TrustPinConfig{})
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
// timestamp doesn't fail, even though its checksum for root is wrong according to timestamp
require.NoError(t, builder.Load(data.CanonicalTimestampRole, meta[data.CanonicalTimestampRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalTimestampRole, meta[data.CanonicalTimestampRole], 1, false))
// loading the snapshot in fails, because of the checksum the timestamp has
err = builder.Load(data.CanonicalSnapshotRole, snapJSON, 0, false)
err = builder.Load(data.CanonicalSnapshotRole, snapJSON, 1, false)
require.Error(t, err)
require.IsType(t, data.ErrMismatchedChecksum{}, err)
require.True(t, builder.IsLoaded(data.CanonicalTimestampRole))
require.False(t, builder.IsLoaded(data.CanonicalSnapshotRole))
// all the other metadata can be loaded in, even though the checksums are wrong according to timestamp
for _, roleName := range []string{data.CanonicalTargetsRole, "targets/other"} {
require.NoError(t, builder.Load(roleName, meta[roleName], 0, false))
require.NoError(t, builder.Load(roleName, meta[roleName], 1, false))
}
// --- load snapshot first
builder = tuf.NewRepoBuilder(nil, gun, nil, trustpinning.TrustPinConfig{})
builder = tuf.NewRepoBuilder(gun, nil, trustpinning.TrustPinConfig{})
for _, roleName := range append(data.BaseRoles, "targets/other") {
switch roleName {
case data.CanonicalTimestampRole:
continue
case data.CanonicalSnapshotRole:
require.NoError(t, builder.Load(roleName, snapJSON, 0, false))
require.NoError(t, builder.Load(roleName, snapJSON, 1, false))
default:
require.NoError(t, builder.Load(roleName, meta[roleName], 0, false))
require.NoError(t, builder.Load(roleName, meta[roleName], 1, false))
}
}
// timestamp fails because the snapshot checksum is wrong
err = builder.Load(data.CanonicalTimestampRole, meta[data.CanonicalTimestampRole], 0, false)
err = builder.Load(data.CanonicalTimestampRole, meta[data.CanonicalTimestampRole], 1, false)
require.Error(t, err)
checksumErr, ok := err.(data.ErrMismatchedChecksum)
require.True(t, ok)
@ -587,13 +587,13 @@ func TestSnapshotLoadedFirstChecksumsOthers(t *testing.T) {
gun := "docker.com/notary"
meta := setupSnapshotChecksumming(t, gun)
// --- load root then snapshot
builder := tuf.NewRepoBuilder(nil, gun, nil, trustpinning.TrustPinConfig{})
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 0, false))
builder := tuf.NewRepoBuilder(gun, nil, trustpinning.TrustPinConfig{})
require.NoError(t, builder.Load(data.CanonicalRootRole, meta[data.CanonicalRootRole], 1, false))
require.NoError(t, builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 1, false))
// loading timestamp is fine, even though the timestamp metadata has the wrong checksum because
// we don't check timestamp checksums
require.NoError(t, builder.Load(data.CanonicalTimestampRole, meta[data.CanonicalTimestampRole], 0, false))
require.NoError(t, builder.Load(data.CanonicalTimestampRole, meta[data.CanonicalTimestampRole], 1, false))
// loading the other roles' metadata with a space will fail because of a checksum failure (builder
// checks right away if the snapshot is loaded) - in the case of targets/other/other, which should
@ -608,10 +608,10 @@ func TestSnapshotLoadedFirstChecksumsOthers(t *testing.T) {
require.False(t, builder.IsLoaded(roleNameToLoad))
// now load it for real (since we need targets loaded before trying to load "targets/other")
require.NoError(t, builder.Load(roleNameToLoad, meta[roleNameToLoad], 0, false))
require.NoError(t, builder.Load(roleNameToLoad, meta[roleNameToLoad], 1, false))
}
// loading the non-existent role wil fail
err := builder.Load("targets/other/other", meta["targets/other/other"], 0, false)
err := builder.Load("targets/other/other", meta["targets/other/other"], 1, false)
require.Error(t, err)
require.IsType(t, data.ErrMissingMeta{}, err)
require.False(t, builder.IsLoaded("targets/other/other"))
@ -627,7 +627,7 @@ func TestSnapshotLoadedAfterChecksumsOthersRetroactively(t *testing.T) {
// --- load all the other metadata first, but with an extra space at the end which should
// --- validate fine, except for the checksum.
for _, roleNameToPermute := range append(data.BaseRoles, "targets/other") {
builder := tuf.NewRepoBuilder(nil, gun, nil, trustpinning.TrustPinConfig{})
builder := tuf.NewRepoBuilder(gun, nil, trustpinning.TrustPinConfig{})
if roleNameToPermute == data.CanonicalSnapshotRole {
continue
}
@ -641,12 +641,12 @@ func TestSnapshotLoadedAfterChecksumsOthersRetroactively(t *testing.T) {
// having a space added at the end should not affect any validity check except checksum
require.NoError(t, builder.Load(roleNameToLoad, append(meta[roleNameToLoad], ' '), 0, false))
default:
require.NoError(t, builder.Load(roleNameToLoad, meta[roleNameToLoad], 0, false))
require.NoError(t, builder.Load(roleNameToLoad, meta[roleNameToLoad], 1, false))
}
require.True(t, builder.IsLoaded(roleNameToLoad))
}
// now load the snapshot - it should fail with the checksum failure for the permuted role
err := builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 0, false)
err := builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 1, false)
switch roleNameToPermute {
case data.CanonicalTimestampRole:
require.NoError(t, err) // we don't check the timestamp's checksum
@ -662,14 +662,14 @@ func TestSnapshotLoadedAfterChecksumsOthersRetroactively(t *testing.T) {
// load all the metadata as is without alteration (so they should validate all checksums)
// but also load the metadata that is not contained in the snapshot. Then when the snapshot
// is loaded it will fail validation, because it doesn't have target/other/other's checksum
builder := tuf.NewRepoBuilder(nil, gun, nil, trustpinning.TrustPinConfig{})
builder := tuf.NewRepoBuilder(gun, nil, trustpinning.TrustPinConfig{})
for _, roleNameToLoad := range append(data.BaseRoles, "targets/other", "targets/other/other") {
if roleNameToLoad == data.CanonicalSnapshotRole {
continue
}
require.NoError(t, builder.Load(roleNameToLoad, meta[roleNameToLoad], 0, false))
require.NoError(t, builder.Load(roleNameToLoad, meta[roleNameToLoad], 1, false))
}
err := builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 0, false)
err := builder.Load(data.CanonicalSnapshotRole, meta[data.CanonicalSnapshotRole], 1, false)
require.Error(t, err)
require.IsType(t, data.ErrMissingMeta{}, err)
}

View File

@ -118,7 +118,7 @@ func (c *Client) downloadTimestamp() error {
logrus.Debug(remoteErr.Error())
logrus.Warn("Error while downloading remote metadata, using cached timestamp - this might not be the latest version available remotely")
err := c.newBuilder.Load(role, cachedTS, 0, false)
err := c.newBuilder.Load(role, cachedTS, 1, false)
if err == nil {
logrus.Debug("successfully verified cached timestamp")
}
@ -194,7 +194,7 @@ func (c *Client) tryLoadCacheThenRemote(consistentInfo tuf.ConsistentInfo) ([]by
return c.tryLoadRemote(consistentInfo, nil)
}
if err = c.newBuilder.Load(consistentInfo.RoleName, cachedTS, 0, false); err == nil {
if err = c.newBuilder.Load(consistentInfo.RoleName, cachedTS, 1, false); err == nil {
logrus.Debugf("successfully verified cached %s", consistentInfo.RoleName)
return cachedTS, nil
}
@ -213,8 +213,8 @@ func (c *Client) tryLoadRemote(consistentInfo tuf.ConsistentInfo, old []byte) ([
// try to load the old data into the old builder - only use it to validate
// versions if it loads successfully. If it errors, then the loaded version
// will be 0
c.oldBuilder.Load(consistentInfo.RoleName, old, 0, true)
// will be 1
c.oldBuilder.Load(consistentInfo.RoleName, old, 1, true)
minVersion := c.oldBuilder.GetLoadedVersion(consistentInfo.RoleName)
if err := c.newBuilder.Load(consistentInfo.RoleName, raw, minVersion, false); err != nil {

View File

@ -31,9 +31,9 @@ func isValidRootStructure(r Root) error {
role: CanonicalRootRole, msg: fmt.Sprintf("expected type %s, not %s", expectedType, r.Type)}
}
if r.Version < 0 {
if r.Version < 1 {
return ErrInvalidMetadata{
role: CanonicalRootRole, msg: "version cannot be negative"}
role: CanonicalRootRole, msg: "version cannot be less than 1"}
}
// all the base roles MUST appear in the root.json - other roles are allowed,

View File

@ -225,4 +225,12 @@ func TestRootFromSignedValidatesVersion(t *testing.T) {
root.Signed.Version = -1
_, err := rootToSignedAndBack(t, root)
require.IsType(t, ErrInvalidMetadata{}, err)
root.Signed.Version = 0
_, err = rootToSignedAndBack(t, root)
require.IsType(t, ErrInvalidMetadata{}, err)
root.Signed.Version = 1
_, err = rootToSignedAndBack(t, root)
require.NoError(t, err)
}

View File

@ -32,9 +32,9 @@ func IsValidSnapshotStructure(s Snapshot) error {
role: CanonicalSnapshotRole, msg: fmt.Sprintf("expected type %s, not %s", expectedType, s.Type)}
}
if s.Version < 0 {
if s.Version < 1 {
return ErrInvalidMetadata{
role: CanonicalSnapshotRole, msg: "version cannot be negative"}
role: CanonicalSnapshotRole, msg: "version cannot be less than one"}
}
for _, role := range []string{CanonicalRootRole, CanonicalTargetsRole} {

View File

@ -200,6 +200,14 @@ func TestSnapshotFromSignedValidatesVersion(t *testing.T) {
sn.Signed.Version = -1
_, err := snapshotToSignedAndBack(t, sn)
require.IsType(t, ErrInvalidMetadata{}, err)
sn.Signed.Version = 0
_, err = snapshotToSignedAndBack(t, sn)
require.IsType(t, ErrInvalidMetadata{}, err)
sn.Signed.Version = 1
_, err = snapshotToSignedAndBack(t, sn)
require.NoError(t, err)
}
// GetMeta returns the checksum, or an error if it is missing.

View File

@ -38,8 +38,8 @@ func isValidTargetsStructure(t Targets, roleName string) error {
role: roleName, msg: fmt.Sprintf("expected type %s, not %s", expectedType, t.Type)}
}
if t.Version < 0 {
return ErrInvalidMetadata{role: roleName, msg: "version cannot be negative"}
if t.Version < 1 {
return ErrInvalidMetadata{role: roleName, msg: "version cannot be less than one"}
}
for _, roleObj := range t.Delegations.Roles {

View File

@ -236,4 +236,16 @@ func TestTargetsFromSignedValidatesVersion(t *testing.T) {
require.NoError(t, err)
_, err = TargetsFromSigned(s, "targets/a")
require.IsType(t, ErrInvalidMetadata{}, err)
tg.Signed.Version = 0
s, err = tg.ToSigned()
require.NoError(t, err)
_, err = TargetsFromSigned(s, "targets/a")
require.IsType(t, ErrInvalidMetadata{}, err)
tg.Signed.Version = 1
s, err = tg.ToSigned()
require.NoError(t, err)
_, err = TargetsFromSigned(s, "targets/a")
require.NoError(t, err)
}

View File

@ -31,9 +31,9 @@ func IsValidTimestampStructure(t Timestamp) error {
role: CanonicalTimestampRole, msg: fmt.Sprintf("expected type %s, not %s", expectedType, t.Type)}
}
if t.Version < 0 {
if t.Version < 1 {
return ErrInvalidMetadata{
role: CanonicalTimestampRole, msg: "version cannot be negative"}
role: CanonicalTimestampRole, msg: "version cannot be less than one"}
}
// Meta is a map of FileMeta, so if the role isn't in the map it returns

View File

@ -200,6 +200,14 @@ func TestTimestampFromSignedValidatesVersion(t *testing.T) {
ts.Signed.Version = -1
_, err := timestampToSignedAndBack(t, ts)
require.IsType(t, ErrInvalidMetadata{}, err)
ts.Signed.Version = 0
_, err = timestampToSignedAndBack(t, ts)
require.IsType(t, ErrInvalidMetadata{}, err)
ts.Signed.Version = 1
_, err = timestampToSignedAndBack(t, ts)
require.NoError(t, err)
}
// GetSnapshot returns the snapshot checksum, or an error if it is missing.