From 7b332a01841d711c26f500eb3ceb76d3d1f253f2 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Fri, 12 Mar 2021 14:26:21 +0100 Subject: [PATCH] rbd: add rbdImage.copyEncryptionConfig() to copy encryption metadata Cloning volumes requires copying the DEK from the source to the newly cloned volume. Introduce copyEncryptionConfig() as a helper for that. Signed-off-by: Niels de Vos --- internal/rbd/encryption.go | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/internal/rbd/encryption.go b/internal/rbd/encryption.go index e9b2622cb..259ae43d2 100644 --- a/internal/rbd/encryption.go +++ b/internal/rbd/encryption.go @@ -111,6 +111,45 @@ func (ri *rbdImage) setupEncryption(ctx context.Context) error { return nil } +// copyEncryptionConfig copies the VolumeEncryption object from the source +// rbdImage to the passed argument. This function re-encrypts the passphrase +// from the original, so that both encrypted passphrases (potentially, depends +// on the DEKStore) have different contents. +func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage) error { + // get the unencrypted passphrase + passphrase, err := ri.encryption.GetCryptoPassphrase(ri.VolID) + if err != nil { + return fmt.Errorf("failed to fetch passphrase for %q: %w", + ri.String(), err) + } + + cp.encryption, err = util.NewVolumeEncryption(ri.encryption.GetID(), ri.encryption.KMS) + if errors.Is(err, util.ErrDEKStoreNeeded) { + cp.encryption.SetDEKStore(cp) + } + + // re-encrypt the plain passphrase for the cloned volume + err = cp.encryption.StoreCryptoPassphrase(cp.VolID, passphrase) + if err != nil { + return fmt.Errorf("failed to store passphrase for %q: %w", + cp.String(), err) + } + + // copy encryption status for the original volume + status, err := ri.checkRbdImageEncrypted(context.TODO()) + if err != nil { + return fmt.Errorf("failed to get encryption status for %q: %w", + ri.String(), err) + } + err = cp.ensureEncryptionMetadataSet(status) + if err != nil { + return fmt.Errorf("failed to store encryption status for %q: "+ + "%w", cp.String(), err) + } + + return nil +} + func (ri *rbdImage) encryptDevice(ctx context.Context, devicePath string) error { passphrase, err := ri.encryption.GetCryptoPassphrase(ri.VolID) if err != nil {