cleanup: move KMS functionality into its own package

A new "internal/kms" package is introduced, it holds the API that can be
consumed by the RBD components.

The KMS providers are currently in the same package as the API. With
later follow-up changes the providers will be placed in their own
sub-package.

Because of the name of the package "kms", the types, functions and
structs inside the package should not be prefixed with KMS anymore:

    internal/kms/kms.go:213:6: type name will be used as kms.KMSInitializerArgs by other packages, and that stutters; consider calling this InitializerArgs (golint)

Updates: #852
Signed-off-by: Niels de Vos <ndevos@redhat.com>
This commit is contained in:
Niels de Vos
2021-08-26 13:43:20 +02:00
committed by mergify[bot]
parent 778b5e86de
commit 4a3b1181ce
16 changed files with 215 additions and 190 deletions

View File

@ -26,6 +26,7 @@ import (
"strconv"
"strings"
"github.com/ceph/ceph-csi/internal/kms"
"github.com/ceph/ceph-csi/internal/util/log"
)
@ -33,9 +34,6 @@ const (
mapperFilePrefix = "luks-rbd-"
mapperFilePathPrefix = "/dev/mapper"
// kmsConfigPath is the location of the vault config file.
kmsConfigPath = "/etc/ceph-csi-encryption-kms-config/config.json"
// Passphrase size - 20 bytes is 160 bits to satisfy:
// https://tools.ietf.org/html/rfc6749#section-10.10
encryptionPassphraseSize = 20
@ -54,11 +52,11 @@ var (
)
type VolumeEncryption struct {
KMS EncryptionKMS
KMS kms.EncryptionKMS
// dekStore that will be used, this can be the EncryptionKMS or a
// different object implementing the DEKStore interface.
dekStore DEKStore
dekStore kms.DEKStore
id string
}
@ -76,7 +74,7 @@ func FetchEncryptionKMSID(encrypted, kmsID string) (string, error) {
}
if kmsID == "" {
kmsID = defaultKMSType
kmsID = kms.DefaultKMSType
}
return kmsID, nil
@ -88,24 +86,24 @@ func FetchEncryptionKMSID(encrypted, kmsID string) (string, error) {
// Callers that receive a ErrDEKStoreNeeded error, should use
// VolumeEncryption.SetDEKStore() to configure an alternative storage for the
// DEKs.
func NewVolumeEncryption(id string, kms EncryptionKMS) (*VolumeEncryption, error) {
func NewVolumeEncryption(id string, ekms kms.EncryptionKMS) (*VolumeEncryption, error) {
kmsID := id
if kmsID == "" {
// if kmsID is not set, encryption is enabled, and the type is
// SecretsKMS
kmsID = defaultKMSType
kmsID = kms.DefaultKMSType
}
ve := &VolumeEncryption{
id: kmsID,
KMS: kms,
KMS: ekms,
}
if kms.requiresDEKStore() == DEKStoreIntegrated {
dekStore, ok := kms.(DEKStore)
if ekms.RequiresDEKStore() == kms.DEKStoreIntegrated {
dekStore, ok := ekms.(kms.DEKStore)
if !ok {
return nil, fmt.Errorf("KMS %T does not implement the "+
"DEKStore interface", kms)
"DEKStore interface", ekms)
}
ve.dekStore = dekStore
@ -118,7 +116,7 @@ func NewVolumeEncryption(id string, kms EncryptionKMS) (*VolumeEncryption, error
// SetDEKStore sets the DEKStore for this VolumeEncryption instance. It will be
// used when StoreNewCryptoPassphrase() or RemoveDEK() is called.
func (ve *VolumeEncryption) SetDEKStore(dekStore DEKStore) {
func (ve *VolumeEncryption) SetDEKStore(dekStore kms.DEKStore) {
ve.dekStore = dekStore
}
@ -141,72 +139,6 @@ func (ve *VolumeEncryption) GetID() string {
return ve.id
}
// EncryptionKMS provides external Key Management System for encryption
// passphrases storage.
type EncryptionKMS interface {
Destroy()
// requiresDEKStore returns the DEKStoreType that is needed to be
// configure for the KMS. Nothing needs to be done when this function
// returns DEKStoreIntegrated, otherwise you will need to configure an
// alternative storage for the DEKs.
requiresDEKStore() DEKStoreType
// EncryptDEK provides a way for a KMS to encrypt a DEK. In case the
// encryption is done transparently inside the KMS service, the
// function can return an unencrypted value.
EncryptDEK(volumeID, plainDEK string) (string, error)
// DecryptDEK provides a way for a KMS to decrypt a DEK. In case the
// encryption is done transparently inside the KMS service, the
// function does not need to do anything except return the encyptedDEK
// as it was received.
DecryptDEK(volumeID, encyptedDEK string) (string, error)
}
// DEKStoreType describes what DEKStore needs to be configured when using a
// particular KMS. A KMS might support different DEKStores depending on its
// configuration.
type DEKStoreType string
const (
// DEKStoreIntegrated indicates that the KMS itself supports storing
// DEKs.
DEKStoreIntegrated = DEKStoreType("")
// DEKStoreMetadata indicates that the KMS should be configured to
// store the DEK in the metadata of the volume.
DEKStoreMetadata = DEKStoreType("metadata")
)
// DEKStore allows KMS instances to implement a modular backend for DEK
// storage. This can be used to store the DEK in a different location, in case
// the KMS can not store passphrases for volumes.
type DEKStore interface {
// StoreDEK saves the DEK in the configured store.
StoreDEK(volumeID string, dek string) error
// FetchDEK reads the DEK from the configured store and returns it.
FetchDEK(volumeID string) (string, error)
// RemoveDEK deletes the DEK from the configured store.
RemoveDEK(volumeID string) error
}
// integratedDEK is a DEKStore that can not be configured. Either the KMS does
// not use a DEK, or the DEK is stored in the KMS without additional
// configuration options.
type integratedDEK struct{}
func (i integratedDEK) requiresDEKStore() DEKStoreType {
return DEKStoreIntegrated
}
func (i integratedDEK) EncryptDEK(volumeID, plainDEK string) (string, error) {
return plainDEK, nil
}
func (i integratedDEK) DecryptDEK(volumeID, encyptedDEK string) (string, error) {
return encyptedDEK, nil
}
// StoreCryptoPassphrase takes an unencrypted passphrase, encrypts it and saves
// it in the DEKStore.
func (ve *VolumeEncryption) StoreCryptoPassphrase(volumeID, passphrase string) error {