// Adding targets to a role that we don't have signing keys for fails func TestAddTargetsNoSigningKeys(t *testing.T) { hash := sha256.Sum256([]byte{}) f := data.FileMeta{ Length: 1, Hashes: map[string][]byte{ "sha256": hash[:], }, } ed25519 := signed.NewEd25519() keyDB := keys.NewDB() repo := initRepo(t, ed25519, keyDB) testKey, err := ed25519.Create("targets/test", data.ED25519Key) assert.NoError(t, err) role, err := data.NewRole( "targets/test", 1, []string{testKey.ID()}, []string{"test"}, []string{}) assert.NoError(t, err) err = repo.UpdateDelegations(role, data.KeyList{testKey}) assert.NoError(t, err) // now delete the signing key (all keys) repo.cryptoService = signed.NewEd25519() // adding the targets to the role should create the metadata though _, err = repo.AddTargets("targets/test", data.Files{"f": f}) assert.Error(t, err) assert.IsType(t, signed.ErrNoKeys{}, err) }
// Adding targets to a role that we don't have signing keys for fails func TestAddTargetsNoSigningKeys(t *testing.T) { hash := sha256.Sum256([]byte{}) f := data.FileMeta{ Length: 1, Hashes: map[string][]byte{ "sha256": hash[:], }, } ed25519 := signed.NewEd25519() repo := initRepo(t, ed25519) testKey, err := ed25519.Create("targets/test", testGUN, data.ED25519Key) require.NoError(t, err) err = repo.UpdateDelegationKeys("targets/test", []data.PublicKey{testKey}, []string{}, 1) require.NoError(t, err) err = repo.UpdateDelegationPaths("targets/test", []string{"test"}, []string{}, false) require.NoError(t, err) // now delete the signing key (all keys) repo.cryptoService = signed.NewEd25519() // adding the targets to the role should create the metadata though _, err = repo.AddTargets("targets/test", data.Files{"f": f}) require.Error(t, err) require.IsType(t, signed.ErrNoKeys{}, err) }
func TestCreateSnapshotNoKeyInCrypto(t *testing.T) { store := storage.NewMemStorage() crypto := signed.NewEd25519() _, err := GetOrCreateSnapshotKey("gun", store, crypto, data.ED25519Key) // reset crypto so the store has the key but crypto doesn't crypto = signed.NewEd25519() _, _, err = createSnapshot("gun", &data.SignedSnapshot{}, store, crypto) assert.Error(t, err) }
// This rotates the key of some delegation role func TestSwizzlerRotateKeyDelegationRole(t *testing.T) { f, origMeta := createNewSwizzler(t) theRole := "targets/a/b" cs := signed.NewEd25519() pubKey, err := cs.Create(theRole, f.Gun, data.ED25519Key) require.NoError(t, err) require.NoError(t, f.RotateKey(theRole, pubKey)) for role, metaBytes := range origMeta { newMeta, err := f.MetadataCache.GetMeta(role, store.NoSizeLimit) require.NoError(t, err) if role != "targets/a" { require.True(t, bytes.Equal(metaBytes, newMeta), "bytes have changed for role %s", role) } else { require.False(t, bytes.Equal(metaBytes, newMeta)) origSigned, newSigned := &data.SignedTargets{}, &data.SignedTargets{} require.NoError(t, json.Unmarshal(metaBytes, origSigned)) require.NoError(t, json.Unmarshal(newMeta, newSigned)) require.NotEqual(t, []string{pubKey.ID()}, origSigned.Signed.Delegations.Roles[0].KeyIDs) require.Equal(t, []string{pubKey.ID()}, newSigned.Signed.Delegations.Roles[0].KeyIDs) _, ok := origSigned.Signed.Delegations.Keys[pubKey.ID()] require.False(t, ok) _, ok = newSigned.Signed.Delegations.Keys[pubKey.ID()] require.True(t, ok) } } }
func TestRotation(t *testing.T) { signer := signed.NewEd25519() repo := tuf.NewRepo(signer) remote := store.NewMemoryStore(nil) cache := store.NewMemoryStore(nil) // Generate initial root key and role and add to key DB rootKey, err := signer.Create("root", data.ED25519Key) assert.NoError(t, err, "Error creating root key") rootRole, err := data.NewRole("root", 1, []string{rootKey.ID()}, nil) assert.NoError(t, err, "Error creating root role") originalRoot, err := data.NewRoot( map[string]data.PublicKey{rootKey.ID(): rootKey}, map[string]*data.RootRole{"root": &rootRole.RootRole}, false, ) repo.Root = originalRoot // Generate new key and role. replacementKey, err := signer.Create("root", data.ED25519Key) assert.NoError(t, err, "Error creating replacement root key") replacementRole, err := data.NewRole("root", 1, []string{replacementKey.ID()}, nil) assert.NoError(t, err, "Error creating replacement root role") // Generate a new root with the replacement key and role testRoot, err := data.NewRoot( map[string]data.PublicKey{replacementKey.ID(): replacementKey}, map[string]*data.RootRole{ data.CanonicalRootRole: &replacementRole.RootRole, data.CanonicalSnapshotRole: &replacementRole.RootRole, data.CanonicalTargetsRole: &replacementRole.RootRole, data.CanonicalTimestampRole: &replacementRole.RootRole, }, false, ) assert.NoError(t, err, "Failed to create new root") // Sign testRoot with both old and new keys signedRoot, err := testRoot.ToSigned() err = signed.Sign(signer, signedRoot, rootKey, replacementKey) assert.NoError(t, err, "Failed to sign root") var origKeySig bool var replKeySig bool for _, sig := range signedRoot.Signatures { if sig.KeyID == rootKey.ID() { origKeySig = true } else if sig.KeyID == replacementKey.ID() { replKeySig = true } } assert.True(t, origKeySig, "Original root key signature not present") assert.True(t, replKeySig, "Replacement root key signature not present") client := NewClient(repo, remote, cache) err = client.verifyRoot("root", signedRoot, 0) assert.NoError(t, err, "Failed to verify key rotated root") }
// Ensures that the httpstore can interpret the errors returned from the server func TestValidationErrorFormat(t *testing.T) { ctx := context.WithValue( context.Background(), notary.CtxKeyMetaStore, storage.NewMemStorage()) ctx = context.WithValue(ctx, notary.CtxKeyKeyAlgo, data.ED25519Key) handler := RootHandler(ctx, nil, signed.NewEd25519(), nil, nil, nil) server := httptest.NewServer(handler) defer server.Close() client, err := store.NewHTTPStore( fmt.Sprintf("%s/v2/docker.com/notary/_trust/tuf/", server.URL), "", "json", "key", http.DefaultTransport, ) require.NoError(t, err) repo, _, err := testutils.EmptyRepo("docker.com/notary") require.NoError(t, err) r, tg, sn, ts, err := testutils.Sign(repo) require.NoError(t, err) rs, rt, _, _, err := testutils.Serialize(r, tg, sn, ts) require.NoError(t, err) // No snapshot is passed, and the server doesn't have the snapshot key, // so ErrBadHierarchy err = client.SetMulti(map[string][]byte{ data.CanonicalRootRole: rs, data.CanonicalTargetsRole: rt, }) require.Error(t, err) require.IsType(t, validation.ErrBadHierarchy{}, err) }
func TestGetTimestampKeyCreateWithFailingStore(t *testing.T) { store := FailingStore{storage.NewMemStorage()} crypto := signed.NewEd25519() k, err := GetOrCreateTimestampKey("gun", store, crypto, data.ED25519Key) require.Error(t, err, "Expected error") require.Nil(t, k, "Key should be nil") }
// we require that at least the base targets role is available when creating // initializing a snapshot func TestInitSnapshotNoTargets(t *testing.T) { cryptoService := signed.NewEd25519() keyDB := keys.NewDB() rootKey, err := cryptoService.Create("root", data.ED25519Key) assert.NoError(t, err) snapshotKey, err := cryptoService.Create("snapshot", data.ED25519Key) assert.NoError(t, err) keyDB.AddKey(rootKey) keyDB.AddKey(snapshotKey) rootRole := &data.Role{ Name: "root", RootRole: data.RootRole{ KeyIDs: []string{rootKey.ID()}, Threshold: 1, }, } snapshotRole := &data.Role{ Name: "snapshot", RootRole: data.RootRole{ KeyIDs: []string{snapshotKey.ID()}, Threshold: 1, }, } keyDB.AddRole(rootRole) keyDB.AddRole(snapshotRole) repo := NewRepo(keyDB, cryptoService) err = repo.InitSnapshot() assert.Error(t, err) assert.IsType(t, ErrNotLoaded{}, err) }
// Removing targets from a role that exists, has targets, and is signable // should succeed, even if we also want to remove targets that don't exist. func TestRemoveExistingAndNonexistingTargets(t *testing.T) { ed25519 := signed.NewEd25519() keyDB := keys.NewDB() repo := initRepo(t, ed25519, keyDB) testKey, err := ed25519.Create("targets/test", data.ED25519Key) assert.NoError(t, err) role, err := data.NewRole( "targets/test", 1, []string{testKey.ID()}, []string{"test"}, []string{}) assert.NoError(t, err) err = repo.UpdateDelegations(role, data.KeyList{testKey}) assert.NoError(t, err) // no empty metadata is created for this role _, ok := repo.Targets["targets/test"] assert.False(t, ok, "no empty targets file should be created") // now remove a target assert.NoError(t, repo.RemoveTargets("targets/test", "f")) // still no metadata _, ok = repo.Targets["targets/test"] assert.False(t, ok) }
func TestGetDelegationRolesInvalidPaths(t *testing.T) { ed25519 := signed.NewEd25519() repo := initRepo(t, ed25519) testKey1, err := ed25519.Create("targets/test", data.ED25519Key) assert.NoError(t, err) role, err := data.NewRole("targets/test", 1, []string{testKey1.ID()}, []string{"path", "anotherpath"}) assert.NoError(t, err) err = repo.UpdateDelegations(role, data.KeyList{testKey1}) assert.NoError(t, err) testKey2, err := ed25519.Create("targets/test/b", data.ED25519Key) assert.NoError(t, err) // Now we add a delegation with a path that is not prefixed by its parent delegation role, err = data.NewRole("targets/test/b", 1, []string{testKey2.ID()}, []string{"invalidpath"}) assert.NoError(t, err) err = repo.UpdateDelegations(role, data.KeyList{testKey2}) assert.NoError(t, err) // Getting this delegation does not actually restrict paths, unless we use the RestrictChild method delgRole, err := repo.GetDelegationRole("targets/test/b") assert.NoError(t, err) assert.Contains(t, delgRole.Paths, "invalidpath") delgRole, err = repo.GetDelegationRole("targets/test") assert.NoError(t, err) assert.Contains(t, delgRole.Paths, "path") assert.Contains(t, delgRole.Paths, "anotherpath") }
func TestDeleteDelegationsRoleNotExistBecauseNoParentMeta(t *testing.T) { ed25519 := signed.NewEd25519() keyDB := keys.NewDB() repo := initRepo(t, ed25519, keyDB) testKey, err := ed25519.Create("targets/test", data.ED25519Key) assert.NoError(t, err) role, err := data.NewRole("targets/test", 1, []string{testKey.ID()}, []string{"test"}, []string{}) assert.NoError(t, err) err = repo.UpdateDelegations(role, data.KeyList{testKey}) assert.NoError(t, err) // no empty delegation metadata created for new delegation _, ok := repo.Targets["targets/test"] assert.False(t, ok, "no targets file should be created for empty delegation") delRole, err := data.NewRole( "targets/test/a", 1, []string{testKey.ID()}, []string{"test"}, []string{}) err = repo.DeleteDelegation(*delRole) assert.NoError(t, err) // still no metadata _, ok = repo.Targets["targets/test"] assert.False(t, ok) }
// This rotates the key of some base role func TestSwizzlerRotateKeyBaseRole(t *testing.T) { f, origMeta := createNewSwizzler(t) theRole := data.CanonicalSnapshotRole cs := signed.NewEd25519() pubKey, err := cs.Create(theRole, f.Gun, data.ED25519Key) require.NoError(t, err) require.NoError(t, f.RotateKey(theRole, pubKey)) for role, metaBytes := range origMeta { newMeta, err := f.MetadataCache.GetSized(role, store.NoSizeLimit) require.NoError(t, err) if role != data.CanonicalRootRole { require.True(t, bytes.Equal(metaBytes, newMeta), "bytes have changed for role %s", role) } else { require.False(t, bytes.Equal(metaBytes, newMeta)) origSigned, newSigned := &data.SignedRoot{}, &data.SignedRoot{} require.NoError(t, json.Unmarshal(metaBytes, origSigned)) require.NoError(t, json.Unmarshal(newMeta, newSigned)) require.NotEqual(t, []string{pubKey.ID()}, origSigned.Signed.Roles[theRole].KeyIDs) require.Equal(t, []string{pubKey.ID()}, newSigned.Signed.Roles[theRole].KeyIDs) _, ok := origSigned.Signed.Keys[pubKey.ID()] require.False(t, ok) _, ok = newSigned.Signed.Keys[pubKey.ID()] require.True(t, ok) } } }
// Adding targets to a role that exists and has not metadata first creates the // metadata and then correctly adds the target func TestAddTargetsRoleExistsAndMetadataDoesntExist(t *testing.T) { hash := sha256.Sum256([]byte{}) f := data.FileMeta{ Length: 1, Hashes: map[string][]byte{ "sha256": hash[:], }, } ed25519 := signed.NewEd25519() repo := initRepo(t, ed25519) testKey, err := ed25519.Create("targets/test", data.ED25519Key) assert.NoError(t, err) role, err := data.NewRole("targets/test", 1, []string{testKey.ID()}, []string{""}) assert.NoError(t, err) err = repo.UpdateDelegations(role, data.KeyList{testKey}) assert.NoError(t, err) // no empty metadata is created for this role _, ok := repo.Targets["targets/test"] assert.False(t, ok, "no empty targets file should be created") // adding the targets to the role should create the metadata though _, err = repo.AddTargets("targets/test", data.Files{"f": f}) assert.NoError(t, err) r, ok := repo.Targets["targets/test"] assert.True(t, ok) targetsF, ok := r.Signed.Targets["f"] assert.True(t, ok) assert.Equal(t, f, targetsF) }
// RotateKey supports only timestamp and snapshot key rotation func TestRotateKeyEndpoint(t *testing.T) { ctx := context.WithValue( context.Background(), notary.CtxKeyMetaStore, storage.NewMemStorage()) ctx = context.WithValue(ctx, notary.CtxKeyKeyAlgo, data.ED25519Key) ccc := utils.NewCacheControlConfig(10, false) handler := RootHandler(ctx, nil, signed.NewEd25519(), ccc, ccc, nil) ts := httptest.NewServer(handler) defer ts.Close() rolesToStatus := map[string]int{ data.CanonicalTimestampRole: http.StatusOK, data.CanonicalSnapshotRole: http.StatusOK, data.CanonicalTargetsRole: http.StatusNotFound, data.CanonicalRootRole: http.StatusNotFound, "targets/delegation": http.StatusNotFound, "somerandomrole": http.StatusNotFound, } var buf bytes.Buffer for role, expectedStatus := range rolesToStatus { res, err := http.Post( fmt.Sprintf("%s/v2/gun/_trust/tuf/%s.key", ts.URL, role), "text/plain", &buf) require.NoError(t, err) require.Equal(t, expectedStatus, res.StatusCode) } }
func TestGetSnapshotKeyCreateWithInvalidAlgo(t *testing.T) { store := storage.NewMemStorage() crypto := signed.NewEd25519() k, err := GetOrCreateSnapshotKey("gun", store, crypto, "notactuallyanalgorithm") require.Error(t, err, "Expected error") require.Nil(t, k, "Key should be nil") }
func TestGetSnapshotKeyCreateWithCorruptedStore(t *testing.T) { store := CorruptedStore{storage.NewMemStorage()} crypto := signed.NewEd25519() k, err := GetOrCreateSnapshotKey("gun", store, crypto, data.ED25519Key) require.Error(t, err, "Expected error") require.Nil(t, k, "Key should be nil") }
func TestUpdateDelegationsInvalidRole(t *testing.T) { ed25519 := signed.NewEd25519() keyDB := keys.NewDB() repo := initRepo(t, ed25519, keyDB) roleKey, err := ed25519.Create("Invalid Role", data.ED25519Key) assert.NoError(t, err) // data.NewRole errors if the role isn't a valid TUF role so use one of the non-delegation // valid roles invalidRole, err := data.NewRole("root", 1, []string{roleKey.ID()}, []string{}, []string{}) assert.NoError(t, err) err = repo.UpdateDelegations(invalidRole, data.KeyList{roleKey}) assert.Error(t, err) assert.IsType(t, data.ErrInvalidRole{}, err) r, ok := repo.Targets[data.CanonicalTargetsRole] assert.True(t, ok) assert.Len(t, r.Signed.Delegations.Roles, 0) // no delegation metadata created for invalid delgation _, ok = repo.Targets["root"] assert.False(t, ok, "no targets file should be created since delegation failed") }
func TestGetSnapshotNotExists(t *testing.T) { store := storage.NewMemStorage() crypto := signed.NewEd25519() _, err := GetOrCreateSnapshot("gun", store, crypto) assert.Error(t, err) }
// A delegation can be created with a role that is missing a signing key, so // long as UpdateDelegations is called with the key func TestUpdateDelegationsRoleThatIsMissingDelegationKey(t *testing.T) { ed25519 := signed.NewEd25519() keyDB := keys.NewDB() repo := initRepo(t, ed25519, keyDB) roleKey, err := ed25519.Create("Invalid Role", data.ED25519Key) assert.NoError(t, err) role, err := data.NewRole("targets/role", 1, []string{}, []string{""}, []string{}) assert.NoError(t, err) // key should get added to role as part of updating the delegation err = repo.UpdateDelegations(role, data.KeyList{roleKey}) assert.NoError(t, err) r, ok := repo.Targets[data.CanonicalTargetsRole] assert.True(t, ok) assert.Len(t, r.Signed.Delegations.Roles, 1) assert.Len(t, r.Signed.Delegations.Keys, 1) keyIDs := r.Signed.Delegations.Roles[0].KeyIDs assert.Len(t, keyIDs, 1) assert.Equal(t, roleKey.ID(), keyIDs[0]) assert.True(t, r.Dirty) // no empty delegation metadata created for new delegation _, ok = repo.Targets["targets/role"] assert.False(t, ok, "no targets file should be created for empty delegation") }
func TestGetSnapshotCurrValid(t *testing.T) { store := storage.NewMemStorage() crypto := signed.NewEd25519() _, err := GetOrCreateSnapshotKey("gun", store, crypto, data.ED25519Key) newData := []byte{2} currMeta, err := data.NewFileMeta(bytes.NewReader(newData), "sha256") assert.NoError(t, err) snapshot := &data.SignedSnapshot{ Signed: data.Snapshot{ Expires: data.DefaultExpires(data.CanonicalSnapshotRole), Meta: data.Files{ data.CanonicalRootRole: currMeta, }, }, } snapJSON, _ := json.Marshal(snapshot) // test when db is missing the role data store.UpdateCurrent("gun", storage.MetaUpdate{Role: "snapshot", Version: 0, Data: snapJSON}) _, err = GetOrCreateSnapshot("gun", store, crypto) assert.NoError(t, err) // test when db has the role data store.UpdateCurrent("gun", storage.MetaUpdate{Role: "root", Version: 0, Data: newData}) _, err = GetOrCreateSnapshot("gun", store, crypto) assert.NoError(t, err) // test when db role data is expired store.UpdateCurrent("gun", storage.MetaUpdate{Role: "root", Version: 1, Data: []byte{3}}) _, err = GetOrCreateSnapshot("gun", store, crypto) assert.NoError(t, err) }
func TestDeleteDelegationsMidSliceRole(t *testing.T) { ed25519 := signed.NewEd25519() keyDB := keys.NewDB() repo := initRepo(t, ed25519, keyDB) testKey, err := ed25519.Create("targets/test", data.ED25519Key) assert.NoError(t, err) role, err := data.NewRole("targets/test", 1, []string{}, []string{""}, []string{}) assert.NoError(t, err) err = repo.UpdateDelegations(role, data.KeyList{testKey}) assert.NoError(t, err) role2, err := data.NewRole("targets/test2", 1, []string{}, []string{""}, []string{}) assert.NoError(t, err) err = repo.UpdateDelegations(role2, data.KeyList{testKey}) assert.NoError(t, err) role3, err := data.NewRole("targets/test3", 1, []string{}, []string{""}, []string{}) assert.NoError(t, err) err = repo.UpdateDelegations(role3, data.KeyList{testKey}) assert.NoError(t, err) err = repo.DeleteDelegation(*role2) assert.NoError(t, err) r, ok := repo.Targets[data.CanonicalTargetsRole] assert.True(t, ok) assert.Len(t, r.Signed.Delegations.Roles, 2) assert.Len(t, r.Signed.Delegations.Keys, 1) assert.True(t, r.Dirty) }
func TestCreateSnapshotNoKeyInStorage(t *testing.T) { store := storage.NewMemStorage() crypto := signed.NewEd25519() _, _, err := createSnapshot("gun", nil, store, crypto) assert.Error(t, err) }
func TestUpdateDelegations(t *testing.T) { ed25519 := signed.NewEd25519() keyDB := keys.NewDB() repo := initRepo(t, ed25519, keyDB) testKey, err := ed25519.Create("targets/test", data.ED25519Key) if err != nil { t.Fatal(err) } role, err := data.NewRole("targets/test", 1, []string{testKey.ID()}, []string{"test"}, []string{}) if err != nil { t.Fatal(err) } err = repo.UpdateDelegations(role, data.KeyList{testKey}, "") if err != nil { t.Fatal(err) } testDeepKey, err := ed25519.Create("targets/test/deep", data.ED25519Key) if err != nil { t.Fatal(err) } roleDeep, err := data.NewRole("targets/test/deep", 1, []string{testDeepKey.ID()}, []string{"test/deep"}, []string{}) if err != nil { t.Fatal(err) } err = repo.UpdateDelegations(roleDeep, data.KeyList{testDeepKey}, "") if err != nil { t.Fatal(err) } writeRepo(t, "/tmp/tufdelegation", repo) }
func TestGetTimestampNewSnapshot(t *testing.T) { store := storage.NewMemStorage() crypto := signed.NewEd25519() snapshot := &data.SignedSnapshot{ Signed: data.Snapshot{ Expires: data.DefaultExpires(data.CanonicalSnapshotRole), }, } snapshot.Signed.Version = 0 snapJSON, _ := json.Marshal(snapshot) store.UpdateCurrent("gun", storage.MetaUpdate{Role: "snapshot", Version: 0, Data: snapJSON}) // create a key to be used by GetTimestamp _, err := GetOrCreateTimestampKey("gun", store, crypto, data.ED25519Key) assert.Nil(t, err, "GetKey errored") ts1, err := GetOrCreateTimestamp("gun", store, crypto) assert.Nil(t, err, "GetTimestamp errored") snapshot = &data.SignedSnapshot{ Signed: data.Snapshot{ Expires: data.DefaultExpires(data.CanonicalSnapshotRole), }, } snapshot.Signed.Version = 1 snapJSON, _ = json.Marshal(snapshot) store.UpdateCurrent("gun", storage.MetaUpdate{Role: "snapshot", Version: 1, Data: snapJSON}) ts2, err := GetOrCreateTimestamp("gun", store, crypto) assert.NoError(t, err, "GetTimestamp errored") assert.NotEqual(t, ts1, ts2, "Timestamp was not regenerated when snapshot changed") }
// adding a key to a role marks root as dirty as well as the role func TestAddBaseKeysToRoot(t *testing.T) { for _, role := range data.BaseRoles { ed25519 := signed.NewEd25519() keyDB := keys.NewDB() repo := initRepo(t, ed25519, keyDB) key, err := ed25519.Create(role, data.ED25519Key) assert.NoError(t, err) assert.Len(t, repo.Root.Signed.Roles[role].KeyIDs, 1) assert.NoError(t, repo.AddBaseKeys(role, key)) _, ok := repo.Root.Signed.Keys[key.ID()] assert.True(t, ok) assert.Len(t, repo.Root.Signed.Roles[role].KeyIDs, 2) assert.True(t, repo.Root.Dirty) switch role { case data.CanonicalSnapshotRole: assert.True(t, repo.Snapshot.Dirty) case data.CanonicalTargetsRole: assert.True(t, repo.Targets[data.CanonicalTargetsRole].Dirty) case data.CanonicalTimestampRole: assert.True(t, repo.Timestamp.Dirty) } } }
// removing one or more keys from a role marks root as dirty as well as the role func TestRemoveBaseKeysFromRoot(t *testing.T) { for _, role := range data.BaseRoles { ed25519 := signed.NewEd25519() repo := initRepo(t, ed25519) origKeyIDs := ed25519.ListKeys(role) require.Len(t, origKeyIDs, 1) require.Len(t, repo.Root.Signed.Roles[role].KeyIDs, 1) require.NoError(t, repo.RemoveBaseKeys(role, origKeyIDs...)) require.Len(t, repo.Root.Signed.Roles[role].KeyIDs, 0) require.True(t, repo.Root.Dirty) switch role { case data.CanonicalSnapshotRole: require.True(t, repo.Snapshot.Dirty) case data.CanonicalTargetsRole: require.True(t, repo.Targets[data.CanonicalTargetsRole].Dirty) case data.CanonicalTimestampRole: require.True(t, repo.Timestamp.Dirty) case data.CanonicalRootRole: require.Len(t, repo.originalRootRole.Keys, 1) require.Contains(t, repo.originalRootRole.ListKeyIDs(), origKeyIDs[0]) } } }
// Ensures that the httpstore can interpret the errors returned from the server func TestValidationErrorFormat(t *testing.T) { ctx := context.WithValue( context.Background(), "metaStore", storage.NewMemStorage()) ctx = context.WithValue(ctx, "keyAlgorithm", data.ED25519Key) handler := RootHandler(nil, ctx, signed.NewEd25519()) server := httptest.NewServer(handler) defer server.Close() client, err := store.NewHTTPStore( fmt.Sprintf("%s/v2/gun/_trust/tuf/", server.URL), "", "json", "", "key", http.DefaultTransport, ) _, repo, _ := testutils.EmptyRepo() r, tg, sn, ts, err := testutils.Sign(repo) assert.NoError(t, err) rs, _, _, _, err := testutils.Serialize(r, tg, sn, ts) assert.NoError(t, err) err = client.SetMultiMeta(map[string][]byte{data.CanonicalRootRole: rs}) assert.Error(t, err) assert.IsType(t, validation.ErrBadRoot{}, err) }
func TestCreateTimestampNoKeyInCrypto(t *testing.T) { store := storage.NewMemStorage() repo, _, err := testutils.EmptyRepo("gun") require.NoError(t, err) meta, err := testutils.SignAndSerialize(repo) require.NoError(t, err) // create an expired timestamp _, err = repo.SignTimestamp(time.Now().AddDate(-1, -1, -1)) require.True(t, repo.Timestamp.Signed.Expires.Before(time.Now())) require.NoError(t, err) timestampJSON, err := json.Marshal(repo.Timestamp) require.NoError(t, err) // set all the metadata so we know the failure to sign is just because of the key require.NoError(t, store.UpdateCurrent("gun", storage.MetaUpdate{Role: data.CanonicalRootRole, Version: 0, Data: meta[data.CanonicalRootRole]})) require.NoError(t, store.UpdateCurrent("gun", storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0, Data: meta[data.CanonicalSnapshotRole]})) require.NoError(t, store.UpdateCurrent("gun", storage.MetaUpdate{Role: data.CanonicalTimestampRole, Version: 1, Data: timestampJSON})) // pass it a new cryptoservice without the key _, _, err = GetOrCreateTimestamp("gun", store, signed.NewEd25519()) require.Error(t, err) require.IsType(t, signed.ErrInsufficientSignatures{}, err) }
func TestRotationNewSigMissing(t *testing.T) { logrus.SetLevel(logrus.DebugLevel) kdb := keys.NewDB() signer := signed.NewEd25519() repo := tuf.NewRepo(kdb, signer) remote := store.NewMemoryStore(nil, nil) cache := store.NewMemoryStore(nil, nil) // Generate initial root key and role and add to key DB rootKey, err := signer.Create("root", data.ED25519Key) assert.NoError(t, err, "Error creating root key") rootRole, err := data.NewRole("root", 1, []string{rootKey.ID()}, nil, nil) assert.NoError(t, err, "Error creating root role") kdb.AddKey(rootKey) err = kdb.AddRole(rootRole) assert.NoError(t, err, "Error adding root role to db") // Generate new key and role. These will appear in the root.json // but will not be added to the keyDB. replacementKey, err := signer.Create("root", data.ED25519Key) assert.NoError(t, err, "Error creating replacement root key") replacementRole, err := data.NewRole("root", 1, []string{replacementKey.ID()}, nil, nil) assert.NoError(t, err, "Error creating replacement root role") assert.NotEqual(t, rootKey.ID(), replacementKey.ID(), "Key IDs are the same") // Generate a new root with the replacement key and role testRoot, err := data.NewRoot( map[string]data.PublicKey{replacementKey.ID(): replacementKey}, map[string]*data.RootRole{"root": &replacementRole.RootRole}, false, ) assert.NoError(t, err, "Failed to create new root") _, ok := testRoot.Signed.Keys[rootKey.ID()] assert.False(t, ok, "Old root key appeared in test root") // Sign testRoot with both old and new keys signedRoot, err := testRoot.ToSigned() err = signed.Sign(signer, signedRoot, rootKey) assert.NoError(t, err, "Failed to sign root") var origKeySig bool var replKeySig bool for _, sig := range signedRoot.Signatures { if sig.KeyID == rootKey.ID() { origKeySig = true } else if sig.KeyID == replacementKey.ID() { replKeySig = true } } assert.True(t, origKeySig, "Original root key signature not present") assert.False(t, replKeySig, "Replacement root key signature was present and shouldn't be") client := NewClient(repo, remote, kdb, cache) err = client.verifyRoot("root", signedRoot, 0) assert.Error(t, err, "Should have errored on verify as replacement signature was missing.") }
func TestCreateSnapshotNoKeyInCrypto(t *testing.T) { store := storage.NewMemStorage() repo, _, err := testutils.EmptyRepo("gun") require.NoError(t, err) sgnd, err := repo.SignRoot(data.DefaultExpires(data.CanonicalRootRole)) require.NoError(t, err) rootJSON, err := json.Marshal(sgnd) require.NoError(t, err) // create an expired snapshot sgnd, err = repo.SignSnapshot(time.Now().AddDate(-1, -1, -1)) require.True(t, repo.Snapshot.Signed.Expires.Before(time.Now())) require.NoError(t, err) snapshotJSON, err := json.Marshal(sgnd) require.NoError(t, err) // set all the metadata so we know the failure to sign is just because of the key require.NoError(t, store.UpdateCurrent("gun", storage.MetaUpdate{Role: data.CanonicalRootRole, Version: 0, Data: rootJSON})) require.NoError(t, store.UpdateCurrent("gun", storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0, Data: snapshotJSON})) hashBytes := sha256.Sum256(snapshotJSON) hashHex := hex.EncodeToString(hashBytes[:]) // pass it a new cryptoservice without the key _, _, err = GetOrCreateSnapshot("gun", hashHex, store, signed.NewEd25519()) require.Error(t, err) require.IsType(t, signed.ErrInsufficientSignatures{}, err) }