list shows where the key is stored

Signed-off-by: David Lawrence <david.lawrence@docker.com> (github: endophage)
This commit is contained in:
David Lawrence
2015-11-10 12:55:18 -08:00
parent 7f341a1e20
commit 6acc130e17
7 changed files with 105 additions and 65 deletions

View File

@@ -7,7 +7,11 @@ import (
"sort"
"strings"
"github.com/docker/notary"
notaryclient "github.com/docker/notary/client"
"github.com/docker/notary/cryptoservice"
"github.com/docker/notary/passphrase"
"github.com/docker/notary/trustmanager"
"github.com/docker/notary/tuf/data"
"github.com/spf13/cobra"
@@ -93,16 +97,20 @@ func keysList(cmd *cobra.Command, args []string) {
parseConfig()
cs := getCryptoService(cmd, trustDir, retriever, true)
stores := getKeyStores(cmd, trustDir, retriever, true)
// Get a map of all the keys/roles
keysMap := cs.ListAllKeys()
keys := make(map[trustmanager.KeyStore]map[string]string)
for _, store := range stores {
keys[store] = store.ListKeys()
}
cmd.Println("")
cmd.Println("# Root keys: ")
for k, v := range keysMap {
if v == "root" {
cmd.Println(k)
for store, keysMap := range keys {
for k, v := range keysMap {
if v == "root" {
cmd.Println(k, " - ", store.Name())
}
}
}
@@ -110,17 +118,20 @@ func keysList(cmd *cobra.Command, args []string) {
cmd.Println("# Signing keys: ")
// Get a list of all the keys
var sortedKeys []string
for k := range keysMap {
sortedKeys = append(sortedKeys, k)
}
// Sort the list of all the keys
sort.Strings(sortedKeys)
for store, keysMap := range keys {
var sortedKeys []string
for k := range keysMap {
sortedKeys = append(sortedKeys, k)
}
// Print a sorted list of the key/role
for _, k := range sortedKeys {
if keysMap[k] != "root" {
printKey(cmd, k, keysMap[k])
// Sort the list of all the keys
sort.Strings(sortedKeys)
// Print a sorted list of the key/role
for _, k := range sortedKeys {
if keysMap[k] != "root" {
printKey(cmd, k, keysMap[k], store.Name())
}
}
}
}
@@ -143,7 +154,10 @@ func keysGenerateRootKey(cmd *cobra.Command, args []string) {
parseConfig()
cs := getCryptoService(cmd, trustDir, retriever, true)
cs := cryptoservice.NewCryptoService(
"",
getKeyStores(cmd, trustDir, retriever, true)...,
)
pubKey, err := cs.Create(data.CanonicalRootRole, algorithm)
if err != nil {
@@ -164,7 +178,10 @@ func keysExport(cmd *cobra.Command, args []string) {
parseConfig()
cs := getCryptoService(cmd, trustDir, retriever, false)
cs := cryptoservice.NewCryptoService(
"",
getKeyStores(cmd, trustDir, retriever, true)...,
)
exportFile, err := os.Create(exportFilename)
if err != nil {
@@ -204,7 +221,10 @@ func keysExportRoot(cmd *cobra.Command, args []string) {
parseConfig()
cs := getCryptoService(cmd, trustDir, retriever, false)
cs := cryptoservice.NewCryptoService(
"",
getKeyStores(cmd, trustDir, retriever, true)...,
)
exportFile, err := os.Create(exportFilename)
if err != nil {
@@ -236,7 +256,10 @@ func keysImport(cmd *cobra.Command, args []string) {
parseConfig()
cs := getCryptoService(cmd, trustDir, retriever, false)
cs := cryptoservice.NewCryptoService(
"",
getKeyStores(cmd, trustDir, retriever, true)...,
)
zipReader, err := zip.OpenReader(importFilename)
if err != nil {
@@ -262,7 +285,10 @@ func keysImportRoot(cmd *cobra.Command, args []string) {
parseConfig()
cs := getCryptoService(cmd, trustDir, retriever, true)
cs := cryptoservice.NewCryptoService(
"",
getKeyStores(cmd, trustDir, retriever, true)...,
)
importFile, err := os.Open(importFilename)
if err != nil {
@@ -277,10 +303,10 @@ func keysImportRoot(cmd *cobra.Command, args []string) {
}
}
func printKey(cmd *cobra.Command, keyPath, alias string) {
func printKey(cmd *cobra.Command, keyPath, alias, loc string) {
keyID := filepath.Base(keyPath)
gun := filepath.Dir(keyPath)
cmd.Printf("%s - %s - %s\n", gun, alias, keyID)
cmd.Printf("%s - %s - %s - %s\n", gun, alias, keyID, loc)
}
func keysRotate(cmd *cobra.Command, args []string) {
@@ -299,3 +325,28 @@ func keysRotate(cmd *cobra.Command, args []string) {
fatalf(err.Error())
}
}
func getKeyStores(cmd *cobra.Command, directory string,
ret passphrase.Retriever, withHardware bool) []trustmanager.KeyStore {
keysPath := filepath.Join(directory, notary.PrivDir)
fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, ret)
if err != nil {
fatalf("Failed to create private key store in directory: %s", keysPath)
}
ks := []trustmanager.KeyStore{fileKeyStore}
if withHardware {
yubiStore, err := getYubiKeyStore(fileKeyStore, ret)
if err != nil {
cmd.Println("No YubiKey detected - using local filesystem only.")
} else {
// Note that the order is important, since we want to prioritize
// the yubikey store
ks = []trustmanager.KeyStore{yubiStore, fileKeyStore}
}
}
return ks
}

View File

@@ -3,22 +3,10 @@
package main
import (
"path/filepath"
"github.com/docker/notary"
"github.com/docker/notary/cryptoservice"
"github.com/docker/notary/passphrase"
"github.com/docker/notary/trustmanager"
"github.com/spf13/cobra"
)
func getCryptoService(cmd *cobra.Command, directory string,
ret passphrase.Retriever, _ bool) *cryptoservice.CryptoService {
keysPath := filepath.Join(directory, notary.PrivDir)
fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, ret)
if err != nil {
fatalf("Failed to create private key store in directory: %s", keysPath)
}
return cryptoservice.NewCryptoService("", fileKeyStore)
func getYubiKeyStore(fileKeyStore trustmanager.KeyStore, ret passphrase.Retriever) (trustmanager.KeyStore, error) {
return nil, errors.New("Not built with hardware support")
}

View File

@@ -3,38 +3,14 @@
package main
import (
"path/filepath"
"github.com/docker/notary"
"github.com/docker/notary/cryptoservice"
"github.com/docker/notary/passphrase"
"github.com/docker/notary/trustmanager"
"github.com/spf13/cobra"
)
// Build a CryptoService, optionally including a hardware keystore. Returns
// the CryptoService and whether or not a hardware keystore was included.
func getCryptoService(cmd *cobra.Command, directory string,
ret passphrase.Retriever, withHardware bool) *cryptoservice.CryptoService {
keysPath := filepath.Join(directory, notary.PrivDir)
fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, ret)
func getYubiKeyStore(fileKeyStore trustmanager.KeyStore, ret passphrase.Retriever) (trustmanager.KeyStore, error) {
yubiStore, err := trustmanager.NewYubiKeyStore(fileKeyStore, ret)
if err != nil {
fatalf("Failed to create private key store in directory: %s", keysPath)
return nil, err
}
ks := []trustmanager.KeyStore{fileKeyStore}
if withHardware {
yubiStore, err := trustmanager.NewYubiKeyStore(fileKeyStore, ret)
if err != nil {
cmd.Println("No YubiKey detected - using local filesystem only.")
} else {
// Note that the order is important, since we want to prioritize
// the yubikey store
ks = []trustmanager.KeyStore{yubiStore, fileKeyStore}
}
}
return cryptoservice.NewCryptoService("", ks...)
return yubiStore, nil
}

View File

@@ -58,6 +58,11 @@ func NewKeyDBStore(passphraseRetriever passphrase.Retriever, defaultPassAlias, d
cachedKeys: cachedKeys}, nil
}
// Name returns a user friendly name for the storage location
func (s KeyDBStore) Name() string {
return "database"
}
// AddKey stores the contents of a private key. Both name and alias are ignored,
// we always use Key IDs as name, and don't support aliases
func (s *KeyDBStore) AddKey(name, alias string, privKey data.PrivateKey) error {

View File

@@ -1,6 +1,7 @@
package trustmanager
import (
"fmt"
"path/filepath"
"strings"
"sync"
@@ -44,6 +45,12 @@ func NewKeyFileStore(baseDir string, passphraseRetriever passphrase.Retriever) (
cachedKeys: cachedKeys}, nil
}
// Name returns a user friendly name for the location this store
// keeps its data
func (s KeyFileStore) Name() string {
return fmt.Sprintf("file (%s)", s.SimpleFileStore.BaseDir())
}
// AddKey stores the contents of a PEM-encoded private key as a PEM block
func (s *KeyFileStore) AddKey(name, alias string, privKey data.PrivateKey) error {
s.Lock()
@@ -96,6 +103,12 @@ func NewKeyMemoryStore(passphraseRetriever passphrase.Retriever) *KeyMemoryStore
cachedKeys: cachedKeys}
}
// Name returns a user friendly name for the location this store
// keeps its data
func (s KeyMemoryStore) Name() string {
return "memory"
}
// AddKey stores the contents of a PEM-encoded private key as a PEM block
func (s *KeyMemoryStore) AddKey(name, alias string, privKey data.PrivateKey) error {
s.Lock()

View File

@@ -46,6 +46,7 @@ type KeyStore interface {
RemoveKey(name string) error
ExportKey(name string) ([]byte, error)
ImportKey(pemBytes []byte, alias string) error
Name() string
}
type cachedKey struct {

View File

@@ -580,6 +580,12 @@ func NewYubiKeyStore(backupStore KeyStore, passphraseRetriever passphrase.Retrie
return s, nil
}
// Name returns a user friendly name for the location this store
// keeps its data
func (s YubiKeyStore) Name() string {
return "yubikey"
}
func (s *YubiKeyStore) ListKeys() map[string]string {
if len(s.keys) > 0 {
return buildKeyMap(s.keys)