func TestMemoryStore(t *testing.T) {
	s := NewMemoryStore(nil)
	_, err := s.GetMeta("nonexistent", 0)
	require.Error(t, err)
	require.IsType(t, ErrMetaNotFound{}, err)

	metaContent := []byte("content")
	metaSize := int64(7)
	err = s.SetMeta("exists", metaContent)
	require.NoError(t, err)

	meta, err := s.GetMeta("exists", metaSize)
	require.NoError(t, err)
	require.Equal(t, metaContent, meta)

	meta, err = s.GetMeta("exists", -1)
	require.NoError(t, err)
	require.Equal(t, metaContent, meta)

	err = s.RemoveAll()
	require.NoError(t, err)

	_, err = s.GetMeta("exists", 0)
	require.Error(t, err)
	require.IsType(t, ErrMetaNotFound{}, err)
}
Example #2
0
// If there is no previous snapshot or the previous snapshot is corrupt, then
// even if everything else is in place, getting the snapshot fails
func TestGetSnapshotNoPreviousSnapshot(t *testing.T) {
	repo, crypto, 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)

	for _, snapshotJSON := range [][]byte{nil, []byte("invalid JSON")} {
		store := storage.NewMemStorage()

		// so we know it's not a failure in getting root
		require.NoError(t,
			store.UpdateCurrent("gun", storage.MetaUpdate{Role: data.CanonicalRootRole, Version: 0, Data: rootJSON}))

		if snapshotJSON != nil {
			require.NoError(t,
				store.UpdateCurrent("gun",
					storage.MetaUpdate{Role: data.CanonicalSnapshotRole, Version: 0, Data: snapshotJSON}))
		}

		hashBytes := sha256.Sum256(snapshotJSON)
		hashHex := hex.EncodeToString(hashBytes[:])

		_, _, err = GetOrCreateSnapshot("gun", hashHex, store, crypto)
		require.Error(t, err, "GetSnapshot should have failed")
		if snapshotJSON == nil {
			require.IsType(t, storage.ErrNotFound{}, err)
		} else {
			require.IsType(t, &json.SyntaxError{}, err)
		}
	}
}
Example #3
0
// If there is no previous timestamp or the previous timestamp is corrupt, then
// even if everything else is in place, getting the timestamp fails
func TestGetTimestampNoPreviousTimestamp(t *testing.T) {
	repo, crypto, err := testutils.EmptyRepo("gun")
	require.NoError(t, err)

	meta, err := testutils.SignAndSerialize(repo)
	require.NoError(t, err)

	for _, timestampJSON := range [][]byte{nil, []byte("invalid JSON")} {
		store := storage.NewMemStorage()

		// so we know it's not a failure in getting root or snapshot
		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]}))

		if timestampJSON != nil {
			require.NoError(t,
				store.UpdateCurrent("gun",
					storage.MetaUpdate{Role: data.CanonicalTimestampRole, Version: 0, Data: timestampJSON}))
		}

		_, _, err = GetOrCreateTimestamp("gun", store, crypto)
		require.Error(t, err, "GetTimestamp should have failed")
		if timestampJSON == nil {
			require.IsType(t, storage.ErrNotFound{}, err)
		} else {
			require.IsType(t, &json.SyntaxError{}, err)
		}
	}
}
Example #4
0
// If the root or targets metadata is missing, the snapshot metadata fails to validate
// and thus fails to convert into a SignedSnapshot
func TestSnapshotFromSignedValidatesMeta(t *testing.T) {
	var err error
	for _, roleName := range []string{CanonicalRootRole, CanonicalTargetsRole} {
		sn := validSnapshotTemplate()

		// invalid checksum length
		sn.Signed.Meta[roleName].Hashes["sha256"] = []byte("too short")
		_, err = snapshotToSignedAndBack(t, sn)
		require.IsType(t, ErrInvalidMetadata{}, err)

		// missing sha256 checksum
		delete(sn.Signed.Meta[roleName].Hashes, "sha256")
		_, err = snapshotToSignedAndBack(t, sn)
		require.IsType(t, ErrInvalidMetadata{}, err)

		// add a different checksum to make sure it's not failing because of the hash length
		sn.Signed.Meta[roleName].Hashes["sha512"] = bytes.Repeat([]byte("a"), sha512.Size)
		_, err = snapshotToSignedAndBack(t, sn)
		require.IsType(t, ErrInvalidMetadata{}, err)

		// delete the ckechsum metadata entirely for the role
		delete(sn.Signed.Meta, roleName)
		_, err = snapshotToSignedAndBack(t, sn)
		require.IsType(t, ErrInvalidMetadata{}, err)

		// add some extra metadata to make sure it's not failing because the metadata
		// is empty
		sn.Signed.Meta[CanonicalSnapshotRole] = FileMeta{}
		_, err = snapshotToSignedAndBack(t, sn)
		require.IsType(t, ErrInvalidMetadata{}, err)
	}
}
Example #5
0
func TestSetSingleAndSetMultiMeta(t *testing.T) {
	metas := map[string][]byte{
		"root":    []byte("root data"),
		"targets": []byte("targets data"),
	}

	var updates map[string][]byte

	handler := func(w http.ResponseWriter, r *http.Request) {
		reader, err := r.MultipartReader()
		require.NoError(t, err)
		updates = make(map[string][]byte)
		for {
			part, err := reader.NextPart()
			if err == io.EOF {
				break
			}
			role := strings.TrimSuffix(part.FileName(), ".json")
			updates[role], err = ioutil.ReadAll(part)
			require.NoError(t, err)
		}
	}
	server := httptest.NewServer(http.HandlerFunc(handler))
	defer server.Close()
	store, err := NewHTTPStore(server.URL, "metadata", "json", "key", http.DefaultTransport)
	require.NoError(t, err)

	require.NoError(t, store.SetMulti(metas))
	require.Len(t, updates, 2)
	rd, rok := updates["root"]
	require.True(t, rok)
	require.Equal(t, rd, metas["root"])
	td, tok := updates["targets"]
	require.True(t, tok)
	require.Equal(t, td, metas["targets"])

	require.NoError(t, store.Set("root", metas["root"]))
	require.Len(t, updates, 1)
	rd, rok = updates["root"]
	require.True(t, rok)
	require.Equal(t, rd, metas["root"])

	// if there is a network error, it gets translated to NetworkError
	store, err = NewHTTPStore(
		server.URL,
		"metadata",
		"txt",
		"key",
		failRoundTripper{},
	)
	require.NoError(t, err)

	err = store.SetMulti(metas)
	require.IsType(t, NetworkError{}, err)
	require.Equal(t, "FAIL", err.Error())

	err = store.Set("root", metas["root"])
	require.IsType(t, NetworkError{}, err)
	require.Equal(t, "FAIL", err.Error())
}
Example #6
0
func TestBuilderOnlyAcceptsDelegationsAfterParent(t *testing.T) {
	meta, gun := getSampleMeta(t)
	builder := tuf.NewRepoBuilder(gun, nil, trustpinning.TrustPinConfig{})

	// load the root
	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], 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, 1, builder.GetLoadedVersion(delgName))
	}

	// load the targets
	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"], 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"], 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"], 1, false))
}
Example #7
0
func TestValidateRootCanContainOnlyx509KeysWithRightGun(t *testing.T) {
	gun := "docker.com/notary"
	repo, cs, err := testutils.EmptyRepo("wrong/gun")
	require.NoError(t, err)
	serverCrypto := testutils.CopyKeys(t, cs, data.CanonicalTimestampRole)

	// if the root has the wrong gun, the server will fail to validate
	r, tg, sn, ts, err := testutils.Sign(repo)
	require.NoError(t, err)
	root, targets, snapshot, timestamp, err := getUpdates(r, tg, sn, ts)
	require.NoError(t, err)

	_, err = validateUpdate(serverCrypto, gun,
		[]storage.MetaUpdate{root, targets, snapshot, timestamp},
		storage.NewMemStorage())
	require.Error(t, err)
	require.IsType(t, validation.ErrBadRoot{}, err)

	// create regular non-x509 keys - change the root keys to one that is not
	// an x509 key - it should also fail to validate
	newRootKey, err := cs.Create(data.CanonicalRootRole, gun, data.ECDSAKey)
	require.NoError(t, err)
	require.NoError(t, repo.ReplaceBaseKeys(data.CanonicalRootRole, newRootKey))

	r, tg, sn, ts, err = testutils.Sign(repo)
	require.NoError(t, err)
	root, targets, snapshot, timestamp, err = getUpdates(r, tg, sn, ts)
	require.NoError(t, err)

	_, err = validateUpdate(serverCrypto, gun,
		[]storage.MetaUpdate{root, targets, snapshot, timestamp},
		storage.NewMemStorage())
	require.Error(t, err)
	require.IsType(t, validation.ErrBadRoot{}, err)
}
Example #8
0
// If the role data specified is nil, or has an invalid threshold, or doesn't have enough
// keys to cover the threshold, or has key IDs that are not in the key list, the root
// metadata fails to validate and thus fails to convert into a SignedRoot
func TestRootFromSignedValidatesRoleData(t *testing.T) {
	var err error
	for _, roleName := range BaseRoles {
		root := validRootTemplate()

		// Invalid threshold
		root.Signed.Roles[roleName].Threshold = 0
		_, err = rootToSignedAndBack(t, root)
		require.IsType(t, ErrInvalidMetadata{}, err)

		// Keys that aren't in the list of keys
		root.Signed.Roles[roleName].Threshold = 1
		root.Signed.Roles[roleName].KeyIDs = []string{"key11"}
		_, err = rootToSignedAndBack(t, root)
		require.IsType(t, ErrInvalidMetadata{}, err)

		// role is nil
		root.Signed.Roles[roleName] = nil
		_, err = rootToSignedAndBack(t, root)
		require.IsType(t, ErrInvalidMetadata{}, err)

		// too few roles
		delete(root.Signed.Roles, roleName)
		_, err = rootToSignedAndBack(t, root)
		require.IsType(t, ErrInvalidMetadata{}, err)

		// add an extra role that doesn't belong, so that the number of roles
		// is correct a required one is still missing
		root.Signed.Roles["extraneous"] = &RootRole{KeyIDs: []string{"key3"}, Threshold: 1}
		_, err = rootToSignedAndBack(t, root)
		require.IsType(t, ErrInvalidMetadata{}, err)
	}
}
func TestJSONHelper(t *testing.T) {
	type myTestType struct {
		A int
		B string
	}

	testInstance := &myTestType{5, "hello"}
	f := JSONCallback(&myTestType{}, func(data interface{}, err error) {
		assert.Nil(t, err)
		assert.IsType(t, &myTestType{}, data)
		assert.Equal(t, testInstance, data)
	})
	jsonBytes, err := json.Marshal(testInstance)
	assert.Nil(t, err)
	f(jsonBytes)

	testArr := []*myTestType{&myTestType{1, "1"}, &myTestType{2, "2"}}
	f = JSONCallback([]*myTestType{}, func(data interface{}, err error) {
		assert.Nil(t, err)
		assert.IsType(t, []*myTestType{}, data)
		assert.Equal(t, testArr, data)
	})
	jsonBytes, err = json.Marshal(testArr)
	assert.Nil(t, err)
	f(jsonBytes)
}
Example #10
0
// If the snapshot metadata is missing, the timestamp metadata fails to validate
// and thus fails to convert into a SignedTimestamp
func TestTimestampFromSignedValidatesMeta(t *testing.T) {
	var err error
	ts := validTimestampTemplate()

	// invalid checksum length
	ts.Signed.Meta[CanonicalSnapshotRole].Hashes["sha256"] = []byte("too short")
	_, err = timestampToSignedAndBack(t, ts)
	require.IsType(t, ErrInvalidMetadata{}, err)

	// missing sha256 checksum
	delete(ts.Signed.Meta[CanonicalSnapshotRole].Hashes, "sha256")
	_, err = timestampToSignedAndBack(t, ts)
	require.IsType(t, ErrInvalidMetadata{}, err)

	// add a different checksum to make sure it's not failing because of the hash length
	ts.Signed.Meta[CanonicalSnapshotRole].Hashes["sha512"] = bytes.Repeat([]byte("a"), sha512.Size)
	_, err = timestampToSignedAndBack(t, ts)
	require.IsType(t, ErrInvalidMetadata{}, err)

	// delete the ckechsum metadata entirely for the role
	delete(ts.Signed.Meta, CanonicalSnapshotRole)
	_, err = timestampToSignedAndBack(t, ts)
	require.IsType(t, ErrInvalidMetadata{}, err)

	// add some extra metadata to make sure it's not failing because the metadata
	// is empty
	ts.Signed.Meta[CanonicalSnapshotRole] = FileMeta{}
	_, err = timestampToSignedAndBack(t, ts)
	require.IsType(t, ErrInvalidMetadata{}, err)
}
func TestJSONCodec(t *testing.T) {
	type myTestType struct {
		A int
		B string
	}

	itemCodec := JSONCodec(&myTestType{})
	testInstance := &myTestType{5, "hello"}
	jsonBytes, err := itemCodec.Encode(testInstance)
	assert.Nil(t, err)

	decodedInstance, err := itemCodec.Decode(jsonBytes)
	assert.Nil(t, err)
	assert.IsType(t, &myTestType{}, decodedInstance)
	assert.Equal(t, testInstance, decodedInstance)

	arrCodec := JSONCodec([]*myTestType{})
	testArr := []*myTestType{&myTestType{1, "1"}, &myTestType{2, "2"}}
	jsonBytes, err = arrCodec.Encode(testArr)
	assert.Nil(t, err)

	decodedArr, err := arrCodec.Decode(jsonBytes)
	assert.Nil(t, err)
	assert.IsType(t, []*myTestType{}, decodedArr)
	assert.Equal(t, testArr, decodedArr)
}
Example #12
0
// If the root is missing or corrupt, no snapshot can be generated
func TestCannotMakeNewSnapshotIfNoRoot(t *testing.T) {
	repo, crypto, err := testutils.EmptyRepo("gun")
	require.NoError(t, err)

	// create an expired snapshot
	_, 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(repo.Snapshot)
	require.NoError(t, err)

	for _, rootJSON := range [][]byte{nil, []byte("invalid JSON")} {
		store := storage.NewMemStorage()

		if rootJSON != nil {
			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: 1, Data: snapshotJSON}))

		hashBytes := sha256.Sum256(snapshotJSON)
		hashHex := hex.EncodeToString(hashBytes[:])

		_, _, err := GetOrCreateSnapshot("gun", hashHex, store, crypto)
		require.Error(t, err, "GetSnapshot errored")

		if rootJSON == nil { // missing metadata
			require.IsType(t, storage.ErrNotFound{}, err)
		} else {
			require.IsType(t, &json.SyntaxError{}, err)
		}
	}
}
Example #13
0
// UpdateMany does not insert any rows (or at least rolls them back) if there
// are any conflicts.
func testUpdateManyConflictRollback(t *testing.T, s MetaStore) []StoredTUFMeta {
	gun := "testGUN"
	successBatch := make([]StoredTUFMeta, 4)
	updates := make([]MetaUpdate, 4)
	for i, role := range data.BaseRoles {
		successBatch[i] = SampleCustomTUFObj(gun, role, 1, nil)
		updates[i] = MakeUpdate(successBatch[i])
	}

	require.NoError(t, s.UpdateMany(gun, updates))

	before, err := s.GetChanges("0", 1000, "")
	if _, ok := s.(RethinkDB); !ok {
		require.NoError(t, err)
	}

	// conflicts with what's in DB
	badBatch := make([]StoredTUFMeta, 4)
	for i, role := range data.BaseRoles {
		version := 2
		if role == data.CanonicalTargetsRole {
			version = 1
		}
		tufdata := []byte(fmt.Sprintf("%s_%s_%d_bad", gun, role, version))
		badBatch[i] = SampleCustomTUFObj(gun, role, version, tufdata)
		updates[i] = MakeUpdate(badBatch[i])
	}

	// check no changes were written when there was a conflict+rollback
	after, err := s.GetChanges("0", 1000, "")
	if _, ok := s.(RethinkDB); !ok {
		require.NoError(t, err)
	}
	require.Equal(t, len(before), len(after))

	err = s.UpdateMany(gun, updates)
	require.Error(t, err)
	require.IsType(t, ErrOldVersion{}, err)

	// self-conflicting, in that it's a duplicate, but otherwise no DB conflicts
	duplicate := SampleCustomTUFObj(gun, data.CanonicalTimestampRole, 3, []byte("duplicate"))
	duplicateUpdate := MakeUpdate(duplicate)
	err = s.UpdateMany(gun, []MetaUpdate{duplicateUpdate, duplicateUpdate})
	require.Error(t, err)
	require.IsType(t, ErrOldVersion{}, err)

	assertExpectedTUFMetaInStore(t, s, successBatch, true)

	for _, tufObj := range append(badBatch, duplicate) {
		checksumBytes := sha256.Sum256(tufObj.Data)
		checksum := hex.EncodeToString(checksumBytes[:])

		_, _, err = s.GetChecksum(tufObj.Gun, tufObj.Role, checksum)
		require.Error(t, err)
		require.IsType(t, ErrNotFound{}, err)
	}

	return successBatch
}
Example #14
0
// The TLS KEK and the KEK for the headers should be in sync, and so failing
// to decrypt the TLS key should be mean we won't be able to decrypt the headers.
// However, the TLS Key encryption uses AES-256-CBC (golang as of 1.7.x does not seem
// to support GCM, so no cipher modes with digests) so sometimes decrypting with
// the wrong passphrase will not result in an error.  This means we will ultimately
// have to rely on the header encryption mechanism, which does include a digest, to
// determine if the KEK is valid.
func TestDecryptTLSKeyFalsePositive(t *testing.T) {
	badKey := []byte(`
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,e7927e79e748233776c03c2eb7275f09
kek-version: 392
raft-dek: CAESMBrzZ0gNVPe3FRs42743q8RtkUBrK1ICQpHWX2vdQ8iqSKt1WoKdFDFD2r28LYAVLxoYQguwHbijMx9k+BALUNBAI3s199S5tvnr

JfGenNvzm++AvsOh+UmcBY+JgI6lnfzaCB68agmlmEZYLYi5tqtAU7gif6VIJpCW
+Pj23Fzkw8sKKOOBeapSC5lp+Cjx9OsCci/R9xrdx+uxnnzKJNxOB/qzqcQfZDMh
id2LxdliFcPEk/Yj5gNGpT0UMFJ4G52enbOwOru46f0=
-----END EC PRIVATE KEY-----
`)

	// not actually a real swarm cert - generated a cert corresponding to the key that expires in 20 years
	matchingCert := []byte(`
-----BEGIN CERTIFICATE-----
MIIB9jCCAZygAwIBAgIRAIdzF3Z9VT2OXbRvEw5cR68wCgYIKoZIzj0EAwIwYDEi
MCAGA1UEChMZbWRwMXU5Z3FoOTV1NXN2MmNodDRrcDB1cTEWMBQGA1UECxMNc3dh
cm0tbWFuYWdlcjEiMCAGA1UEAxMZcXJzYmwza2FqOWhiZWprM2R5aWFlc3FiYTAg
GA8wMDAxMDEwMTAwMDAwMFoXDTM2MTEwODA2MjMwMlowYDEiMCAGA1UEChMZbWRw
MXU5Z3FoOTV1NXN2MmNodDRrcDB1cTEWMBQGA1UECxMNc3dhcm0tbWFuYWdlcjEi
MCAGA1UEAxMZcXJzYmwza2FqOWhiZWprM2R5aWFlc3FiYTBZMBMGByqGSM49AgEG
CCqGSM49AwEHA0IABGOivD25E/zcupRFQdKOKbPHS9Mx7JlUhlWnl0iR0K5VhVIU
XjUHt98GuX6gDjs4yUzEKSGxYPsSYlnG9zQqbQSjNTAzMA4GA1UdDwEB/wQEAwIF
oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMAoGCCqGSM49BAMC
A0gAMEUCIQDWtjg1ITGznQILipaEe70G/NgZAOtFfuPXTVkUl3el+wIgSVOVKB/Q
O0T3aXuZGYNyh//KqAoA3erCmh6HauMz84Y=
-----END CERTIFICATE-----
	`)

	var wrongKEK []byte // empty passphrase doesn't decrypt without errors
	falsePositiveKEK, err := base64.RawStdEncoding.DecodeString("bIQgLAAMoGCrHdjMLVhEVqnYTAM7ZNF2xWMiwtw7AiQ")
	require.NoError(t, err)
	realKEK, err := base64.RawStdEncoding.DecodeString("fDg9YejLnMjU+FpulWR62oJLzVpkD2j7VQuP5xiK9QA")
	require.NoError(t, err)

	tempdir, err := ioutil.TempDir("", "KeyReadWriter-false-positive-decryption")
	require.NoError(t, err)
	defer os.RemoveAll(tempdir)

	path := ca.NewConfigPaths(tempdir)
	require.NoError(t, ioutil.WriteFile(path.Node.Key, badKey, 0600))
	require.NoError(t, ioutil.WriteFile(path.Node.Cert, matchingCert, 0644))

	krw := ca.NewKeyReadWriter(path.Node, wrongKEK, RaftDEKData{})
	_, _, err = krw.Read()
	require.IsType(t, ca.ErrInvalidKEK{}, errors.Cause(err))

	krw = ca.NewKeyReadWriter(path.Node, falsePositiveKEK, RaftDEKData{})
	_, _, err = krw.Read()
	require.Error(t, err)
	require.IsType(t, ca.ErrInvalidKEK{}, errors.Cause(err))

	krw = ca.NewKeyReadWriter(path.Node, realKEK, RaftDEKData{})
	_, _, err = krw.Read()
	require.NoError(t, err)
}
Example #15
0
func testDirectoryCreate(t *testing.T) {
	req := &fuse.CreateRequest{Name: ctx.it}
	obj, fh, err := ctx.d.Create(nil, req, &fuse.CreateResponse{})
	assert.Nil(t, err)
	require.IsType(t, &Object{}, obj)
	require.IsType(t, &ObjectHandle{}, fh)
	ctx.f, _ = obj.(*Object)
	ctx.h, _ = fh.(*ObjectHandle)
	ctx.h.Release(nil, nil)
}
Example #16
0
// If the targets metadata contains delegations which are invalid, the targets metadata
// fails to validate and thus fails to convert into a SignedTargets
func TestTargetsFromSignedValidatesDelegations(t *testing.T) {
	for _, roleName := range []string{CanonicalTargetsRole, path.Join(CanonicalTargetsRole, "a")} {
		targets := validTargetsTemplate()
		delgRole, err := NewRole(path.Join(roleName, "b"), 1, []string{"key1"}, nil)
		require.NoError(t, err)
		targets.Signed.Delegations.Roles = []*Role{delgRole}

		// delegation has invalid threshold
		delgRole.Threshold = 0
		s, err := targets.ToSigned()
		require.NoError(t, err)
		_, err = TargetsFromSigned(s, roleName)
		require.Error(t, err)
		require.IsType(t, ErrInvalidMetadata{}, err)

		delgRole.Threshold = 1

		// Keys that aren't in the list of keys
		delgRole.KeyIDs = []string{"keys11"}
		s, err = targets.ToSigned()
		require.NoError(t, err)
		_, err = TargetsFromSigned(s, roleName)
		require.Error(t, err)
		require.IsType(t, ErrInvalidMetadata{}, err)

		delgRole.KeyIDs = []string{"keys1"}

		// not delegation role
		delgRole.Name = CanonicalRootRole
		s, err = targets.ToSigned()
		require.NoError(t, err)
		_, err = TargetsFromSigned(s, roleName)
		require.Error(t, err)
		require.IsType(t, ErrInvalidMetadata{}, err)

		// more than one level deep
		delgRole.Name = path.Join(roleName, "x", "y")
		s, err = targets.ToSigned()
		require.NoError(t, err)
		_, err = TargetsFromSigned(s, roleName)
		require.Error(t, err)
		require.IsType(t, ErrInvalidMetadata{}, err)

		// not in delegation hierarchy
		if IsDelegation(roleName) {
			delgRole.Name = path.Join(CanonicalTargetsRole, "z")
			s, err := targets.ToSigned()
			require.NoError(t, err)
			_, err = TargetsFromSigned(s, roleName)
			require.Error(t, err)
			require.IsType(t, ErrInvalidMetadata{}, err)
		}
	}
}
Example #17
0
// Checks that both the walking metastore and underlying metastore do not contain the TUF file
func ConsistentEmptyGetCurrentTest(t *testing.T, s *TUFMetaStorage, rec TUFFile) {
	_, byt, err := s.GetCurrent(rec.Gun, rec.Role)
	require.Nil(t, byt)
	require.Error(t, err, "There should be an error getting an empty table")
	require.IsType(t, ErrNotFound{}, err, "Should get a not found error")

	_, byt, err = s.MetaStore.GetCurrent(rec.Gun, rec.Role)
	require.Nil(t, byt)
	require.Error(t, err, "There should be an error getting an empty table")
	require.IsType(t, ErrNotFound{}, err, "Should get a not found error")
}
Example #18
0
// GetMeta returns the checksum, or an error if it is missing.
func TestSnapshotGetMeta(t *testing.T) {
	ts := validSnapshotTemplate()
	f, err := ts.GetMeta(CanonicalRootRole)
	require.NoError(t, err)
	require.IsType(t, &FileMeta{}, f)

	// now one that doesn't exist
	f, err = ts.GetMeta("targets/a/b")
	require.Error(t, err)
	require.IsType(t, ErrMissingMeta{}, err)
	require.Nil(t, f)
}
Example #19
0
// GetSnapshot returns the snapshot checksum, or an error if it is missing.
func TestTimestampGetSnapshot(t *testing.T) {
	ts := validTimestampTemplate()
	f, err := ts.GetSnapshot()
	require.NoError(t, err)
	require.IsType(t, &FileMeta{}, f)

	// no timestamp meta
	delete(ts.Signed.Meta, CanonicalSnapshotRole)
	f, err = ts.GetSnapshot()
	require.Error(t, err)
	require.IsType(t, ErrMissingMeta{}, err)
	require.Nil(t, f)
}
Example #20
0
// The version cannot be negative
func TestRootFromSignedValidatesVersion(t *testing.T) {
	root := validRootTemplate()
	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)
}
Example #21
0
// The version cannot be negative
func TestSnapshotFromSignedValidatesVersion(t *testing.T) {
	sn := validSnapshotTemplate()
	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)
}
Example #22
0
// The version cannot be negative
func TestTimestampFromSignedValidatesVersion(t *testing.T) {
	ts := validTimestampTemplate()
	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)
}
func testLRUCache(t *testing.T, cache util.LRUCache) {
	rlruCache := cache.(*RedisLRUCache)
	rlruCache.Purge()
	N := 256
	for i := 0; i < N; i++ {
		cache.Add(strconv.Itoa(i), i)
	}

	// Make sure out keys are correct
	assert.Equal(t, N, cache.Len())
	assert.Equal(t, N, len(rlruCache.Keys()))
	for _, k := range rlruCache.Keys() {
		assert.IsType(t, "", k)
		v, ok := cache.Get(k)
		assert.True(t, ok)
		assert.IsType(t, 0, v)
		assert.Equal(t, k, strconv.Itoa(v.(int)))
	}

	for i := 0; i < N; i++ {
		found, ok := cache.Get(strconv.Itoa(i))
		assert.True(t, ok)
		assert.IsType(t, 0, found)
		assert.Equal(t, found.(int), i)
	}

	for i := 0; i < N; i++ {
		_, ok := cache.Get(strconv.Itoa(i))
		assert.True(t, ok)
		oldLen := cache.Len()
		cache.Remove(strconv.Itoa(i))
		assert.Equal(t, oldLen-1, cache.Len())
	}
	assert.Equal(t, 0, cache.Len())

	// Add some TestStructs to make sure the codec works.
	for i := 0; i < N; i++ {
		strKey := "structkey-" + strconv.Itoa(i)
		ts := &TestStruct{
			PixelDiffFilePath: "somesting-" + strconv.Itoa(i),
			MaxRGBADiffs:      []int{i * 4, i*4 + 1, i*4 + 2, i*4 + 3},
		}
		cache.Add(strKey, ts)
		assert.Equal(t, i+1, cache.Len())
		foundTS, ok := cache.Get(strKey)
		assert.True(t, ok)
		assert.IsType(t, &TestStruct{}, foundTS)
		assert.Equal(t, ts, foundTS)
	}
}
Example #24
0
// Applying a delegation whose parent doesn't exist fails.
func TestApplyTargetsDelegationParentDoesntExist(t *testing.T) {
	repo, cs, err := testutils.EmptyRepo("docker.com/notary")
	require.NoError(t, err)

	// make sure a key exists for the previous level, so it's not a missing
	// key error, but we don't care about this key
	_, err = cs.Create("targets/level1", "docker.com/notary", data.ED25519Key)
	require.NoError(t, err)

	newKey, err := cs.Create("targets/level1/level2", "docker.com/notary", data.ED25519Key)
	require.NoError(t, err)

	// create delegation
	kl := data.KeyList{newKey}
	td := &changelist.TUFDelegation{
		NewThreshold: 1,
		AddKeys:      kl,
	}

	tdJSON, err := json.Marshal(td)
	require.NoError(t, err)

	ch := changelist.NewTUFChange(
		changelist.ActionCreate,
		"targets/level1/level2",
		changelist.TypeTargetsDelegation,
		"",
		tdJSON,
	)

	err = applyTargetsChange(repo, nil, ch)
	require.Error(t, err)
	require.IsType(t, data.ErrInvalidRole{}, err)
}
Example #25
0
func TestApplyTargetsDelegationEditNonExisting(t *testing.T) {
	repo, cs, err := testutils.EmptyRepo("docker.com/notary")
	require.NoError(t, err)

	newKey, err := cs.Create("targets/level1", "docker.com/notary", data.ED25519Key)
	require.NoError(t, err)

	// create delegation
	kl := data.KeyList{newKey}
	td := &changelist.TUFDelegation{
		NewThreshold: 1,
		AddKeys:      kl,
		AddPaths:     []string{"level1"},
	}

	tdJSON, err := json.Marshal(td)
	require.NoError(t, err)

	ch := changelist.NewTUFChange(
		changelist.ActionUpdate,
		"targets/level1",
		changelist.TypeTargetsDelegation,
		"",
		tdJSON,
	)

	err = applyTargetsChange(repo, nil, ch)
	require.Error(t, err)
	require.IsType(t, data.ErrInvalidRole{}, err)
}
func testUpdateRemoteNon200Error(t *testing.T, opts updateOpts, errExpected interface{}) {
	_, serverSwizzler := newServerSwizzler(t)
	ts := readOnlyServer(t, serverSwizzler.MetadataCache, opts.notFoundCode, "docker.com/notary")
	defer ts.Close()

	repo := newBlankRepo(t, ts.URL)
	defer os.RemoveAll(repo.baseDir)

	if opts.localCache {
		_, err := repo.Update(false) // acquire local cache
		require.NoError(t, err)
	}

	if opts.serverHasNewData {
		bumpVersions(t, serverSwizzler, 1)
	}

	require.NoError(t, serverSwizzler.RemoveMetadata(opts.role), "failed to remove %s", opts.role)

	_, err := repo.Update(opts.forWrite)
	if errExpected == nil {
		require.NoError(t, err, "expected no failure updating when %s is %v (forWrite: %v)",
			opts.role, opts.notFoundCode, opts.forWrite)
	} else {
		require.Error(t, err, "expected failure updating when %s is %v (forWrite: %v)",
			opts.role, opts.notFoundCode, opts.forWrite)
		require.IsType(t, errExpected, err, "wrong update error when %s is %v (forWrite: %v)",
			opts.role, opts.notFoundCode, opts.forWrite)
		if notFound, ok := err.(store.ErrMetaNotFound); ok {
			require.True(t, strings.HasPrefix(notFound.Resource, opts.role), "wrong resource missing (forWrite: %v)", opts.forWrite)
		}
	}
}
Example #27
0
// 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)
}
Example #28
0
func testContainerMkdir(t *testing.T) {
	req := &fuse.MkdirRequest{Name: directoryName}
	dir, err := ctx.c.Mkdir(nil, req)
	assert.Nil(t, err)
	require.IsType(t, &Directory{}, dir)
	ctx.d, _ = dir.(*Directory)
}
Example #29
0
func testDirectorySymlink(t *testing.T) {
	req := &fuse.SymlinkRequest{Target: oldFileName, NewName: symlinkName}
	sym, err := ctx.d.Symlink(nil, req)
	assert.Nil(t, err)
	require.IsType(t, &Symlink{}, sym)
	ctx.s, _ = sym.(*Symlink)
}
Example #30
0
func testDirectoryHardlink(t *testing.T) {
	req := &fuse.LinkRequest{NewName: hardlinkName}
	link, err := ctx.d.Link(nil, req, ctx.f)
	assert.Nil(t, err)
	require.IsType(t, &Object{}, link)
	ctx.l, _ = link.(*Object)
}