mirror of https://github.com/docker/docs.git
170 lines
4.8 KiB
Go
170 lines
4.8 KiB
Go
package trustmanager
|
|
|
|
import (
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/endophage/gotuf/data"
|
|
)
|
|
|
|
const (
|
|
keyExtension = "key"
|
|
)
|
|
|
|
// KeyStore is a generic interface for private key storage
|
|
type KeyStore interface {
|
|
LimitedFileStore
|
|
|
|
AddKey(name string, privKey data.PrivateKey) error
|
|
GetKey(name string) (data.PrivateKey, error)
|
|
AddEncryptedKey(name string, privKey data.PrivateKey, passphrase string) error
|
|
GetDecryptedKey(name string, passphrase string) (data.PrivateKey, error)
|
|
ListKeys() []string
|
|
}
|
|
|
|
// KeyFileStore persists and manages private keys on disk
|
|
type KeyFileStore struct {
|
|
SimpleFileStore
|
|
}
|
|
|
|
// KeyMemoryStore manages private keys in memory
|
|
type KeyMemoryStore struct {
|
|
MemoryFileStore
|
|
}
|
|
|
|
// NewKeyFileStore returns a new KeyFileStore creating a private directory to
|
|
// hold the keys.
|
|
func NewKeyFileStore(baseDir string) (*KeyFileStore, error) {
|
|
fileStore, err := NewPrivateSimpleFileStore(baseDir, keyExtension)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &KeyFileStore{*fileStore}, nil
|
|
}
|
|
|
|
// 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, name, privKey)
|
|
}
|
|
|
|
// GetKey returns the PrivateKey given a KeyID
|
|
func (s *KeyFileStore) GetKey(name string) (data.PrivateKey, error) {
|
|
return getKey(s, name)
|
|
}
|
|
|
|
// AddEncryptedKey stores the contents of a PEM-encoded private key as an encrypted PEM block
|
|
func (s *KeyFileStore) AddEncryptedKey(name string, privKey data.PrivateKey, passphrase string) error {
|
|
return addEncryptedKey(s, name, privKey, passphrase)
|
|
}
|
|
|
|
// GetDecryptedKey decrypts and returns the PEM Encoded private key given a flename
|
|
// and a passphrase
|
|
func (s *KeyFileStore) GetDecryptedKey(name string, passphrase string) (data.PrivateKey, error) {
|
|
return getDecryptedKey(s, name, passphrase)
|
|
}
|
|
|
|
// 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
|
|
func (s *KeyFileStore) ListKeys() []string {
|
|
return listKeys(s)
|
|
}
|
|
|
|
// NewKeyMemoryStore returns a new KeyMemoryStore which holds keys in memory
|
|
func NewKeyMemoryStore() *KeyMemoryStore {
|
|
memStore := NewMemoryFileStore()
|
|
|
|
return &KeyMemoryStore{*memStore}
|
|
}
|
|
|
|
// 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, name, privKey)
|
|
}
|
|
|
|
// GetKey returns the PrivateKey given a KeyID
|
|
func (s *KeyMemoryStore) GetKey(name string) (data.PrivateKey, error) {
|
|
return getKey(s, name)
|
|
}
|
|
|
|
// AddEncryptedKey stores the contents of a PEM-encoded private key as an encrypted PEM block
|
|
func (s *KeyMemoryStore) AddEncryptedKey(name string, privKey data.PrivateKey, passphrase string) error {
|
|
return addEncryptedKey(s, name, privKey, passphrase)
|
|
}
|
|
|
|
// GetDecryptedKey decrypts and returns the PEM Encoded private key given a flename
|
|
// and a passphrase
|
|
func (s *KeyMemoryStore) GetDecryptedKey(name string, passphrase string) (data.PrivateKey, error) {
|
|
return getDecryptedKey(s, name, passphrase)
|
|
}
|
|
|
|
// 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
|
|
func (s *KeyMemoryStore) ListKeys() []string {
|
|
return listKeys(s)
|
|
}
|
|
|
|
func addKey(s LimitedFileStore, name string, privKey data.PrivateKey) error {
|
|
pemPrivKey, err := KeyToPEM(privKey)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return s.Add(name, pemPrivKey)
|
|
}
|
|
|
|
func getKey(s LimitedFileStore, name string) (data.PrivateKey, error) {
|
|
keyBytes, err := s.Get(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Convert PEM encoded bytes back to a PrivateKey
|
|
privKey, err := ParsePEMPrivateKey(keyBytes, "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return privKey, nil
|
|
}
|
|
|
|
func addEncryptedKey(s LimitedFileStore, name string, privKey data.PrivateKey, passphrase string) error {
|
|
encryptedPrivKey, err := EncryptPrivateKey(privKey, passphrase)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return s.Add(name, encryptedPrivKey)
|
|
}
|
|
|
|
func getDecryptedKey(s LimitedFileStore, name string, passphrase string) (data.PrivateKey, error) {
|
|
keyBytes, err := s.Get(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Gets an unencrypted PrivateKey.
|
|
privKey, err := ParsePEMPrivateKey(keyBytes, passphrase)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return privKey, nil
|
|
}
|
|
|
|
func listKeys(s LimitedFileStore) []string {
|
|
var keyIDList []string
|
|
for _, f := range s.ListFiles(false) {
|
|
keyID := strings.TrimSpace(strings.TrimSuffix(filepath.Base(f), filepath.Ext(f)))
|
|
keyIDList = append(keyIDList, keyID)
|
|
}
|
|
return keyIDList
|
|
}
|
|
|
|
// RemoveKey removes the key from the keyfilestore
|
|
func (s *KeyFileStore) RemoveKey(name string) error {
|
|
return s.Remove(name)
|
|
}
|