Add ExportRootKey and ImportRootKey functions

Also add a unit test

Signed-off-by: Aaron Lehmann <aaron.lehmann@docker.com>
This commit is contained in:
Aaron Lehmann 2015-07-15 13:34:32 -07:00
parent 20633e3e12
commit 479333ca7b
2 changed files with 98 additions and 1 deletions

View File

@ -16,6 +16,36 @@ import (
"github.com/endophage/gotuf/data"
)
// ExportRootKey exports the specified root key to an io.Writer in PEM format.
// The key's existing encryption is preserved.
func (km *KeyStoreManager) ExportRootKey(dest io.Writer, keyID string) error {
pemBytes, err := km.rootKeyStore.Get(keyID)
if err != nil {
return err
}
_, err = dest.Write(pemBytes)
return err
}
// ImportRootKey imports a root in PEM format key from an io.Reader
// The key's existing encryption is preserved. The keyID parameter is
// necessary because otherwise we'd need the passphrase to decrypt the key
// in order to compute the ID.
func (km *KeyStoreManager) ImportRootKey(source io.Reader, keyID string) error {
pemBytes, err := ioutil.ReadAll(source)
if err != nil {
return err
}
err = km.rootKeyStore.Add(keyID, pemBytes)
if err != nil {
return err
}
return err
}
func moveKeysWithNewPassphrase(oldKeyStore, newKeyStore *trustmanager.KeyFileStore, outputPassphrase string) error {
// List all files but no symlinks
for _, f := range oldKeyStore.ListFiles(false) {

View File

@ -69,7 +69,7 @@ func TestImportExportZip(t *testing.T) {
tempZipFile.Close()
assert.NoError(t, err)
// Check the contents of the zip file
// Reopen the zip file for importing
zipReader, err := zip.OpenReader(tempZipFilePath)
assert.NoError(t, err, "could not open zip file")
@ -173,3 +173,70 @@ func TestImportExportZip(t *testing.T) {
_, err = os.Stat(filepath.Join(tempBaseDir2, "private", "root_keys", rootKeyFilename))
assert.NoError(t, err, "missing root key")
}
func TestImportExportRootKey(t *testing.T) {
gun := "docker.com/notary"
oldPassphrase := "oldPassphrase"
// 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)
ts, _ := createTestServer(t)
defer ts.Close()
repo, err := client.NewNotaryRepository(tempBaseDir, gun, ts.URL, http.DefaultTransport)
assert.NoError(t, err, "error creating repo: %s", err)
rootKeyID, err := repo.KeyStoreManager.GenRootKey(data.ECDSAKey.String(), oldPassphrase)
assert.NoError(t, err, "error generating root key: %s", err)
rootCryptoService, err := repo.KeyStoreManager.GetRootCryptoService(rootKeyID, oldPassphrase)
assert.NoError(t, err, "error retrieving root key: %s", err)
err = repo.Initialize(rootCryptoService)
assert.NoError(t, err, "error creating repository: %s", err)
tempKeyFile, err := ioutil.TempFile("", "notary-test-export-")
tempKeyFilePath := tempKeyFile.Name()
defer os.Remove(tempKeyFilePath)
err = repo.KeyStoreManager.ExportRootKey(tempKeyFile, rootKeyID)
assert.NoError(t, err)
tempKeyFile.Close()
// Create new repo to test import
tempBaseDir2, err := ioutil.TempDir("", "notary-test-")
defer os.RemoveAll(tempBaseDir2)
assert.NoError(t, err, "failed to create a temporary directory: %s", err)
repo2, err := client.NewNotaryRepository(tempBaseDir2, gun, ts.URL, http.DefaultTransport)
assert.NoError(t, err, "error creating repo: %s", err)
rootKeyID2, err := repo2.KeyStoreManager.GenRootKey(data.ECDSAKey.String(), "oldPassphrase")
assert.NoError(t, err, "error generating root key: %s", err)
rootCryptoService2, err := repo2.KeyStoreManager.GetRootCryptoService(rootKeyID2, "oldPassphrase")
assert.NoError(t, err, "error retrieving root key: %s", err)
err = repo2.Initialize(rootCryptoService2)
assert.NoError(t, err, "error creating repository: %s", err)
// Check the contents of the zip file
keyReader, err := os.Open(tempKeyFilePath)
assert.NoError(t, err, "could not open key file")
err = repo2.KeyStoreManager.ImportRootKey(keyReader, rootKeyID)
assert.NoError(t, err)
keyReader.Close()
// Look for repo's root key in repo2
// There should be a file named after the key ID of the root key we
// imported.
rootKeyFilename := rootKeyID + ".key"
_, err = os.Stat(filepath.Join(tempBaseDir2, "private", "root_keys", rootKeyFilename))
assert.NoError(t, err, "missing root key")
}