diff --git a/client/client_test.go b/client/client_test.go index 18cbe02615..5df2cd1034 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -75,7 +75,7 @@ func testInitRepo(t *testing.T, rootType data.KeyAlgorithm) { // Inspect contents of the temporary directory expectedDirs := []string{ "private", - filepath.Join("private", gun), + filepath.Join("private", "tuf_keys", gun), filepath.Join("private", "root_keys"), "trusted_certificates", filepath.Join("trusted_certificates", gun), diff --git a/keystoremanager/import_export.go b/keystoremanager/import_export.go index 8dc2ee420b..c17452c984 100644 --- a/keystoremanager/import_export.go +++ b/keystoremanager/import_export.go @@ -113,14 +113,9 @@ func moveKeysWithNewPassphrase(oldKeyStore, newKeyStore *trustmanager.KeyFileSto return nil } -func addKeysToArchive(zipWriter *zip.Writer, newKeyStore *trustmanager.KeyFileStore, tempBaseDir string, dedup map[string]struct{}) error { +func addKeysToArchive(zipWriter *zip.Writer, newKeyStore *trustmanager.KeyFileStore, tempBaseDir string) error { // List all files but no symlinks for _, fullKeyPath := range newKeyStore.ListFiles(false) { - if _, present := dedup[fullKeyPath]; present { - continue - } - dedup[fullKeyPath] = struct{}{} - relKeyPath := strings.TrimPrefix(fullKeyPath, tempBaseDir) relKeyPath = strings.TrimPrefix(relKeyPath, string(filepath.Separator)) @@ -162,7 +157,7 @@ func (km *KeyStoreManager) ExportAllKeys(dest io.Writer, outputPassphrase string defer os.RemoveAll(tempBaseDir) // Create temporary keystores to use as a staging area - tempNonRootKeysPath := filepath.Join(tempBaseDir, privDir) + tempNonRootKeysPath := filepath.Join(tempBaseDir, privDir, nonRootKeysSubdir) tempNonRootKeyStore, err := trustmanager.NewKeyFileStore(tempNonRootKeysPath) if err != nil { return err @@ -183,13 +178,10 @@ func (km *KeyStoreManager) ExportAllKeys(dest io.Writer, outputPassphrase string zipWriter := zip.NewWriter(dest) - // Root and non-root stores overlap, so we need to dedup files - dedup := make(map[string]struct{}) - - if err := addKeysToArchive(zipWriter, tempRootKeyStore, tempBaseDir, dedup); err != nil { + if err := addKeysToArchive(zipWriter, tempRootKeyStore, tempBaseDir); err != nil { return err } - if err := addKeysToArchive(zipWriter, tempNonRootKeyStore, tempBaseDir, dedup); err != nil { + if err := addKeysToArchive(zipWriter, tempNonRootKeyStore, tempBaseDir); err != nil { return err } @@ -208,23 +200,14 @@ func (km *KeyStoreManager) ImportKeysZip(zipReader zip.Reader, passphrase string newRootKeys := make(map[string][]byte) newNonRootKeys := make(map[string]*data.PrivateKey) + // Note that using / as a separator is okay here - the zip package + // guarantees that the separator will be / + rootKeysPrefix := privDir + "/" + rootKeysSubdir + "/" + nonRootKeysPrefix := privDir + "/" + nonRootKeysSubdir + "/" + // Iterate through the files in the archive. Don't add the keys for _, f := range zipReader.File { fNameTrimmed := strings.TrimSuffix(f.Name, filepath.Ext(f.Name)) - // Note that using / as a separator is okay here - the zip - // package guarantees that the separator will be / - keysPrefix := privDir + "/" - - if !strings.HasPrefix(fNameTrimmed, keysPrefix) { - // This path inside the zip archive doesn't start with - // "private". That's unexpected, because all keys - // should be in that subdirectory. To avoid adding a - // file to the filestore that we won't be able to use, - // skip this file in the import. - logrus.Warnf("skipping import of key with a path that doesn't begin with %s: %s", keysPrefix, f.Name) - continue - } - fNameTrimmed = strings.TrimPrefix(fNameTrimmed, keysPrefix) rc, err := f.Open() if err != nil { @@ -239,21 +222,31 @@ func (km *KeyStoreManager) ImportKeysZip(zipReader zip.Reader, passphrase string // Is this in the root_keys directory? // Note that using / as a separator is okay here - the zip // package guarantees that the separator will be / - rootKeysPrefix := rootKeysSubdir + "/" if strings.HasPrefix(fNameTrimmed, rootKeysPrefix) { if err = checkRootKeyIsEncrypted(pemBytes); err != nil { + rc.Close() return err } // Root keys are preserved without decrypting keyName := strings.TrimPrefix(fNameTrimmed, rootKeysPrefix) newRootKeys[keyName] = pemBytes - } else { + } else if strings.HasPrefix(fNameTrimmed, nonRootKeysPrefix) { // Non-root keys need to be decrypted key, err := trustmanager.ParsePEMPrivateKey(pemBytes, passphrase) if err != nil { + rc.Close() return err } - newNonRootKeys[fNameTrimmed] = key + keyName := strings.TrimPrefix(fNameTrimmed, nonRootKeysPrefix) + newNonRootKeys[keyName] = key + } else { + // This path inside the zip archive doesn't look like a + // root key or a non-root key. To avoid adding a file + // to the filestore that we won't be able to use, skip + // this file in the import. + logrus.Warnf("skipping import of key with a path that doesn't begin with %s or %s: %s", rootKeysPrefix, nonRootKeysPrefix, f.Name) + rc.Close() + continue } rc.Close() diff --git a/keystoremanager/keystoremanager.go b/keystoremanager/keystoremanager.go index d27be29d3c..cd607d6db1 100644 --- a/keystoremanager/keystoremanager.go +++ b/keystoremanager/keystoremanager.go @@ -29,16 +29,18 @@ type KeyStoreManager struct { } const ( - trustDir = "trusted_certificates" - privDir = "private" - rootKeysSubdir = "root_keys" - rsaRootKeySize = 4096 // Used for new root keys + trustDir = "trusted_certificates" + privDir = "private" + rootKeysSubdir = "root_keys" + nonRootKeysSubdir = "tuf_keys" + rsaRootKeySize = 4096 // Used for new root keys ) // NewKeyStoreManager returns an initialized KeyStoreManager, or an error // if it fails to create the KeyFileStores or load certificates func NewKeyStoreManager(baseDir string) (*KeyStoreManager, error) { - nonRootKeyStore, err := trustmanager.NewKeyFileStore(filepath.Join(baseDir, privDir)) + nonRootKeysPath := filepath.Join(baseDir, privDir, nonRootKeysSubdir) + nonRootKeyStore, err := trustmanager.NewKeyFileStore(nonRootKeysPath) if err != nil { return nil, err }