mirror of https://github.com/docker/docs.git
keystore aliasing, take 1
Signed-off-by: Nathan McCauley <nathan.mccauley@docker.com>
This commit is contained in:
parent
7530774101
commit
5df1eb21f3
|
@ -41,7 +41,7 @@ func init() {
|
|||
flag.BoolVar(&debug, "debug", false, "show the version and exit")
|
||||
}
|
||||
|
||||
func passphraseRetriever(keyName string, createNew bool, attempts int) (passphrase string, giveup bool, err error) {
|
||||
func passphraseRetriever(keyName, alias string, createNew bool, attempts int) (passphrase string, giveup bool, err error) {
|
||||
|
||||
//TODO(mccauley) Read from config once we have locked keys in notary-signer
|
||||
return "", false, nil;
|
||||
|
|
|
@ -89,7 +89,7 @@ func init() {
|
|||
|
||||
//TODO(mccauley): Appears unused? Remove it? Or is it here for early failure?
|
||||
privKeyStore, err = trustmanager.NewKeyFileStore(finalPrivDir,
|
||||
func (string, bool, int) (string, bool, error) { return "", false, nil})
|
||||
func (string, string, bool, int) (string, bool, error) { return "", false, nil})
|
||||
if err != nil {
|
||||
fatalf("could not create KeyFileStore: %v", err)
|
||||
}
|
||||
|
|
|
@ -16,11 +16,18 @@ import (
|
|||
notaryclient "github.com/docker/notary/client"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/docker/notary/trustmanager"
|
||||
)
|
||||
|
||||
// FIXME: This should not be hardcoded
|
||||
const hardcodedBaseURL = "https://notary-server:4443"
|
||||
|
||||
var retriever trustmanager.PassphraseRetriever
|
||||
|
||||
func init() {
|
||||
retriever = getNotaryPassphraseRetriever()
|
||||
}
|
||||
|
||||
var remoteTrustServer string
|
||||
|
||||
var cmdTufList = &cobra.Command{
|
||||
|
@ -83,7 +90,7 @@ func tufAdd(cmd *cobra.Command, args []string) {
|
|||
targetPath := args[2]
|
||||
|
||||
repo, err := notaryclient.NewNotaryRepository(viper.GetString("baseTrustDir"), gun, hardcodedBaseURL,
|
||||
getInsecureTransport(), passphraseRetriever)
|
||||
getInsecureTransport(), retriever)
|
||||
if err != nil {
|
||||
fatalf(err.Error())
|
||||
}
|
||||
|
@ -108,7 +115,7 @@ func tufInit(cmd *cobra.Command, args []string) {
|
|||
gun := args[0]
|
||||
|
||||
nRepo, err := notaryclient.NewNotaryRepository(viper.GetString("baseTrustDir"), gun, hardcodedBaseURL,
|
||||
getInsecureTransport(), passphraseRetriever)
|
||||
getInsecureTransport(), retriever)
|
||||
if err != nil {
|
||||
fatalf(err.Error())
|
||||
}
|
||||
|
@ -144,7 +151,7 @@ func tufList(cmd *cobra.Command, args []string) {
|
|||
}
|
||||
gun := args[0]
|
||||
repo, err := notaryclient.NewNotaryRepository(viper.GetString("baseTrustDir"), gun, hardcodedBaseURL,
|
||||
getInsecureTransport(), passphraseRetriever)
|
||||
getInsecureTransport(), retriever)
|
||||
if err != nil {
|
||||
fatalf(err.Error())
|
||||
}
|
||||
|
@ -170,7 +177,7 @@ func tufLookup(cmd *cobra.Command, args []string) {
|
|||
targetName := args[1]
|
||||
|
||||
repo, err := notaryclient.NewNotaryRepository(viper.GetString("baseTrustDir"), gun, hardcodedBaseURL,
|
||||
getInsecureTransport(), passphraseRetriever)
|
||||
getInsecureTransport(), retriever)
|
||||
if err != nil {
|
||||
fatalf(err.Error())
|
||||
}
|
||||
|
@ -195,12 +202,12 @@ func tufPublish(cmd *cobra.Command, args []string) {
|
|||
fmt.Println("Pushing changes to ", gun, ".")
|
||||
|
||||
repo, err := notaryclient.NewNotaryRepository(viper.GetString("baseTrustDir"), gun, hardcodedBaseURL,
|
||||
getInsecureTransport(), passphraseRetriever)
|
||||
getInsecureTransport(), retriever)
|
||||
if err != nil {
|
||||
fatalf(err.Error())
|
||||
}
|
||||
|
||||
err = repo.Publish(passphraseRetriever)
|
||||
err = repo.Publish(retriever)
|
||||
if err != nil {
|
||||
fatalf(err.Error())
|
||||
}
|
||||
|
@ -241,7 +248,7 @@ func verify(cmd *cobra.Command, args []string) {
|
|||
gun := args[0]
|
||||
targetName := args[1]
|
||||
repo, err := notaryclient.NewNotaryRepository(viper.GetString("baseTrustDir"), gun, hardcodedBaseURL,
|
||||
getInsecureTransport(), passphraseRetriever)
|
||||
getInsecureTransport(), retriever)
|
||||
if err != nil {
|
||||
fatalf(err.Error())
|
||||
}
|
||||
|
@ -265,9 +272,22 @@ func verify(cmd *cobra.Command, args []string) {
|
|||
return
|
||||
}
|
||||
|
||||
func passphraseRetriever(keyName string, createNew bool, numAttempts int) (string, bool, error) {
|
||||
fmt.Printf("Retrieving passphrase for key %s: ", keyName)
|
||||
func getNotaryPassphraseRetriever() (trustmanager.PassphraseRetriever) {
|
||||
userEnteredTargetsSnapshotsPass := false
|
||||
targetsSnapshotsPass := ""
|
||||
|
||||
return func(keyID string, alias string, createNew bool, numAttempts int) (string, bool, error) {
|
||||
fmt.Printf("userEnteredTargetsSnapshotsPass: %s\n", userEnteredTargetsSnapshotsPass)
|
||||
fmt.Printf("targetsSnapshotsPass: %s\n", targetsSnapshotsPass)
|
||||
fmt.Printf("keyID: %s\n", keyID)
|
||||
fmt.Printf("alias: %s\n", alias)
|
||||
fmt.Printf("numAttempts: %s\n", numAttempts)
|
||||
|
||||
if numAttempts == 0 && userEnteredTargetsSnapshotsPass && (alias == "snapshot" || alias == "targets") {
|
||||
fmt.Println("return cached value")
|
||||
|
||||
return targetsSnapshotsPass, false, nil;
|
||||
}
|
||||
if (numAttempts > 3 && !createNew) {
|
||||
return "", true, errors.New("Too many attempts")
|
||||
}
|
||||
|
@ -281,7 +301,12 @@ func passphraseRetriever(keyName string, createNew bool, numAttempts int) (strin
|
|||
|
||||
stdin := bufio.NewReader(os.Stdin)
|
||||
|
||||
fmt.Printf("Enter %s key passphrase: ", keyName)
|
||||
if createNew {
|
||||
fmt.Printf("Enter passphrase for new %s key with id %s: ", alias, keyID)
|
||||
}else {
|
||||
fmt.Printf("Enter key passphrase for %s key with id %s: ", alias, keyID)
|
||||
}
|
||||
|
||||
passphrase, err := stdin.ReadBytes('\n')
|
||||
fmt.Println()
|
||||
if err != nil {
|
||||
|
@ -290,6 +315,11 @@ func passphraseRetriever(keyName string, createNew bool, numAttempts int) (strin
|
|||
passphrase = passphrase[0 : len(passphrase)-1]
|
||||
|
||||
if !createNew {
|
||||
retPass := string(passphrase)
|
||||
if alias == "snapshot" || alias == "targets" {
|
||||
userEnteredTargetsSnapshotsPass = true
|
||||
targetsSnapshotsPass = retPass
|
||||
}
|
||||
return string(passphrase), false, nil;
|
||||
}
|
||||
|
||||
|
@ -298,7 +328,7 @@ func passphraseRetriever(keyName string, createNew bool, numAttempts int) (strin
|
|||
return "", false, errors.New("Passphrase too short")
|
||||
}
|
||||
|
||||
fmt.Printf("Repeat %s key passphrase: ", keyName)
|
||||
fmt.Printf("Repeat passphrase for new %s key with id %s:: ", alias, keyID)
|
||||
confirmation, err := stdin.ReadBytes('\n')
|
||||
fmt.Println()
|
||||
if err != nil {
|
||||
|
@ -309,7 +339,15 @@ func passphraseRetriever(keyName string, createNew bool, numAttempts int) (strin
|
|||
if !bytes.Equal(passphrase, confirmation) {
|
||||
return "", false, errors.New("The entered passphrases do not match")
|
||||
}
|
||||
return string(passphrase), false, nil
|
||||
retPass := string(passphrase)
|
||||
|
||||
if alias == "snapshots" || alias == "targets" {
|
||||
userEnteredTargetsSnapshotsPass = true
|
||||
targetsSnapshotsPass = retPass
|
||||
}
|
||||
|
||||
return retPass, false, nil
|
||||
}
|
||||
}
|
||||
|
||||
func getInsecureTransport() *http.Transport {
|
||||
|
|
|
@ -58,8 +58,8 @@ func (ccs *CryptoService) Create(role string, algorithm data.KeyAlgorithm) (data
|
|||
}
|
||||
logrus.Debugf("generated new %s key for role: %s and keyID: %s", algorithm, role, privKey.ID())
|
||||
|
||||
// Store the private key into our keystore with the name being: /GUN/ID.key
|
||||
err = ccs.keyStore.AddKey(filepath.Join(ccs.gun, privKey.ID()), privKey)
|
||||
// Store the private key into our keystore with the name being: /GUN/ID.key with an alias of role
|
||||
err = ccs.keyStore.AddKey(filepath.Join(ccs.gun, privKey.ID()), role, privKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to add key to filestore: %v", err)
|
||||
}
|
||||
|
|
|
@ -34,6 +34,10 @@ var (
|
|||
ErrNoKeysFoundForGUN = errors.New("no keys found for specified GUN")
|
||||
)
|
||||
|
||||
const (
|
||||
aliasSuffix = ".alias"
|
||||
)
|
||||
|
||||
// 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 {
|
||||
|
@ -89,29 +93,17 @@ func moveKeys(oldKeyStore, newKeyStore *trustmanager.KeyFileStore) error {
|
|||
relKeyPath := strings.TrimPrefix(fullKeyPath, oldKeyStore.BaseDir())
|
||||
relKeyPath = strings.TrimPrefix(relKeyPath, string(filepath.Separator))
|
||||
|
||||
pemBytes, err := oldKeyStore.Get(relKeyPath)
|
||||
pemBytes, err := oldKeyStore.GetKey(relKeyPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
block, _ := pem.Decode(pemBytes)
|
||||
if block == nil {
|
||||
return ErrNoValidPrivateKey
|
||||
}
|
||||
|
||||
if !x509.IsEncryptedPEMBlock(block) {
|
||||
// Key is not encrypted. Parse it, and add it
|
||||
// to the temporary store as an encrypted key.
|
||||
privKey, err := trustmanager.ParsePEMPrivateKey(pemBytes, "")
|
||||
alias, err := oldKeyStore.GetKeyAlias(relKeyPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = newKeyStore.AddKey(relKeyPath, privKey)
|
||||
} else {
|
||||
// Encrypted key - pass it through without
|
||||
// decrypting
|
||||
err = newKeyStore.Add(relKeyPath, pemBytes)
|
||||
}
|
||||
|
||||
err = newKeyStore.AddKey(relKeyPath, alias, pemBytes)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -207,11 +199,13 @@ func (km *KeyStoreManager) ImportKeysZip(zipReader zip.Reader, passphrase string
|
|||
// store in an inconsistent state
|
||||
newRootKeys := make(map[string][]byte)
|
||||
newNonRootKeys := make(map[string]data.PrivateKey)
|
||||
newNonRootKeyAliases := make(map[string]string)
|
||||
|
||||
// Note that using / as a separator is okay here - the zip package
|
||||
// guarantees that the separator will be /
|
||||
rootKeysPrefix := privDir + "/" + rootKeysSubdir + "/"
|
||||
nonRootKeysPrefix := privDir + "/" + nonRootKeysSubdir + "/"
|
||||
aliasSuffix := ".alias"
|
||||
|
||||
// Iterate through the files in the archive. Don't add the keys
|
||||
for _, f := range zipReader.File {
|
||||
|
@ -222,7 +216,7 @@ func (km *KeyStoreManager) ImportKeysZip(zipReader zip.Reader, passphrase string
|
|||
return err
|
||||
}
|
||||
|
||||
pemBytes, err := ioutil.ReadAll(rc)
|
||||
fileBytes, err := ioutil.ReadAll(rc)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -231,25 +225,29 @@ func (km *KeyStoreManager) ImportKeysZip(zipReader zip.Reader, passphrase string
|
|||
// Note that using / as a separator is okay here - the zip
|
||||
// package guarantees that the separator will be /
|
||||
if strings.HasPrefix(fNameTrimmed, rootKeysPrefix) {
|
||||
if err = checkRootKeyIsEncrypted(pemBytes); err != nil {
|
||||
if err = checkRootKeyIsEncrypted(fileBytes); err != nil {
|
||||
rc.Close()
|
||||
return err
|
||||
}
|
||||
// Root keys are preserved without decrypting
|
||||
keyName := strings.TrimPrefix(fNameTrimmed, rootKeysPrefix)
|
||||
newRootKeys[keyName] = pemBytes
|
||||
newRootKeys[keyName] = fileBytes
|
||||
} else if strings.HasPrefix(fNameTrimmed, nonRootKeysPrefix) {
|
||||
// Non-root keys need to be decrypted
|
||||
key, err := trustmanager.ParsePEMPrivateKey(pemBytes, passphrase)
|
||||
key, err := trustmanager.ParsePEMPrivateKey(fileBytes, passphrase)
|
||||
if err != nil {
|
||||
rc.Close()
|
||||
return err
|
||||
}
|
||||
keyName := strings.TrimPrefix(fNameTrimmed, nonRootKeysPrefix)
|
||||
newNonRootKeys[keyName] = key
|
||||
} else if strings.HasSuffix(fNameTrimmed, aliasSuffix) {
|
||||
// Aliases need to be recorded so they can be reintroduced in the new zip
|
||||
fileName := strings.TrimSuffix(fNameTrimmed, aliasSuffix)
|
||||
newNonRootKeyAliases[fileName] = string(fileBytes)
|
||||
} else {
|
||||
// This path inside the zip archive doesn't look like a
|
||||
// root key or a non-root key. To avoid adding a file
|
||||
// root key, non-root key, or alias. 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)
|
||||
|
@ -261,13 +259,17 @@ func (km *KeyStoreManager) ImportKeysZip(zipReader zip.Reader, passphrase string
|
|||
}
|
||||
|
||||
for keyName, pemBytes := range newRootKeys {
|
||||
if err := km.rootKeyStore.Add(keyName + "." + aliasSuffix, []byte("root")); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := km.rootKeyStore.Add(keyName, pemBytes); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for keyName, privKey := range newNonRootKeys {
|
||||
if err := km.nonRootKeyStore.AddKey(keyName, privKey); err != nil {
|
||||
alias := newNonRootKeyAliases[keyName]
|
||||
if err := km.nonRootKeyStore.AddKey(keyName, alias, privKey); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -292,6 +294,11 @@ func moveKeysByGUN(oldKeyStore, newKeyStore *trustmanager.KeyFileStore, gun stri
|
|||
return err
|
||||
}
|
||||
|
||||
alias, err := oldKeyStore.GetKeyAlias(relKeyPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
block, _ := pem.Decode(pemBytes)
|
||||
if block == nil {
|
||||
return ErrNoValidPrivateKey
|
||||
|
@ -307,7 +314,7 @@ func moveKeysByGUN(oldKeyStore, newKeyStore *trustmanager.KeyFileStore, gun stri
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = newKeyStore.AddKey(relKeyPath, privKey)
|
||||
err = newKeyStore.AddKey(relKeyPath, alias, privKey)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ func (km *KeyStoreManager) GenRootKey(algorithm string) (string, error) {
|
|||
}
|
||||
|
||||
// Changing the root
|
||||
km.rootKeyStore.AddKey(privKey.ID(), privKey)
|
||||
km.rootKeyStore.AddKey(privKey.ID(), "root", privKey)
|
||||
|
||||
return privKey.ID(), nil
|
||||
}
|
||||
|
|
|
@ -9,14 +9,16 @@ import (
|
|||
|
||||
const (
|
||||
keyExtension = "key"
|
||||
aliasExtension = "alias"
|
||||
)
|
||||
|
||||
// KeyStore is a generic interface for private key storage
|
||||
type KeyStore interface {
|
||||
LimitedFileStore
|
||||
|
||||
AddKey(name string, privKey data.PrivateKey) error
|
||||
AddKey(name, alias string, privKey data.PrivateKey) error
|
||||
GetKey(name string) (data.PrivateKey, error)
|
||||
GetKeyAlias(name string) (string, error)
|
||||
ListKeys() []string
|
||||
RemoveKey(name string) error
|
||||
}
|
||||
|
@ -25,7 +27,7 @@ type KeyStore interface {
|
|||
// for a given named key. If it should be treated as new passphrase (e.g. with
|
||||
// confirmation), createNew will be true. Attempts is passed in so that implementers
|
||||
// decide how many chances to give to a human, for example.
|
||||
type PassphraseRetriever func(keyName string, createNew bool, attempts int) (passphrase string, giveup bool, err error)
|
||||
type PassphraseRetriever func(keyId, alias string, createNew bool, attempts int) (passphrase string, giveup bool, err error)
|
||||
|
||||
// KeyFileStore persists and manages private keys on disk
|
||||
type KeyFileStore struct {
|
||||
|
@ -51,8 +53,8 @@ func NewKeyFileStore(baseDir string, passphraseRetriever PassphraseRetriever) (*
|
|||
}
|
||||
|
||||
// AddKey stores the contents of a PEM-encoded private key as a PEM block
|
||||
func (s *KeyFileStore) AddKey(name string, privKey data.PrivateKey) error {
|
||||
return addKey(s, s.PassphraseRetriever, name, privKey)
|
||||
func (s *KeyFileStore) AddKey(name, alias string, privKey data.PrivateKey) error {
|
||||
return addKey(s, s.PassphraseRetriever, name, alias, privKey)
|
||||
}
|
||||
|
||||
// GetKey returns the PrivateKey given a KeyID
|
||||
|
@ -60,6 +62,12 @@ func (s *KeyFileStore) GetKey(name string) (data.PrivateKey, error) {
|
|||
return getKey(s, s.PassphraseRetriever, name)
|
||||
}
|
||||
|
||||
// GetKeyAlias returns the PrivateKey given a KeyID
|
||||
func (s *KeyFileStore) GetKeyAlias(name string) (string, error) {
|
||||
return getKeyAlias(s, name)
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
|
@ -69,7 +77,7 @@ func (s *KeyFileStore) ListKeys() []string {
|
|||
|
||||
// RemoveKey removes the key from the keyfilestore
|
||||
func (s *KeyFileStore) RemoveKey(name string) error {
|
||||
return remove(s, name)
|
||||
return removeKey(s, name)
|
||||
}
|
||||
|
||||
// NewKeyMemoryStore returns a new KeyMemoryStore which holds keys in memory
|
||||
|
@ -80,8 +88,8 @@ func NewKeyMemoryStore(passphraseRetriever PassphraseRetriever) *KeyMemoryStore
|
|||
}
|
||||
|
||||
// AddKey stores the contents of a PEM-encoded private key as a PEM block
|
||||
func (s *KeyMemoryStore) AddKey(name string, privKey data.PrivateKey) error {
|
||||
return addKey(s, s.PassphraseRetriever, name, privKey)
|
||||
func (s *KeyMemoryStore) AddKey(name, alias string, privKey data.PrivateKey) error {
|
||||
return addKey(s, s.PassphraseRetriever, name, alias, privKey)
|
||||
}
|
||||
|
||||
// GetKey returns the PrivateKey given a KeyID
|
||||
|
@ -89,6 +97,12 @@ func (s *KeyMemoryStore) GetKey(name string) (data.PrivateKey, error) {
|
|||
return getKey(s, s.PassphraseRetriever, name)
|
||||
}
|
||||
|
||||
// GetKeyAlias returns the PrivateKey given a KeyID
|
||||
func (s *KeyMemoryStore) GetKeyAlias(name string) (string, error) {
|
||||
return getKeyAlias(s, name)
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
|
@ -98,11 +112,11 @@ func (s *KeyMemoryStore) ListKeys() []string {
|
|||
|
||||
// RemoveKey removes the key from the keystore
|
||||
func (s *KeyMemoryStore) RemoveKey(name string) error {
|
||||
return remove(s, name)
|
||||
return removeKey(s, name)
|
||||
}
|
||||
|
||||
|
||||
func addKey(s LimitedFileStore, passphraseRetriever PassphraseRetriever, name string, privKey data.PrivateKey) error {
|
||||
func addKey(s LimitedFileStore, passphraseRetriever PassphraseRetriever, name, alias string, privKey data.PrivateKey) error {
|
||||
pemPrivKey, err := KeyToPEM(privKey)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -111,8 +125,8 @@ func addKey(s LimitedFileStore, passphraseRetriever PassphraseRetriever, name st
|
|||
attempts := 0
|
||||
passphrase := ""
|
||||
giveup := false
|
||||
for (true) {
|
||||
passphrase, giveup, err = passphraseRetriever(name, true, attempts)
|
||||
for {
|
||||
passphrase, giveup, err = passphraseRetriever(name, alias, true, attempts)
|
||||
if err != nil {
|
||||
attempts++
|
||||
continue
|
||||
|
@ -124,17 +138,29 @@ func addKey(s LimitedFileStore, passphraseRetriever PassphraseRetriever, name st
|
|||
}
|
||||
|
||||
if passphrase != "" {
|
||||
encryptedPrivKey, err := EncryptPrivateKey(privKey, passphrase)
|
||||
pemPrivKey, err = EncryptPrivateKey(privKey, passphrase)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.Add(name, encryptedPrivKey)
|
||||
}
|
||||
|
||||
err = s.Add(name + "." + aliasExtension, []byte(alias))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.Add(name, pemPrivKey)
|
||||
}
|
||||
|
||||
|
||||
func getKeyAlias(s LimitedFileStore, name string) (string, error) {
|
||||
keyAlias, err := s.Get(name + "." + aliasExtension)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(keyAlias), nil
|
||||
}
|
||||
|
||||
// GetKey returns the PrivateKey given a KeyID
|
||||
func getKey(s LimitedFileStore, passphraseRetriever PassphraseRetriever, name string) (data.PrivateKey, error) {
|
||||
keyBytes, err := s.Get(name)
|
||||
|
@ -142,13 +168,19 @@ func getKey(s LimitedFileStore, passphraseRetriever PassphraseRetriever, name st
|
|||
return nil, err
|
||||
}
|
||||
|
||||
keyAlias, err := getKeyAlias(s, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
// See if the key is encrypted. If its encrypted we'll fail to parse the private key
|
||||
privKey, err := ParsePEMPrivateKey(keyBytes, "")
|
||||
if err != nil {
|
||||
// We need to decrypt the key, lets get a passphrase
|
||||
attempts := 0
|
||||
for (true) {
|
||||
passphrase, giveup, err := passphraseRetriever(name, false, attempts)
|
||||
for {
|
||||
passphrase, giveup, err := passphraseRetriever(name, string(keyAlias), false, attempts)
|
||||
// Check if the passphrase retriever got an error or if it is telling us to give up
|
||||
if giveup || err != nil {
|
||||
return nil, err
|
||||
|
@ -179,6 +211,6 @@ func listKeys(s LimitedFileStore) []string {
|
|||
}
|
||||
|
||||
// RemoveKey removes the key from the keyfilestore
|
||||
func remove(s LimitedFileStore, name string) error {
|
||||
func removeKey(s LimitedFileStore, name string) error {
|
||||
return s.Remove(name)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue