docs/trustmanager/keyfilestore.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)
}