diff --git a/internal/rbd/controllerserver.go b/internal/rbd/controllerserver.go index 11b28d3a5..8d6107a54 100644 --- a/internal/rbd/controllerserver.go +++ b/internal/rbd/controllerserver.go @@ -691,7 +691,7 @@ func (cs *ControllerServer) DeleteVolume(ctx context.Context, req *csi.DeleteVol } if rbdVol.isEncrypted() { - if err = rbdVol.encryption.KMS.DeletePassphrase(rbdVol.VolID); err != nil { + if err = rbdVol.encryption.RemoveDEK(rbdVol.VolID); err != nil { util.WarningLog(ctx, "failed to clean the passphrase for volume %s: %s", rbdVol.VolID, err) } } diff --git a/internal/rbd/encryption.go b/internal/rbd/encryption.go index e22f53994..0767b8884 100644 --- a/internal/rbd/encryption.go +++ b/internal/rbd/encryption.go @@ -90,7 +90,7 @@ func (rv *rbdVolume) isEncrypted() bool { // - the Data-Encryption-Key (DEK) will be generated stored for use by the KMS; // - the RBD image will be marked to support encryption in its metadata. func (rv *rbdVolume) setupEncryption(ctx context.Context) error { - err := util.StoreNewCryptoPassphrase(rv.VolID, rv.encryption.KMS) + err := rv.encryption.StoreNewCryptoPassphrase(rv.VolID) if err != nil { util.ErrorLog(ctx, "failed to save encryption passphrase for "+ "image %s: %s", rv.String(), err) @@ -108,7 +108,7 @@ func (rv *rbdVolume) setupEncryption(ctx context.Context) error { } func (rv *rbdVolume) encryptDevice(ctx context.Context, devicePath string) error { - passphrase, err := util.GetCryptoPassphrase(rv.VolID, rv.encryption.KMS) + passphrase, err := rv.encryption.GetCryptoPassphrase(rv.VolID) if err != nil { util.ErrorLog(ctx, "failed to get crypto passphrase for %s: %v", rv.String(), err) @@ -131,7 +131,7 @@ func (rv *rbdVolume) encryptDevice(ctx context.Context, devicePath string) error } func (rv *rbdVolume) openEncryptedDevice(ctx context.Context, devicePath string) (string, error) { - passphrase, err := util.GetCryptoPassphrase(rv.VolID, rv.encryption.KMS) + passphrase, err := rv.encryption.GetCryptoPassphrase(rv.VolID) if err != nil { util.ErrorLog(ctx, "failed to get passphrase for encrypted device %s: %v", rv.String(), err) diff --git a/internal/util/crypto.go b/internal/util/crypto.go index 1f15a3cea..bdc0e2773 100644 --- a/internal/util/crypto.go +++ b/internal/util/crypto.go @@ -106,13 +106,20 @@ func (ve *VolumeEncryption) Destroy() { ve.KMS.Destroy() } +// RemoveDEK deletes the DEK for a particular volumeID from the DEKStore linked +// with this VolumeEncryption instance. +func (ve *VolumeEncryption) RemoveDEK(volumeID string) error { + if ve.dekStore == nil { + return ErrDEKStoreNotFound + } + + return ve.dekStore.RemoveDEK(volumeID) +} + // EncryptionKMS provides external Key Management System for encryption // passphrases storage. type EncryptionKMS interface { Destroy() - GetPassphrase(key string) (string, error) - SavePassphrase(key, value string) error - DeletePassphrase(key string) error GetID() string // requiresDEKStore returns the DEKStoreType that is needed to be @@ -148,6 +155,13 @@ type DEKStore interface { 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 } + // GetKMS returns an instance of Key Management System. // // - tenant is the owner of the Volume, used to fetch the Vault Token from the @@ -209,12 +223,13 @@ func GetKMS(tenant, kmsID string, secrets map[string]string) (EncryptionKMS, err } // StoreNewCryptoPassphrase generates a new passphrase and saves it in the KMS. -func StoreNewCryptoPassphrase(volumeID string, kms EncryptionKMS) error { +func (ve *VolumeEncryption) StoreNewCryptoPassphrase(volumeID string) error { passphrase, err := generateNewEncryptionPassphrase() if err != nil { return fmt.Errorf("failed to generate passphrase for %s: %w", volumeID, err) } - err = kms.SavePassphrase(volumeID, passphrase) + + err = ve.dekStore.StoreDEK(volumeID, passphrase) if err != nil { return fmt.Errorf("failed to save the passphrase for %s: %w", volumeID, err) } @@ -222,8 +237,8 @@ func StoreNewCryptoPassphrase(volumeID string, kms EncryptionKMS) error { } // GetCryptoPassphrase Retrieves passphrase to encrypt volume. -func GetCryptoPassphrase(volumeID string, kms EncryptionKMS) (string, error) { - passphrase, err := kms.GetPassphrase(volumeID) +func (ve *VolumeEncryption) GetCryptoPassphrase(volumeID string) (string, error) { + passphrase, err := ve.dekStore.FetchDEK(volumeID) if err != nil { return "", err } diff --git a/internal/util/crypto_test.go b/internal/util/crypto_test.go index 3b622a08f..61cce4b81 100644 --- a/internal/util/crypto_test.go +++ b/internal/util/crypto_test.go @@ -60,12 +60,16 @@ func TestKMSWorkflow(t *testing.T) { require.NotNil(t, kms) assert.Equal(t, defaultKMSType, kms.GetID()) + ve, err := NewVolumeEncryption(kms) + assert.NoError(t, err) + require.NotNil(t, ve) + volumeID := "volume-id" - err = StoreNewCryptoPassphrase(volumeID, kms) + err = ve.StoreNewCryptoPassphrase(volumeID) assert.NoError(t, err) - passphrase, err := GetCryptoPassphrase(volumeID, kms) + passphrase, err := ve.GetCryptoPassphrase(volumeID) assert.NoError(t, err) assert.Equal(t, secrets[encryptionPassphraseKey], passphrase) } diff --git a/internal/util/secretskms.go b/internal/util/secretskms.go index 45320ecd4..ea6f70179 100644 --- a/internal/util/secretskms.go +++ b/internal/util/secretskms.go @@ -56,19 +56,19 @@ func (kms SecretsKMS) Destroy() { // nothing to do } -// GetPassphrase returns passphrase from Kubernetes secrets. -func (kms SecretsKMS) GetPassphrase(key string) (string, error) { +// FetchDEK returns passphrase from Kubernetes secrets. +func (kms SecretsKMS) FetchDEK(key string) (string, error) { return kms.passphrase, nil } -// SavePassphrase does nothing, as there is no passphrase per key (volume), so +// StoreDEK does nothing, as there is no passphrase per key (volume), so // no need to store is anywhere. -func (kms SecretsKMS) SavePassphrase(key, value string) error { +func (kms SecretsKMS) StoreDEK(key, value string) error { return nil } -// DeletePassphrase is doing nothing as no new passphrases are saved with +// RemoveDEK is doing nothing as no new passphrases are saved with // SecretsKMS. -func (kms SecretsKMS) DeletePassphrase(key string) error { +func (kms SecretsKMS) RemoveDEK(key string) error { return nil } diff --git a/internal/util/vault.go b/internal/util/vault.go index 91889aaa7..97766a19e 100644 --- a/internal/util/vault.go +++ b/internal/util/vault.go @@ -328,9 +328,9 @@ func (vc *vaultConnection) GetID() string { return vc.EncryptionKMSID } -// GetPassphrase returns passphrase from Vault. The passphrase is stored in a +// FetchDEK returns passphrase from Vault. The passphrase is stored in a // data.data.passphrase structure. -func (kms *VaultKMS) GetPassphrase(key string) (string, error) { +func (kms *VaultKMS) FetchDEK(key string) (string, error) { s, err := kms.secrets.GetSecret(filepath.Join(kms.vaultPassphrasePath, key), kms.keyContext) if err != nil { return "", err @@ -348,8 +348,8 @@ func (kms *VaultKMS) GetPassphrase(key string) (string, error) { return passphrase, nil } -// SavePassphrase saves new passphrase in Vault. -func (kms *VaultKMS) SavePassphrase(key, value string) error { +// StoreDEK saves new passphrase in Vault. +func (kms *VaultKMS) StoreDEK(key, value string) error { data := map[string]interface{}{ "data": map[string]string{ "passphrase": value, @@ -365,8 +365,8 @@ func (kms *VaultKMS) SavePassphrase(key, value string) error { return nil } -// DeletePassphrase deletes passphrase from Vault. -func (kms *VaultKMS) DeletePassphrase(key string) error { +// RemoveDEK deletes passphrase from Vault. +func (kms *VaultKMS) RemoveDEK(key string) error { pathKey := filepath.Join(kms.vaultPassphrasePath, key) err := kms.secrets.DeleteSecret(pathKey, kms.keyContext) if err != nil { diff --git a/internal/util/vault_tokens.go b/internal/util/vault_tokens.go index ca04a57ee..36ae5ea2e 100644 --- a/internal/util/vault_tokens.go +++ b/internal/util/vault_tokens.go @@ -347,9 +347,9 @@ func (kms *VaultTokensKMS) initCertificates(config map[string]interface{}) error return nil } -// GetPassphrase returns passphrase from Vault. The passphrase is stored in a +// FetchDEK returns passphrase from Vault. The passphrase is stored in a // data.data.passphrase structure. -func (kms *VaultTokensKMS) GetPassphrase(key string) (string, error) { +func (kms *VaultTokensKMS) FetchDEK(key string) (string, error) { s, err := kms.secrets.GetSecret(key, kms.keyContext) if err != nil { return "", err @@ -367,8 +367,8 @@ func (kms *VaultTokensKMS) GetPassphrase(key string) (string, error) { return passphrase, nil } -// SavePassphrase saves new passphrase in Vault. -func (kms *VaultTokensKMS) SavePassphrase(key, value string) error { +// StoreDEK saves new passphrase in Vault. +func (kms *VaultTokensKMS) StoreDEK(key, value string) error { data := map[string]interface{}{ "data": map[string]string{ "passphrase": value, @@ -383,8 +383,8 @@ func (kms *VaultTokensKMS) SavePassphrase(key, value string) error { return nil } -// DeletePassphrase deletes passphrase from Vault. -func (kms *VaultTokensKMS) DeletePassphrase(key string) error { +// RemoveDEK deletes passphrase from Vault. +func (kms *VaultTokensKMS) RemoveDEK(key string) error { err := kms.secrets.DeleteSecret(key, kms.keyContext) if err != nil { return fmt.Errorf("delete passphrase at %s request to vault failed: %w", key, err)