Exemplo n.º 1
0
func TestECDSAVerifierWithInvalidSignature(t *testing.T) {
	var testECDSAKey data.PrivateKey
	var jsonKey bytes.Buffer

	// Execute our template
	templ, _ := template.New("KeyTemplate").Parse(baseECDSAKey)
	templ.Execute(&jsonKey, KeyTemplate{KeyType: data.ECDSAKey})

	testECDSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
	assert.NoError(t, err)

	// Sign some data using ECDSA
	message := []byte("test data for signing")
	hashed := sha256.Sum256(message)
	signedData, err := ecdsaSign(testECDSAKey, hashed[:])
	assert.NoError(t, err)

	// Modify the signature
	signedData[0]++

	// Create and call Verify on the verifier
	ecdsaVerifier := ECDSAVerifier{}
	err = ecdsaVerifier.Verify(testECDSAKey, signedData, message)
	assert.Error(t, err, "signature verification failed")

}
Exemplo n.º 2
0
func TestRSAPKCS1v15VerifierWithInvalidSignature(t *testing.T) {
	var testRSAKey data.PrivateKey
	var jsonKey bytes.Buffer

	// Execute our template
	templ, _ := template.New("KeyTemplate").Parse(baseRSAKey)
	templ.Execute(&jsonKey, KeyTemplate{KeyType: data.RSAKey})

	testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
	require.NoError(t, err)

	// Sign some data using RSAPKCS1v15
	message := []byte("test data for signing")
	hash := crypto.SHA256
	hashed := sha256.Sum256(message)
	signedData, err := rsaPKCS1v15Sign(testRSAKey, hash, hashed[:])
	require.NoError(t, err)

	// Modify the signature
	signedData[0]++

	// Create and call Verify on the verifier
	rsaVerifier := RSAPKCS1v15Verifier{}
	err = rsaVerifier.Verify(testRSAKey, signedData, message)
	require.Error(t, err, "signature verification failed")
}
Exemplo n.º 3
0
// reads data from the repository in order to fake data being served via
// the ServeMux.
func fakeServerData(t *testing.T, repo *NotaryRepository, mux *http.ServeMux) {
	tempKey, err := data.UnmarshalPrivateKey([]byte(timestampECDSAKeyJSON))
	assert.NoError(t, err)

	savedTUFRepo := repo.tufRepo // in case this is overwritten

	fileStore, err := trustmanager.NewKeyFileStore(repo.baseDir, passphraseRetriever)
	assert.NoError(t, err)
	fileStore.AddKey(
		filepath.Join(filepath.FromSlash(repo.gun), tempKey.ID()),
		"nonroot", tempKey)

	rootJSONFile := filepath.Join(repo.baseDir, "tuf",
		filepath.FromSlash(repo.gun), "metadata", "root.json")
	rootFileBytes, err := ioutil.ReadFile(rootJSONFile)

	signedTargets, err := savedTUFRepo.SignTargets(
		"targets", data.DefaultExpires("targets"))
	assert.NoError(t, err)

	signedSnapshot, err := savedTUFRepo.SignSnapshot(
		data.DefaultExpires("snapshot"))
	assert.NoError(t, err)

	signedTimestamp, err := savedTUFRepo.SignTimestamp(
		data.DefaultExpires("timestamp"))
	assert.NoError(t, err)

	mux.HandleFunc("/v2/docker.com/notary/_trust/tuf/root.json",
		func(w http.ResponseWriter, r *http.Request) {
			assert.NoError(t, err)
			fmt.Fprint(w, string(rootFileBytes))
		})

	mux.HandleFunc("/v2/docker.com/notary/_trust/tuf/timestamp.json",
		func(w http.ResponseWriter, r *http.Request) {
			timestampJSON, _ := json.Marshal(signedTimestamp)
			fmt.Fprint(w, string(timestampJSON))
		})

	mux.HandleFunc("/v2/docker.com/notary/_trust/tuf/snapshot.json",
		func(w http.ResponseWriter, r *http.Request) {
			snapshotJSON, _ := json.Marshal(signedSnapshot)
			fmt.Fprint(w, string(snapshotJSON))
		})

	mux.HandleFunc("/v2/docker.com/notary/_trust/tuf/targets.json",
		func(w http.ResponseWriter, r *http.Request) {
			targetsJSON, _ := json.Marshal(signedTargets)
			fmt.Fprint(w, string(targetsJSON))
		})
}
Exemplo n.º 4
0
func TestRSAPSSVerifierWithInvalidKeyType(t *testing.T) {
	var testRSAKey data.PrivateKey
	var jsonKey bytes.Buffer

	// Execute our template
	templ, _ := template.New("KeyTemplate").Parse(baseRSAKey)
	templ.Execute(&jsonKey, KeyTemplate{KeyType: "rsa-invalid"})

	testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
	assert.NoError(t, err)

	// Valid signed data with invalidRsaKeyJSON
	signedData, _ := hex.DecodeString("2741a57a5ef89f841b4e0a6afbcd7940bc982cd919fbd11dfc21b5ccfe13855b9c401e3df22da5480cef2fa585d0f6dfc6c35592ed92a2a18001362c3a17f74da3906684f9d81c5846bf6a09e2ede6c009ae164f504e6184e666adb14eadf5f6e12e07ff9af9ad49bf1ea9bcfa3bebb2e33be7d4c0fabfe39534f98f1e3c4bff44f637cff3dae8288aea54d86476a3f1320adc39008eae24b991c1de20744a7967d2e685ac0bcc0bc725947f01c9192ffd3e9300eba4b7faa826e84478493fdf97c705dd331dd46072050d6c5e317c2d63df21694dbaf909ebf46ce0ff04f3979fe13723ae1a823c65f27e56efa19e88f9e7b8ee56eac34353b944067deded3a")
	message := []byte("test data for signing")

	// Create and call Verify on the verifier
	rsaVerifier := RSAPSSVerifier{}
	err = rsaVerifier.Verify(testRSAKey, signedData, message)
	assert.Error(t, err, "invalid key type for RSAPSS verifier: rsa-invalid")
}
Exemplo n.º 5
0
func TestECDSAVerifierWithInvalidKey(t *testing.T) {
	var testECDSAKey data.PrivateKey
	var jsonKey bytes.Buffer

	// Execute our template
	templ, _ := template.New("KeyTemplate").Parse(baseRSAKey)
	templ.Execute(&jsonKey, KeyTemplate{KeyType: "rsa"})

	testECDSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
	assert.NoError(t, err)

	// Valid signature using invalidECDSAx509Key
	signedData, _ := hex.DecodeString("7b1c45a4dd488a087db46ee459192d890d4f52352620cb84c2c10e0ce8a67fd6826936463a91ffdffab8e6f962da6fc3d3e5735412f7cd161a9fcf97ba1a7033")
	message := []byte("test data for signing")

	// Create and call Verify on the verifier
	ecdsaVerifier := ECDSAVerifier{}
	err = ecdsaVerifier.Verify(testECDSAKey, signedData, message)
	assert.Error(t, err, "invalid key type for ECDSA verifier: rsa")
}
Exemplo n.º 6
0
func TestRSAPSSx509Verifier(t *testing.T) {
	// Unmarshal our public RSA Key
	var testRSAKey data.PrivateKey
	var jsonKey bytes.Buffer

	// Execute our template
	templ, _ := template.New("KeyTemplate").Parse(baseRSAx509Key)
	templ.Execute(&jsonKey, KeyTemplate{KeyType: data.RSAx509Key})

	testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
	assert.NoError(t, err)

	// Valid signed message
	signedData, _ := hex.DecodeString("3de02fa54cdba45c67860f058b7cff1ba264610dc3c5b466b7df027bc52068bdf2956fe438dba08b0b71daa0780a3037bf8f50a09d91ca81fa872bbdbbbff6ef17e04df8741ad5c2f2c3ea5de97d6ffaf4999c83fdfba4b6cb2443da11c7b7eea84123c2fdaf3319fa6342cbbdbd1aa25d1ac20aeee687e48cbf191cc8f68049230261469eeada33dec0af74287766bd984dd01820a7edfb8b0d030e2fcf00886c578b07eb905a2eebc81fd982a578e717c7ac773cab345950c71e1eaf81b70401e5bf3c67cdcb9068bf4b50ff0456b530b3cec5586827eb39b123f9d666a65f4b418a355438ed1753da8a27577ab9cd791d7b840c7e34ecc1290c46d98aa0dd73c0427f6ef8f63e36af42e9657520b8f56c9231ba7e0172dfc3456c63c54e9eae95d06bafe571e91afa1e42d4010e60dd5c441df112cc8474253eee7f1d6c5350039ffcd1f8b0bb013e4403c16fc5b40d6bd56b742ea1ed82c87880147db194b33b022077cc2e8d31ef3eada3e46683ad437ad8ef7ecbe03c29d7a53a9771e42cc4f9d782813c491186fde2cd1dfa408c4e21dd4c3ca1664e901772ffe1713e37b07c9287572114865a05e17cbe29d8622c6b033dcb43c9721d0943c58098607cc28bd58b3caf3dfc1f66d01ebfaf1aa5c2c5945c23af83fe114e587fa7bcbaea6bdccff3c0ad03ce3328f67af30168e225e5827ad9e94b4702de984e6dd775")
	message := []byte("test data for signing")

	// Create and call Verify on the verifier
	rsaVerifier := RSAPSSVerifier{}
	err = rsaVerifier.Verify(testRSAKey, signedData, message)
	assert.NoError(t, err, "expecting success but got error while verifying data using RSAPSS and an X509 encoded Key")
}
Exemplo n.º 7
0
func TestRSAPKCS1v15x509Verifier(t *testing.T) {
	// Unmarshal our public RSA Key
	var testRSAKey data.PrivateKey
	var jsonKey bytes.Buffer

	// Execute our template
	templ, _ := template.New("KeyTemplate").Parse(baseRSAx509Key)
	templ.Execute(&jsonKey, KeyTemplate{KeyType: data.RSAx509Key})

	testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
	assert.NoError(t, err)

	// Valid signed message
	signedData, _ := hex.DecodeString("a19602f609646d57f3d0db930bbe491a997baf33f13191916713734ae778ddb4898ece2078741bb0c24d726514c6b4538c3665c374b0b8ec9ff234b45459633268224c9962756ad3684aca5f13a286657375e798ddcb857ed2707c900f097666b958df56b43b790357430c2e7a5c379ba9972c8b008363c144aac5c7e0fbfad83cf6855cf73baf8e3ad774e910ba6ac8dc4cce58fe19cffb7b0a1feaa73d23ebd2d59de2d7d9e98a809d73a310c5396df64ff7a22d735e661e39d37a6c4a013caa6005e91f597ea35db24e6c750d704d292a180128dcf72a818c53a96b0a83ba0414a3611097905262eb79a6ced1484af27c7da6809aa21ae7c6f05ae6568d5e5d9c170470213a30caf2340c3d52e7bd4056d22074daffee6e29d0a6fd3ca6dbd001831fb1e48573f3663b63e110cde19efaf56e49a835aeda82e4d7286de591376ecd03de36d402ec703f39f79b2f764f991d8950a119f2618f6d4e4618114900597a1e89ced609949410623a17b97095afe08babc4c295ade954f055ca01b7909f5585e98eb99bd916583476aa877d20da8f4fe35c0867e934f41c935d469664b80904a93f9f4d9432cabd9383e08559d6452f8e12b2d861412c450709ff874ad63c25a640605a41c4073f0eb4e16e1965abf8e088e210cbf9d3ca884ec2c13fc8a288cfcef2425d9607fcab01dab45c5c346671a9ae1d0e52c81379fa212c")
	message := []byte("test data for signing")

	// Create and call Verify on the verifier
	rsaVerifier := RSAPKCS1v15Verifier{}
	err = rsaVerifier.Verify(testRSAKey, signedData, message)
	assert.NoError(t, err, "expecting success but got error while verifying data using RSAPKCS1v15 and an X509 encoded Key")
}
Exemplo n.º 8
0
func TestECDSAVerifier(t *testing.T) {
	var testECDSAKey data.PrivateKey
	var jsonKey bytes.Buffer

	// Execute our template
	templ, _ := template.New("KeyTemplate").Parse(baseECDSAKey)
	templ.Execute(&jsonKey, KeyTemplate{KeyType: data.ECDSAKey})

	testECDSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
	assert.NoError(t, err)

	// Sign some data using ECDSA
	message := []byte("test data for signing")
	hashed := sha256.Sum256(message)
	signedData, err := ecdsaSign(testECDSAKey, hashed[:])
	assert.NoError(t, err)

	// Create and call Verify on the verifier
	ecdsaVerifier := ECDSAVerifier{}
	err = ecdsaVerifier.Verify(testECDSAKey, signedData, message)
	assert.NoError(t, err, "expecting success but got error while verifying data using ECDSA")
}
Exemplo n.º 9
0
func TestRSAPSSVerifier(t *testing.T) {
	// Unmarshal our private RSA Key
	var testRSAKey data.PrivateKey
	var jsonKey bytes.Buffer

	// Execute our template
	templ, _ := template.New("KeyTemplate").Parse(baseRSAKey)
	templ.Execute(&jsonKey, KeyTemplate{KeyType: data.RSAKey})

	testRSAKey, err := data.UnmarshalPrivateKey(jsonKey.Bytes())
	assert.NoError(t, err)

	// Sign some data using RSAPSS
	message := []byte("test data for signing")
	hash := crypto.SHA256
	hashed := sha256.Sum256(message)
	signedData, err := rsaPSSSign(testRSAKey, hash, hashed[:])
	assert.NoError(t, err)

	// Create and call Verify on the verifier
	rsaVerifier := RSAPSSVerifier{}
	err = rsaVerifier.Verify(testRSAKey, signedData, message)
	assert.NoError(t, err, "expecting success but got error while verifying data using RSA PSS")
}
Exemplo n.º 10
0
func testAddListTarget(t *testing.T, rootType string) {
	// Temporary directory where test files will be created
	tempBaseDir, err := ioutil.TempDir("", "notary-test-")
	defer os.RemoveAll(tempBaseDir)

	assert.NoError(t, err, "failed to create a temporary directory: %s", err)

	gun := "docker.com/notary"

	ts, mux := createTestServer(t)
	defer ts.Close()

	repo, err := NewNotaryRepository(tempBaseDir, gun, ts.URL, http.DefaultTransport, passphraseRetriever)
	assert.NoError(t, err, "error creating repository: %s", err)

	rootKeyID, err := repo.KeyStoreManager.GenRootKey(rootType)
	assert.NoError(t, err, "error generating root key: %s", err)

	err = repo.Initialize(rootKeyID)
	assert.NoError(t, err, "error creating repository: %s", err)

	// tests need to manually boostrap timestamp as client doesn't generate it
	err = repo.tufRepo.InitTimestamp()
	assert.NoError(t, err, "error creating repository: %s", err)

	// Add fixtures/intermediate-ca.crt as a target. There's no particular reason
	// for using this file except that it happens to be available as
	// a fixture.
	latestTarget, err := NewTarget("latest", "../fixtures/intermediate-ca.crt")
	assert.NoError(t, err, "error creating target")
	err = repo.AddTarget(latestTarget)
	assert.NoError(t, err, "error adding target")

	// Look for the changelist file
	changelistDirPath := filepath.Join(tempBaseDir, "tuf", filepath.FromSlash(gun), "changelist")

	changelistDir, err := os.Open(changelistDirPath)
	assert.NoError(t, err, "could not open changelist directory")

	fileInfos, err := changelistDir.Readdir(0)
	assert.NoError(t, err, "could not read changelist directory")

	// Should only be one file in the directory
	assert.Len(t, fileInfos, 1, "wrong number of changelist files found")

	clName := fileInfos[0].Name()
	raw, err := ioutil.ReadFile(filepath.Join(changelistDirPath, clName))
	assert.NoError(t, err, "could not read changelist file %s", clName)

	c := &changelist.TufChange{}
	err = json.Unmarshal(raw, c)
	assert.NoError(t, err, "could not unmarshal changelist file %s", clName)

	assert.EqualValues(t, changelist.ActionCreate, c.Actn)
	assert.Equal(t, "targets", c.Role)
	assert.Equal(t, "target", c.ChangeType)
	assert.Equal(t, "latest", c.ChangePath)
	assert.NotEmpty(t, c.Data)

	changelistDir.Close()

	// Create a second target
	currentTarget, err := NewTarget("current", "../fixtures/intermediate-ca.crt")
	assert.NoError(t, err, "error creating target")
	err = repo.AddTarget(currentTarget)
	assert.NoError(t, err, "error adding target")

	changelistDir, err = os.Open(changelistDirPath)
	assert.NoError(t, err, "could not open changelist directory")

	// There should now be a second file in the directory
	fileInfos, err = changelistDir.Readdir(0)
	assert.NoError(t, err, "could not read changelist directory")

	assert.Len(t, fileInfos, 2, "wrong number of changelist files found")

	newFileFound := false
	for _, fileInfo := range fileInfos {
		if fileInfo.Name() != clName {
			clName2 := fileInfo.Name()
			raw, err := ioutil.ReadFile(filepath.Join(changelistDirPath, clName2))
			assert.NoError(t, err, "could not read changelist file %s", clName2)

			c := &changelist.TufChange{}
			err = json.Unmarshal(raw, c)
			assert.NoError(t, err, "could not unmarshal changelist file %s", clName2)

			assert.EqualValues(t, changelist.ActionCreate, c.Actn)
			assert.Equal(t, "targets", c.Role)
			assert.Equal(t, "target", c.ChangeType)
			assert.Equal(t, "current", c.ChangePath)
			assert.NotEmpty(t, c.Data)

			newFileFound = true
			break
		}
	}

	assert.True(t, newFileFound, "second changelist file not found")

	changelistDir.Close()

	// Now test ListTargets. In preparation, we need to expose some signed
	// metadata files on the internal HTTP server.

	// Apply the changelist. Normally, this would be done by Publish

	// load the changelist for this repo
	cl, err := changelist.NewFileChangelist(filepath.Join(tempBaseDir, "tuf", filepath.FromSlash(gun), "changelist"))
	assert.NoError(t, err, "could not open changelist")

	// apply the changelist to the repo
	err = applyChangelist(repo.tufRepo, cl)
	assert.NoError(t, err, "could not apply changelist")

	tempKey, err := data.UnmarshalPrivateKey([]byte(timestampECDSAKeyJSON))
	assert.NoError(t, err)

	repo.KeyStoreManager.KeyStore.AddKey(filepath.Join(filepath.FromSlash(gun), tempKey.ID()), "nonroot", tempKey)

	// Because ListTargets will clear this
	savedTUFRepo := repo.tufRepo

	rootJSONFile := filepath.Join(tempBaseDir, "tuf", filepath.FromSlash(gun), "metadata", "root.json")
	rootFileBytes, err := ioutil.ReadFile(rootJSONFile)

	signedTargets, err := savedTUFRepo.SignTargets("targets", data.DefaultExpires("targets"))
	assert.NoError(t, err)

	signedSnapshot, err := savedTUFRepo.SignSnapshot(data.DefaultExpires("snapshot"))
	assert.NoError(t, err)

	signedTimestamp, err := savedTUFRepo.SignTimestamp(data.DefaultExpires("timestamp"))
	assert.NoError(t, err)

	mux.HandleFunc("/v2/docker.com/notary/_trust/tuf/root.json", func(w http.ResponseWriter, r *http.Request) {
		assert.NoError(t, err)
		fmt.Fprint(w, string(rootFileBytes))
	})

	mux.HandleFunc("/v2/docker.com/notary/_trust/tuf/timestamp.json", func(w http.ResponseWriter, r *http.Request) {
		timestampJSON, _ := json.Marshal(signedTimestamp)
		fmt.Fprint(w, string(timestampJSON))
	})

	mux.HandleFunc("/v2/docker.com/notary/_trust/tuf/snapshot.json", func(w http.ResponseWriter, r *http.Request) {
		snapshotJSON, _ := json.Marshal(signedSnapshot)
		fmt.Fprint(w, string(snapshotJSON))
	})

	mux.HandleFunc("/v2/docker.com/notary/_trust/tuf/targets.json", func(w http.ResponseWriter, r *http.Request) {
		targetsJSON, _ := json.Marshal(signedTargets)
		fmt.Fprint(w, string(targetsJSON))
	})

	targets, err := repo.ListTargets()
	assert.NoError(t, err)

	// Should be two targets
	assert.Len(t, targets, 2, "unexpected number of targets returned by ListTargets")

	if targets[0].Name == "latest" {
		assert.Equal(t, latestTarget, targets[0], "latest target does not match")
		assert.Equal(t, currentTarget, targets[1], "current target does not match")
	} else if targets[0].Name == "current" {
		assert.Equal(t, currentTarget, targets[0], "current target does not match")
		assert.Equal(t, latestTarget, targets[1], "latest target does not match")
	} else {
		t.Fatalf("unexpected target name: %s", targets[0].Name)
	}

	// Also test GetTargetByName
	newLatestTarget, err := repo.GetTargetByName("latest")
	assert.NoError(t, err)
	assert.Equal(t, latestTarget, newLatestTarget, "latest target does not match")

	newCurrentTarget, err := repo.GetTargetByName("current")
	assert.NoError(t, err)
	assert.Equal(t, currentTarget, newCurrentTarget, "current target does not match")
}
Exemplo n.º 11
0
func validateRootSuccessfully(t *testing.T, rootType string) {
	// Temporary directory where test files will be created
	tempBaseDir, err := ioutil.TempDir("", "notary-test-")
	defer os.RemoveAll(tempBaseDir)

	assert.NoError(t, err, "failed to create a temporary directory: %s", err)

	gun := "docker.com/notary"

	ts, mux := createTestServer(t)
	defer ts.Close()

	repo, err := NewNotaryRepository(tempBaseDir, gun, ts.URL, http.DefaultTransport, passphraseRetriever)
	assert.NoError(t, err, "error creating repository: %s", err)

	rootKeyID, err := repo.KeyStoreManager.GenRootKey(rootType)
	assert.NoError(t, err, "error generating root key: %s", err)

	err = repo.Initialize(rootKeyID)
	assert.NoError(t, err, "error creating repository: %s", err)

	// tests need to manually boostrap timestamp as client doesn't generate it
	err = repo.tufRepo.InitTimestamp()
	assert.NoError(t, err, "error creating repository: %s", err)

	// Initialize is supposed to have created new certificate for this repository
	// Lets check for it and store it for later use
	allCerts := repo.KeyStoreManager.TrustedCertificateStore().GetCertificates()
	assert.Len(t, allCerts, 1)

	// Now test ListTargets. In preparation, we need to expose some signed
	// metadata files on the internal HTTP server.
	tempKey, err := data.UnmarshalPrivateKey([]byte(timestampECDSAKeyJSON))
	assert.NoError(t, err)

	repo.KeyStoreManager.KeyStore.AddKey(filepath.Join(filepath.FromSlash(gun), tempKey.ID()), "root", tempKey)

	// Because ListTargets will clear this
	savedTUFRepo := repo.tufRepo

	rootJSONFile := filepath.Join(tempBaseDir, "tuf", filepath.FromSlash(gun), "metadata", "root.json")
	rootFileBytes, err := ioutil.ReadFile(rootJSONFile)

	signedTargets, err := savedTUFRepo.SignTargets("targets", data.DefaultExpires("targets"))
	assert.NoError(t, err)

	signedSnapshot, err := savedTUFRepo.SignSnapshot(data.DefaultExpires("snapshot"))
	assert.NoError(t, err)

	signedTimestamp, err := savedTUFRepo.SignTimestamp(data.DefaultExpires("timestamp"))
	assert.NoError(t, err)

	mux.HandleFunc("/v2/docker.com/notary/_trust/tuf/root.json", func(w http.ResponseWriter, r *http.Request) {
		assert.NoError(t, err)
		fmt.Fprint(w, string(rootFileBytes))
	})

	mux.HandleFunc("/v2/docker.com/notary/_trust/tuf/timestamp.json", func(w http.ResponseWriter, r *http.Request) {
		timestampJSON, _ := json.Marshal(signedTimestamp)
		fmt.Fprint(w, string(timestampJSON))
	})

	mux.HandleFunc("/v2/docker.com/notary/_trust/tuf/snapshot.json", func(w http.ResponseWriter, r *http.Request) {
		snapshotJSON, _ := json.Marshal(signedSnapshot)
		fmt.Fprint(w, string(snapshotJSON))
	})

	mux.HandleFunc("/v2/docker.com/notary/_trust/tuf/targets.json", func(w http.ResponseWriter, r *http.Request) {
		targetsJSON, _ := json.Marshal(signedTargets)
		fmt.Fprint(w, string(targetsJSON))
	})

	_, err = repo.ListTargets()
	assert.NoError(t, err)

	//
	// Test TOFUS logic. We remove all certs and expect a new one to be added after ListTargets
	//
	err = repo.KeyStoreManager.TrustedCertificateStore().RemoveAll()
	assert.NoError(t, err)
	assert.Len(t, repo.KeyStoreManager.TrustedCertificateStore().GetCertificates(), 0)

	// This list targets is expected to succeed and the certificate store to have the new certificate
	_, err = repo.ListTargets()
	assert.NoError(t, err)
	assert.Len(t, repo.KeyStoreManager.TrustedCertificateStore().GetCertificates(), 1)

	//
	// Test certificate mismatch logic. We remove all certs, add a different cert to the
	// same CN, and expect ValidateRoot to fail
	//

	// First, remove all certs
	err = repo.KeyStoreManager.TrustedCertificateStore().RemoveAll()
	assert.NoError(t, err)
	assert.Len(t, repo.KeyStoreManager.TrustedCertificateStore().GetCertificates(), 0)

	// Add a previously generated certificate with CN=docker.com/notary
	err = repo.KeyStoreManager.TrustedCertificateStore().AddCertFromFile("../fixtures/self-signed_docker.com-notary.crt")
	assert.NoError(t, err)

	// This list targets is expected to fail, since there already exists a certificate
	// in the store for the dnsName docker.com/notary, so TOFUS doesn't apply
	_, err = repo.ListTargets()
	if assert.Error(t, err, "An error was expected") {
		assert.Equal(t, err, &keystoremanager.ErrValidationFail{Reason: "failed to validate data with current trusted certificates"})
	}
}