diff --git a/client/repo_pkcs11.go b/client/repo_pkcs11.go index 763144ea1e..260aaca742 100644 --- a/client/repo_pkcs11.go +++ b/client/repo_pkcs11.go @@ -24,14 +24,13 @@ func NewNotaryRepository(baseDir, gun, baseURL string, rt http.RoundTripper, retriever passphrase.Retriever) (*NotaryRepository, error) { keysPath := filepath.Join(baseDir, notary.PrivDir) - backupPath := filepath.Join(baseDir, notary.BackupDir) fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) if err != nil { return nil, fmt.Errorf("failed to create private key store in directory: %s", keysPath) } keyStoreManager, err := keystoremanager.NewKeyStoreManager(baseDir, fileKeyStore) - yubiKeyStore, _ := api.NewYubiKeyStore(backupPath, retriever) + yubiKeyStore, _ := api.NewYubiKeyStore(fileKeyStore, retriever) var cryptoService signed.CryptoService if yubiKeyStore == nil { cryptoService = cryptoservice.NewCryptoService(gun, keyStoreManager.KeyStore) diff --git a/cmd/notary/keys.go b/cmd/notary/keys.go index 4793a25600..7a9c82bbfe 100644 --- a/cmd/notary/keys.go +++ b/cmd/notary/keys.go @@ -22,10 +22,6 @@ import ( func init() { cmdKey.AddCommand(cmdKeyList) - cmdKey.AddCommand(cmdKeyRemoveKey) - cmdKeyRemoveKey.Flags().StringVarP(&keyRemoveGUN, "gun", "g", "", "Globally unique name to remove keys for") - cmdKeyRemoveKey.Flags().BoolVarP(&keyRemoveRoot, "root", "r", false, "Remove root keys") - cmdKeyRemoveKey.Flags().BoolVarP(&keyRemoveYes, "yes", "y", false, "Answer yes to the removal question (no confirmation)") cmdKey.AddCommand(cmdKeyGenerateRootKey) cmdKeyExport.Flags().StringVarP(&keysExportGUN, "gun", "g", "", "Globally unique name to export keys for") @@ -57,17 +53,6 @@ var cmdRotateKey = &cobra.Command{ Run: keysRotate, } -var keyRemoveGUN string -var keyRemoveRoot bool -var keyRemoveYes bool - -var cmdKeyRemoveKey = &cobra.Command{ - Use: "remove [ keyID ]", - Short: "Removes the key with the given keyID.", - Long: "remove the key with the given keyID from the local host.", - Run: keysRemoveKey, -} - var cmdKeyGenerateRootKey = &cobra.Command{ Use: "generate [ algorithm ]", Short: "Generates a new root key with a given algorithm.", @@ -107,67 +92,6 @@ var cmdKeyImportRoot = &cobra.Command{ Run: keysImportRoot, } -// keysRemoveKey deletes a private key based on ID -func keysRemoveKey(cmd *cobra.Command, args []string) { - if len(args) < 1 { - cmd.Usage() - fatalf("must specify the key ID of the key to remove") - } - - parseConfig() - - keysPath := filepath.Join(trustDir, notary.PrivDir) - backupPath := filepath.Join(trustDir, notary.BackupDir) - fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) - if err != nil { - fatalf("failed to create private key store in directory: %s", keysPath) - } - yubiStore, _ := api.NewYubiKeyStore(backupPath, retriever) - var cs signed.CryptoService - if yubiStore == nil { - cs = cryptoservice.NewCryptoService("", fileKeyStore) - } else { - cs = cryptoservice.NewCryptoService("", yubiStore, fileKeyStore) - } - - keyID := args[0] - - // This is an invalid ID - if len(keyID) != idSize { - fatalf("invalid key ID provided: %s", keyID) - } - - keyMap := cs.ListAllKeys() - var key string - for k := range keyMap { - if filepath.Base(k) == keyID { - key = k - } - } - - if key == "" { - fatalf("key with key ID: %s not found\n", keyID) - } - - // List the key about to be removed - fmt.Println("Are you sure you want to remove the following key?") - fmt.Printf("%s\n(yes/no)\n", keyID) - - // Ask for confirmation before removing the key, unless -y is passed - if !keyRemoveYes { - confirmed := askConfirm() - if !confirmed { - fatalf("aborting action.") - } - } - - // Attempt to remove the key - err = cs.RemoveKey(key) - if err != nil { - fatalf("failed to remove key with key ID: %s, %v", keyID, err) - } -} - func keysList(cmd *cobra.Command, args []string) { if len(args) > 0 { cmd.Usage() @@ -177,12 +101,11 @@ func keysList(cmd *cobra.Command, args []string) { parseConfig() keysPath := filepath.Join(trustDir, notary.PrivDir) - backupPath := filepath.Join(trustDir, notary.BackupDir) fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) if err != nil { fatalf("failed to create private key store in directory: %s", keysPath) } - yubiStore, _ := api.NewYubiKeyStore(backupPath, retriever) + yubiStore, _ := api.NewYubiKeyStore(fileKeyStore, retriever) var cs signed.CryptoService if yubiStore == nil { cs = cryptoservice.NewCryptoService("", fileKeyStore) @@ -239,12 +162,11 @@ func keysGenerateRootKey(cmd *cobra.Command, args []string) { parseConfig() keysPath := filepath.Join(trustDir, notary.PrivDir) - backupPath := filepath.Join(trustDir, notary.BackupDir) fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) if err != nil { fatalf("failed to create private key store in directory: %s", keysPath) } - yubiStore, err := api.NewYubiKeyStore(backupPath, retriever) + yubiStore, err := api.NewYubiKeyStore(fileKeyStore, retriever) var cs signed.CryptoService if err != nil { cmd.Printf("No Yubikey detected, importing to local filesystem.") @@ -386,12 +308,11 @@ func keysImportRoot(cmd *cobra.Command, args []string) { parseConfig() keysPath := filepath.Join(trustDir, notary.PrivDir) - backupPath := filepath.Join(trustDir, notary.BackupDir) fileKeyStore, err := trustmanager.NewKeyFileStore(keysPath, retriever) if err != nil { fatalf("failed to create private key store in directory: %s", keysPath) } - yubiStore, err := api.NewYubiKeyStore(backupPath, retriever) + yubiStore, err := api.NewYubiKeyStore(fileKeyStore, retriever) var cs signed.CryptoService if err != nil { cmd.Printf("No Yubikey detected, importing to local filesystem.") diff --git a/signer/api/ecdsa_hardware_crypto_service.go b/signer/api/ecdsa_hardware_crypto_service.go index cbb7e38ba2..a3acc2f0a8 100644 --- a/signer/api/ecdsa_hardware_crypto_service.go +++ b/signer/api/ecdsa_hardware_crypto_service.go @@ -12,13 +12,9 @@ import ( "errors" "fmt" "io" - "io/ioutil" "math/big" - "os" - "path" "github.com/Sirupsen/logrus" - "github.com/docker/notary" "github.com/docker/notary/passphrase" "github.com/docker/notary/trustmanager" "github.com/docker/notary/tuf/data" @@ -35,11 +31,11 @@ const ( var YUBIKEY_ROOT_KEY_ID = []byte{2} type ErrBackupFailed struct { - path string + err string } func (err ErrBackupFailed) Error() string { - return fmt.Sprintf("Failed to backup private key to: %s", err.path) + return fmt.Sprintf("Failed to backup private key to: %s", err.err) } type yubiSlot struct { @@ -108,7 +104,15 @@ func (y *YubiPrivateKey) Sign(rand io.Reader, msg []byte, opts crypto.SignerOpts } // addECDSAKey adds a key to the yubikey -func addECDSAKey(ctx *pkcs11.Ctx, session pkcs11.SessionHandle, privKey data.PrivateKey, pkcs11KeyID []byte, passRetriever passphrase.Retriever, role, backupPath string) error { +func addECDSAKey( + ctx *pkcs11.Ctx, + session pkcs11.SessionHandle, + privKey data.PrivateKey, + pkcs11KeyID []byte, + passRetriever passphrase.Retriever, + role string, + backupStore trustmanager.KeyStore, +) error { logrus.Debugf("Got into add key with key: %s\n", privKey.ID()) // TODO(diogo): Figure out CKU_SO with yubikey @@ -165,14 +169,9 @@ func addECDSAKey(ctx *pkcs11.Ctx, session pkcs11.SessionHandle, privKey data.Pri return fmt.Errorf("error importing: %v", err) } - backupTo := path.Join(backupPath, privKey.ID()) - err = ioutil.WriteFile( - backupTo, - privKey.Private(), - notary.PrivKeyPerms, - ) + err = backupStore.AddKey(privKey.ID(), role, privKey) if err != nil { - return ErrBackupFailed{path: backupTo} + return ErrBackupFailed{err: err.Error()} } return nil @@ -484,21 +483,17 @@ func getNextEmptySlot(ctx *pkcs11.Ctx, session pkcs11.SessionHandle) ([]byte, er type YubiKeyStore struct { passRetriever passphrase.Retriever keys map[string]yubiSlot - backupPath string + backupStore trustmanager.KeyStore } -func NewYubiKeyStore(backupPath string, passphraseRetriever passphrase.Retriever) (*YubiKeyStore, error) { - err := os.MkdirAll(backupPath, notary.PrivKeyPerms) - if err != nil { - return nil, err - } +func NewYubiKeyStore(backupStore trustmanager.KeyStore, passphraseRetriever passphrase.Retriever) (*YubiKeyStore, error) { s := &YubiKeyStore{ passRetriever: passphraseRetriever, keys: make(map[string]yubiSlot), - backupPath: backupPath, + backupStore: backupStore, } s.ListKeys() // populate keys field - return s, err + return s, nil } func (s *YubiKeyStore) ListKeys() map[string]string { @@ -542,7 +537,7 @@ func (s *YubiKeyStore) AddKey(keyID, role string, privKey data.PrivateKey) error return err } logrus.Debugf("Using yubikey slot %v", slot) - err = addECDSAKey(ctx, session, privKey, slot, s.passRetriever, role, s.backupPath) + err = addECDSAKey(ctx, session, privKey, slot, s.passRetriever, role, s.backupStore) if err == nil { s.keys[privKey.ID()] = yubiSlot{ role: role,