Repository: docker/notary
Pull request #234 (2015-10-24 01:46:53)

Remove symlinking root keys
This may break backwards compatibility with import/export, but as per discussion with @diogomonica, no one is really using import/export yet, so that is probably ok.

Update: I have tested this against an existing `.notary` directory with a bunch of symlinked keys (not importing and exporting though), and regular init/add/publish/list operations work.  Switching back to the older version of notary client continued to function, since the symlinks weren't removed.


Patch:
diff --git a/client/client.go b/client/client.go
index a1541809..2d8643d0 100644
--- a/client/client.go
+++ b/client/client.go
@@ -23,6 +23,7 @@ import (
 	"github.com/endophage/gotuf/keys"
 	"github.com/endophage/gotuf/signed"
 	"github.com/endophage/gotuf/store"
+	tufutils "github.com/endophage/gotuf/utils"
 )
 
 const maxSize = 5 << 20
@@ -162,15 +163,6 @@ func (r *NotaryRepository) Initialize(uCryptoService *cryptoservice.UnlockedCryp
 	// Generate a x509Key using the rootCert as the public key
 	rootKey := data.NewPublicKey(algorithmType, trustmanager.CertToPEM(rootCert))
 
-	// Creates a symlink between the certificate ID and the real public key it
-	// is associated with. This is used to be able to retrieve the root private key
-	// associated with a particular certificate
-	logrus.Debugf("Linking %s to %s.", rootKey.ID(), uCryptoService.ID())
-	err = r.KeyStoreManager.RootKeyStore().Link(uCryptoService.ID()+"_root", rootKey.ID()+"_root")
-	if err != nil {
-		return err
-	}
-
 	// All the timestamp keys are generated by the remote server.
 	remote, err := getRemoteStore(r.baseURL, r.gun, r.roundTrip)
 	if err != nil {
@@ -400,7 +392,16 @@ func (r *NotaryRepository) Publish() error {
 			return err
 		}
 		rootKeyID := r.tufRepo.Root.Signed.Roles["root"].KeyIDs[0]
-		rootCryptoService, err := r.KeyStoreManager.GetRootCryptoService(rootKeyID)
+		rootKey, ok := r.tufRepo.Root.Signed.Keys[rootKeyID]
+		if !ok {
+			return errors.New(
+				"Root was signed with %s, which is not in its list of keys.")
+		}
+		canonicalRootID, err := tufutils.CanonicalKeyID(rootKey)
+		if err != nil {
+			return err
+		}
+		rootCryptoService, err := r.KeyStoreManager.GetRootCryptoService(canonicalRootID)
 		if err != nil {
 			return err
 		}
diff --git a/keystoremanager/import_export.go b/keystoremanager/import_export.go
index 7b0cee94..05624ad1 100644
--- a/keystoremanager/import_export.go
+++ b/keystoremanager/import_export.go
@@ -16,10 +16,7 @@ import (
 	"github.com/docker/notary/trustmanager"
 )
 
-const (
-	zipSymlinkAttr = 0xA1ED0000
-	zipMadeByUNIX  = 3 << 8
-)
+const zipMadeByUNIX = 3 << 8
 
 var (
 	// ErrNoValidPrivateKey is returned if a key being imported doesn't
@@ -117,7 +114,6 @@ func (km *KeyStoreManager) ImportRootKey(source io.Reader, keyID string) error {
 }
 
 func moveKeys(oldKeyStore, newKeyStore *trustmanager.KeyFileStore) error {
-	// List all files but no symlinks
 	for f := range oldKeyStore.ListKeys() {
 		privateKey, alias, err := oldKeyStore.GetKey(f)
 		if err != nil {
@@ -131,29 +127,11 @@ func moveKeys(oldKeyStore, newKeyStore *trustmanager.KeyFileStore) error {
 		}
 	}
 
-	// Recreate symlinks
-	for _, relKeyPath := range oldKeyStore.ListFiles(true) {
-		fullKeyPath := filepath.Join(oldKeyStore.BaseDir(), relKeyPath)
-
-		fi, err := os.Lstat(fullKeyPath)
-		if err != nil {
-			return err
-		}
-
-		if (fi.Mode() & os.ModeSymlink) != 0 {
-			target, err := os.Readlink(fullKeyPath)
-			if err != nil {
-				return err
-			}
-			os.Symlink(target, filepath.Join(newKeyStore.BaseDir(), relKeyPath))
-		}
-	}
-
 	return nil
 }
 
 func addKeysToArchive(zipWriter *zip.Writer, newKeyStore *trustmanager.KeyFileStore, subDir string) error {
-	for _, relKeyPath := range newKeyStore.ListFiles(true) {
+	for _, relKeyPath := range newKeyStore.ListFiles() {
 		fullKeyPath := filepath.Join(newKeyStore.BaseDir(), relKeyPath)
 
 		fi, err := os.Lstat(fullKeyPath)
@@ -168,39 +146,18 @@ func addKeysToArchive(zipWriter *zip.Writer, newKeyStore *trustmanager.KeyFileSt
 
 		infoHeader.Name = filepath.Join(subDir, relKeyPath)
 
-		// Is this a symlink? If so, encode properly in the zip file.
-		if (fi.Mode() & os.ModeSymlink) != 0 {
-			infoHeader.CreatorVersion = zipMadeByUNIX
-			infoHeader.ExternalAttrs = zipSymlinkAttr
-
-			zipFileEntryWriter, err := zipWriter.CreateHeader(infoHeader)
-			if err != nil {
-				return err
-			}
-
-			target, err := os.Readlink(fullKeyPath)
-			if err != nil {
-				return err
-			}
-
-			// Write relative path
-			if _, err = zipFileEntryWriter.Write([]byte(target)); err != nil {
-				return err
-			}
-		} else {
-			zipFileEntryWriter, err := zipWriter.CreateHeader(infoHeader)
-			if err != nil {
-				return err
-			}
+		zipFileEntryWriter, err := zipWriter.CreateHeader(infoHeader)
+		if err != nil {
+			return err
+		}
 
-			fileContents, err := ioutil.ReadFile(fullKeyPath)
-			if err != nil {
-				return err
-			}
+		fileContents, err := ioutil.ReadFile(fullKeyPath)
+		if err != nil {
+			return err
+		}
 
-			if _, err = zipFileEntryWriter.Write(fileContents); err != nil {
-				return err
-			}
+		if _, err = zipFileEntryWriter.Write(fileContents); err != nil {
+			return err
 		}
 	}
 
@@ -250,12 +207,6 @@ func (km *KeyStoreManager) ExportAllKeys(dest io.Writer, newPassphraseRetriever
 	return nil
 }
 
-// IsZipSymlink returns true if the file described by the zip file header is a
-// symlink.
-func IsZipSymlink(f *zip.File) bool {
-	return f.CreatorVersion&0xFF00 == zipMadeByUNIX && f.ExternalAttrs == zipSymlinkAttr
-}
-
 // ImportKeysZip imports keys from a zip file provided as an zip.Reader. The
 // keys in the root_keys directory are left encrypted, but the other keys are
 // decrypted with the specified passphrase.
@@ -289,33 +240,19 @@ func (km *KeyStoreManager) ImportKeysZip(zipReader zip.Reader) error {
 		// Note that using / as a separator is okay here - the zip
 		// package guarantees that the separator will be /
 		if strings.HasPrefix(fNameTrimmed, rootKeysPrefix) {
-			if IsZipSymlink(f) {
-				newName := filepath.Join(km.rootKeyStore.BaseDir(), strings.TrimPrefix(f.Name, rootKeysPrefix))
-				err = os.Symlink(string(fileBytes), newName)
-				if err != nil {
-					return err
-				}
-			} else {
-				if err = checkRootKeyIsEncrypted(fileBytes); err != nil {
-					rc.Close()
-					return err
-				}
-				// Root keys are preserved without decrypting
-				keyName := strings.TrimPrefix(fNameTrimmed, rootKeysPrefix)
-				newRootKeys[keyName] = fileBytes
+			if err = checkRootKeyIsEncrypted(fileBytes); err != nil {
+				rc.Close()
+				return err
 			}
+			// Root keys are preserved without decrypting
+			keyName := strings.TrimPrefix(fNameTrimmed, rootKeysPrefix)
+			newRootKeys[keyName] = fileBytes
+
 		} else if strings.HasPrefix(fNameTrimmed, nonRootKeysPrefix) {
-			if IsZipSymlink(f) {
-				newName := filepath.Join(km.nonRootKeyStore.BaseDir(), strings.TrimPrefix(f.Name, nonRootKeysPrefix))
-				err = os.Symlink(string(fileBytes), newName)
-				if err != nil {
-					return err
-				}
-			} else {
-				// Nonroot keys are preserved without decrypting
-				keyName := strings.TrimPrefix(fNameTrimmed, nonRootKeysPrefix)
-				newNonRootKeys[keyName] = fileBytes
-			}
+			// Nonroot keys are preserved without decrypting
+			keyName := strings.TrimPrefix(fNameTrimmed, nonRootKeysPrefix)
+			newNonRootKeys[keyName] = fileBytes
+
 		} else {
 			// This path inside the zip archive doesn't look like a
 			// root key, non-root key, or alias. To avoid adding a file
@@ -345,7 +282,6 @@ func (km *KeyStoreManager) ImportKeysZip(zipReader zip.Reader) error {
 }
 
 func moveKeysByGUN(oldKeyStore, newKeyStore *trustmanager.KeyFileStore, gun string) error {
-	// List all files but no symlinks
 	for relKeyPath := range oldKeyStore.ListKeys() {
 		// Skip keys that aren't associated with this GUN
 		if !strings.HasPrefix(relKeyPath, filepath.FromSlash(gun)) {
diff --git a/trustmanager/filestore.go b/trustmanager/filestore.go
index 5aa3e7ae..4dd106ca 100644
--- a/trustmanager/filestore.go
+++ b/trustmanager/filestore.go
@@ -21,13 +21,12 @@ var (
 	ErrPathOutsideStore = errors.New("path outside file store")
 )
 
-// LimitedFileStore implements the bare bones primitives (no symlinks or
-// hierarchy)
+// LimitedFileStore implements the bare bones primitives (no hierarchy)
 type LimitedFileStore interface {
 	Add(fileName string, data []byte) error
 	Remove(fileName string) error
 	Get(fileName string) ([]byte, error)
-	ListFiles(symlinks bool) []string
+	ListFiles() []string
 }
 
 // FileStore is the interface for full-featured FileStores
@@ -36,8 +35,7 @@ type FileStore interface {
 
 	RemoveDir(directoryName string) error
 	GetPath(fileName string) (string, error)
-	ListDir(directoryName string, symlinks bool) []string
-	Link(src, dst string) error
+	ListDir(directoryName string) []string
 	BaseDir() string
 }
 
@@ -140,18 +138,18 @@ func (f *SimpleFileStore) GetPath(name string) (string, error) {
 }
 
 // ListFiles lists all the files inside of a store
-func (f *SimpleFileStore) ListFiles(symlinks bool) []string {
-	return f.list(f.baseDir, symlinks)
+func (f *SimpleFileStore) ListFiles() []string {
+	return f.list(f.baseDir)
 }
 
 // ListDir lists all the files inside of a directory identified by a name
-func (f *SimpleFileStore) ListDir(name string, symlinks bool) []string {
+func (f *SimpleFileStore) ListDir(name string) []string {
 	fullPath := filepath.Join(f.baseDir, name)
-	return f.list(fullPath, symlinks)
+	return f.list(fullPath)
 }
 
 // list lists all the files in a directory given a full path. Ignores symlinks.
-func (f *SimpleFileStore) list(path string, symlinks bool) []string {
+func (f *SimpleFileStore) list(path string) []string {
 	files := make([]string, 0, 0)
 	filepath.Walk(path, func(fp string, fi os.FileInfo, err error) error {
 		// If there are errors, ignore this particular file
@@ -163,8 +161,8 @@ func (f *SimpleFileStore) list(path string, symlinks bool) []string {
 			return nil
 		}
 
-		// If this is a symlink, and symlinks is true, ignore it
-		if !symlinks && fi.Mode()&os.ModeSymlink == os.ModeSymlink {
+		// If this is a symlink, ignore it
+		if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
 			return nil
 		}
 
@@ -189,19 +187,6 @@ func (f *SimpleFileStore) genFileName(name string) string {
 	return fmt.Sprintf("%s.%s", name, f.fileExt)
 }
 
-// Link creates a symlink between the ID of the certificate used by a repository
-// and the ID of the root key that is being used.
-// We use full path for the source and local for the destination to use relative
-// path for the symlink
-func (f *SimpleFileStore) Link(oldname, newname string) error {
-	newnamePath, err := f.GetPath(newname)
-	if err != nil {
-		return err
-	}
-
-	return os.Symlink(f.genFileName(oldname), newnamePath)
-}
-
 // BaseDir returns the base directory of the filestore
 func (f *SimpleFileStore) BaseDir() string {
 	return f.baseDir
@@ -282,7 +267,7 @@ func (f *MemoryFileStore) Get(name string) ([]byte, error) {
 }
 
 // ListFiles lists all the files inside of a store
-func (f *MemoryFileStore) ListFiles(symlinks bool) []string {
+func (f *MemoryFileStore) ListFiles() []string {
 	var list []string
 
 	for name := range f.files {
diff --git a/trustmanager/keyfilestore.go b/trustmanager/keyfilestore.go
index fc68463d..51f0c4f2 100644
--- a/trustmanager/keyfilestore.go
+++ b/trustmanager/keyfilestore.go
@@ -54,8 +54,6 @@ func (s *KeyFileStore) GetKey(name string) (data.PrivateKey, string, error) {
 }
 
 // ListKeys returns a list of unique PublicKeys present on the KeyFileStore.
-// There might be symlinks associating Certificate IDs to Public Keys, so this
-// method only returns the IDs that aren't symlinks
 func (s *KeyFileStore) ListKeys() map[string]string {
 	return listKeys(s)
 }
@@ -92,8 +90,6 @@ func (s *KeyMemoryStore) GetKey(name string) (data.PrivateKey, string, error) {
 }
 
 // ListKeys returns a list of unique PublicKeys present on the KeyFileStore.
-// There might be symlinks associating Certificate IDs to Public Keys, so this
-// method only returns the IDs that aren't symlinks
 func (s *KeyMemoryStore) ListKeys() map[string]string {
 	return listKeys(s)
 }
@@ -141,7 +137,7 @@ func addKey(s LimitedFileStore, passphraseRetriever passphrase.Retriever, cached
 }
 
 func getKeyAlias(s LimitedFileStore, keyID string) (string, error) {
-	files := s.ListFiles(true)
+	files := s.ListFiles()
 	name := strings.TrimSpace(strings.TrimSuffix(filepath.Base(keyID), filepath.Ext(keyID)))
 
 	for _, file := range files {
@@ -208,12 +204,10 @@ func getKey(s LimitedFileStore, passphraseRetriever passphrase.Retriever, cached
 
 // ListKeys returns a map of unique PublicKeys present on the KeyFileStore and
 // their corresponding aliases.
-// There might be symlinks associating Certificate IDs to Public Keys, so this
-// method only returns the IDs that aren't symlinks
 func listKeys(s LimitedFileStore) map[string]string {
 	keyIDMap := make(map[string]string)
 
-	for _, f := range s.ListFiles(false) {
+	for _, f := range s.ListFiles() {
 		keyIDFull := strings.TrimSpace(strings.TrimSuffix(f, filepath.Ext(f)))
 		keyID := keyIDFull[:strings.LastIndex(keyIDFull, "_")]
 		keyAlias := keyIDFull[strings.LastIndex(keyIDFull, "_")+1:]
diff --git a/trustmanager/x509utils.go b/trustmanager/x509utils.go
index eac624f7..97e75a73 100644
--- a/trustmanager/x509utils.go
+++ b/trustmanager/x509utils.go
@@ -120,7 +120,7 @@ func fingerprintCert(cert *x509.Certificate) (CertID, error) {
 
 // loadCertsFromDir receives a store AddCertFromFile for each certificate found
 func loadCertsFromDir(s *X509FileStore) error {
-	certFiles := s.fileStore.ListFiles(true)
+	certFiles := s.fileStore.ListFiles()
 	for _, f := range certFiles {
 		// ListFiles returns relative paths
 		fullPath := filepath.Join(s.fileStore.BaseDir(), f)


Test patch:
diff --git a/client/client_test.go b/client/client_test.go
index d18e8825..b2264755 100644
--- a/client/client_test.go
+++ b/client/client_test.go
@@ -94,7 +94,7 @@ func testInitRepo(t *testing.T, rootType data.KeyAlgorithm) {
 
 	// Look for keys in private. The filenames should match the key IDs
 	// in the private key store.
-	privKeyList := repo.KeyStoreManager.NonRootKeyStore().ListFiles(true)
+	privKeyList := repo.KeyStoreManager.NonRootKeyStore().ListFiles()
 	for _, privKeyName := range privKeyList {
 		privKeyFileName := filepath.Join(repo.KeyStoreManager.NonRootKeyStore().BaseDir(), privKeyName)
 		_, err := os.Stat(privKeyFileName)
@@ -108,19 +108,12 @@ func testInitRepo(t *testing.T, rootType data.KeyAlgorithm) {
 	_, err = os.Stat(filepath.Join(tempBaseDir, "private", "root_keys", rootKeyFilename))
 	assert.NoError(t, err, "missing root key")
 
-	// Also expect a symlink from the key ID of the certificate key to this
-	// root key
 	certificates := repo.KeyStoreManager.TrustedCertificateStore().GetCertificates()
 	assert.Len(t, certificates, 1, "unexpected number of certificates")
 
 	certID, err := trustmanager.FingerprintCert(certificates[0])
 	assert.NoError(t, err, "unable to fingerprint the certificate")
 
-	actualDest, err := os.Readlink(filepath.Join(tempBaseDir, "private", "root_keys", certID+"_root"+".key"))
-	assert.NoError(t, err, "missing symlink to root key")
-
-	assert.Equal(t, rootKeyFilename, actualDest, "symlink to root key has wrong destination")
-
 	// There should be a trusted certificate
 	_, err = os.Stat(filepath.Join(tempBaseDir, "trusted_certificates", filepath.FromSlash(gun), certID+".crt"))
 	assert.NoError(t, err, "missing trusted certificate")
diff --git a/keystoremanager/import_export_test.go b/keystoremanager/import_export_test.go
index 1e4a0625..71a85cce 100644
--- a/keystoremanager/import_export_test.go
+++ b/keystoremanager/import_export_test.go
@@ -100,10 +100,6 @@ func TestImportExportZip(t *testing.T) {
 	// Iterate through the files in the archive, checking that the files
 	// exist and are encrypted with the expected passphrase.
 	for _, f := range zipReader.File {
-		if keystoremanager.IsZipSymlink(f) {
-			continue
-		}
-
 		expectedPassphrase, present := passphraseByFile[f.Name]
 		if !present {
 			t.Fatalf("unexpected file %s in zip file", f.Name)
@@ -175,35 +171,6 @@ func TestImportExportZip(t *testing.T) {
 	rootKeyFilename := rootCryptoService.ID() + "_root.key"
 	_, err = os.Stat(filepath.Join(tempBaseDir2, "private", "root_keys", rootKeyFilename))
 	assert.NoError(t, err, "missing root key")
-
-	// Look for symlinks in the new repo matching symlinks in the old repo
-	numSymlinks := 0
-
-	oldRootKeyStore := repo.KeyStoreManager.RootKeyStore()
-	newRootKeyStore := repo2.KeyStoreManager.RootKeyStore()
-
-	for _, relKeyPath := range oldRootKeyStore.ListFiles(true) {
-		fullKeyPath := filepath.Join(oldRootKeyStore.BaseDir(), relKeyPath)
-
-		fi, err := os.Lstat(fullKeyPath)
-		assert.NoError(t, err, "lstat failed")
-
-		if (fi.Mode() & os.ModeSymlink) != 0 {
-			numSymlinks++
-
-			oldTarget, err := os.Readlink(fullKeyPath)
-			assert.NoError(t, err, "readlink failed on old repo")
-
-			newTarget, err := os.Readlink(filepath.Join(newRootKeyStore.BaseDir(), relKeyPath))
-			assert.NoError(t, err, "symlink not found in new repo")
-
-			assert.Equal(t, oldTarget, newTarget, "symlink targets do not match")
-		}
-	}
-
-	if numSymlinks == 0 {
-		t.Fatal("no symlinks found in original repo")
-	}
 }
 
 func TestImportExportGUN(t *testing.T) {
diff --git a/keystoremanager/keystoremanager_test.go b/keystoremanager/keystoremanager_test.go
index 8dd3f236..ce4f1111 100644
--- a/keystoremanager/keystoremanager_test.go
+++ b/keystoremanager/keystoremanager_test.go
@@ -264,13 +264,6 @@ func testValidateSuccessfulRootRotation(t *testing.T, keyAlg data.KeyAlgorithm,
 	origRootKey := data.NewPublicKey(rootKeyType, origRootPEMCert)
 	replRootKey := data.NewPublicKey(rootKeyType, replRootPEMCert)
 
-	// Link both certificates to the original public keys
-	err = keyStoreManager.RootKeyStore().Link(origRootKeyID+"_root", origRootKey.ID()+"_root")
-	assert.NoError(t, err)
-
-	err = keyStoreManager.RootKeyStore().Link(replRootKeyID+"_root", replRootKey.ID()+"_root")
-	assert.NoError(t, err)
-
 	rootRole, err := data.NewRole("root", 1, []string{replRootKey.ID()}, nil, nil)
 	assert.NoError(t, err)
 
@@ -350,20 +343,11 @@ func testValidateRootRotationMissingOrigSig(t *testing.T, keyAlg data.KeyAlgorit
 	replRootCert, err := replUnlockedCryptoService.GenerateCertificate(gun)
 	assert.NoError(t, err)
 	// We need the PEM representation of the replacement key to put it into the TUF data
-	origRootPEMCert := trustmanager.CertToPEM(origRootCert)
 	replRootPEMCert := trustmanager.CertToPEM(replRootCert)
 
 	// Tuf key with PEM-encoded x509 certificate
-	origRootKey := data.NewPublicKey(rootKeyType, origRootPEMCert)
 	replRootKey := data.NewPublicKey(rootKeyType, replRootPEMCert)
 
-	// Link both certificates to the original public keys
-	err = keyStoreManager.RootKeyStore().Link(origRootKeyID+"_root", origRootKey.ID()+"_root")
-	assert.NoError(t, err)
-
-	err = keyStoreManager.RootKeyStore().Link(replRootKeyID+"_root", replRootKey.ID()+"_root")
-	assert.NoError(t, err)
-
 	rootRole, err := data.NewRole("root", 1, []string{replRootKey.ID()}, nil, nil)
 	assert.NoError(t, err)
 
@@ -449,13 +433,6 @@ func testValidateRootRotationMissingNewSig(t *testing.T, keyAlg data.KeyAlgorith
 	origRootKey := data.NewPublicKey(rootKeyType, origRootPEMCert)
 	replRootKey := data.NewPublicKey(rootKeyType, replRootPEMCert)
 
-	// Link both certificates to the original public keys
-	err = keyStoreManager.RootKeyStore().Link(origRootKeyID+"_root", origRootKey.ID()+"_root")
-	assert.NoError(t, err)
-
-	err = keyStoreManager.RootKeyStore().Link(replRootKeyID+"_root", replRootKey.ID()+"_root")
-	assert.NoError(t, err)
-
 	rootRole, err := data.NewRole("root", 1, []string{replRootKey.ID()}, nil, nil)
 	assert.NoError(t, err)
 
diff --git a/signer/signer_trust_test.go b/signer/signer_trust_test.go
index bcbba05b..4b5ccef4 100644
--- a/signer/signer_trust_test.go
+++ b/signer/signer_trust_test.go
@@ -40,7 +40,7 @@ func stubHealthFunction(t *testing.T, status map[string]string, err error) rpcHe
 		_, withDeadline := ctx.Deadline()
 		assert.True(t, withDeadline)
 
-		return &pb.HealthStatus{status}, err
+		return &pb.HealthStatus{Status: status}, err
 	}
 }
 
diff --git a/trustmanager/filestore_test.go b/trustmanager/filestore_test.go
index 797fc342..0b64d7d8 100644
--- a/trustmanager/filestore_test.go
+++ b/trustmanager/filestore_test.go
@@ -154,12 +154,6 @@ func TestListFiles(t *testing.T) {
 		if err != nil {
 			t.Fatalf("failed to generate random file: %v", err)
 		}
-
-		// Create symlinks for all the files
-		err = os.Symlink(expectedFilename, filepath.Join(tempBaseDir, expectedFilename+".link."+testExt))
-		if err != nil {
-			t.Fatalf("failed to create symlink: %v", err)
-		}
 	}
 
 	// Create our SimpleFileStore
@@ -169,17 +163,11 @@ func TestListFiles(t *testing.T) {
 		perms:   perms,
 	}
 
-	// Call the List function. Expect 10 real files when not listing symlinks
-	files := store.ListFiles(false)
+	// Call the List function. Expect 10 files
+	files := store.ListFiles()
 	if len(files) != 10 {
 		t.Fatalf("expected 10 files in listing, got: %d", len(files))
 	}
-
-	// Call the List function. Expect 20 total files when listing symlinks
-	files = store.ListFiles(true)
-	if len(files) != 20 {
-		t.Fatalf("expected 20 files in listing, got: %d", len(files))
-	}
 }
 
 func TestListDir(t *testing.T) {
@@ -214,65 +202,20 @@ func TestListDir(t *testing.T) {
 	}
 
 	// Call the ListDir function
-	files := store.ListDir("docker.com/", true)
+	files := store.ListDir("docker.com/")
 	if len(files) != 10 {
 		t.Fatalf("expected 10 files in listing, got: %d", len(files))
 	}
-	files = store.ListDir("docker.com/notary", true)
+	files = store.ListDir("docker.com/notary")
 	if len(files) != 10 {
 		t.Fatalf("expected 10 files in listing, got: %d", len(files))
 	}
-	files = store.ListDir("fakedocker.com/", true)
+	files = store.ListDir("fakedocker.com/")
 	if len(files) != 0 {
 		t.Fatalf("expected 0 files in listing, got: %d", len(files))
 	}
 }
 
-func TestLink(t *testing.T) {
-	testName := "docker.com/notary/certificate"
-	testSymlink := "docker.com/notary/certificate-symlink"
-	testExt := "crt"
-	perms := os.FileMode(0755)
-
-	// Temporary directory where test files will be created
-	tempBaseDir, err := ioutil.TempDir("", "notary-test-")
-	if err != nil {
-		t.Fatalf("failed to create a temporary directory: %v", err)
-	}
-	defer os.RemoveAll(tempBaseDir)
-
-	// Since we're generating this manually we need to add the extension '.'
-	expectedFilePath := filepath.Join(tempBaseDir, testName+"."+testExt)
-	expectedSymlinkPath := filepath.Join(tempBaseDir, testSymlink+"."+testExt)
-
-	_, err = generateRandomFile(expectedFilePath, perms)
-	if err != nil {
-		t.Fatalf("failed to generate random file: %v", err)
-	}
-
-	// Create our SimpleFileStore
-	store := &SimpleFileStore{
-		baseDir: tempBaseDir,
-		fileExt: testExt,
-		perms:   perms,
-	}
-
-	// Call the Link function
-	err = store.Link("certificate", testSymlink)
-	if err != nil {
-		t.Fatalf("failed to create symlink: %v", err)
-	}
-
-	// Check to see if the symlink exists
-	actualSymlinkDest, err := os.Readlink(expectedSymlinkPath)
-	if err != nil {
-		t.Fatalf("expected to find symlink at path: %s", expectedSymlinkPath)
-	}
-	if actualSymlinkDest != "certificate."+testExt {
-		t.Fatalf("symlink has wrong destination: %s", actualSymlinkDest)
-	}
-}
-
 func TestGetPath(t *testing.T) {
 	testExt := "crt"
 	perms := os.FileMode(0755)