diff --git a/internal/cephfs/controllerserver.go b/internal/cephfs/controllerserver.go index 9a750f2a4..dac4bad3b 100644 --- a/internal/cephfs/controllerserver.go +++ b/internal/cephfs/controllerserver.go @@ -77,7 +77,7 @@ func (cs *ControllerServer) createBackingVolume( &volOptions.SubVolume, volOptions.ClusterID, cs.ClusterName, cs.SetMetadata) if sID != nil { - err = parentVolOpt.CopyEncryptionConfig(volOptions, sID.SnapshotID, vID.VolumeID) + err = parentVolOpt.CopyEncryptionConfig(ctx, volOptions, sID.SnapshotID, vID.VolumeID) if err != nil { return status.Error(codes.Internal, err.Error()) } @@ -86,7 +86,7 @@ func (cs *ControllerServer) createBackingVolume( } if parentVolOpt != nil { - err = parentVolOpt.CopyEncryptionConfig(volOptions, pvID.VolumeID, vID.VolumeID) + err = parentVolOpt.CopyEncryptionConfig(ctx, volOptions, pvID.VolumeID, vID.VolumeID) if err != nil { return status.Error(codes.Internal, err.Error()) } @@ -596,7 +596,7 @@ func (cs *ControllerServer) cleanUpBackingVolume( // GetSecret enabled KMS the DEKs are stored by // fscrypt on the volume that is going to be deleted anyway. log.DebugLog(ctx, "going to remove DEK for integrated store %q (fscrypt)", volOptions.Encryption.GetID()) - if err := volOptions.Encryption.RemoveDEK(volID.VolumeID); err != nil { + if err := volOptions.Encryption.RemoveDEK(ctx, volID.VolumeID); err != nil { log.WarningLog(ctx, "failed to clean the passphrase for volume %q (file encryption): %s", volOptions.VolID, err) } @@ -907,7 +907,7 @@ func (cs *ControllerServer) CreateSnapshot( // Use same encryption KMS than source volume and copy the passphrase. The passphrase becomes // available under the snapshot id for CreateVolume to use this snap as a backing volume snapVolOptions := store.VolumeOptions{} - err = parentVolOptions.CopyEncryptionConfig(&snapVolOptions, sourceVolID, sID.SnapshotID) + err = parentVolOptions.CopyEncryptionConfig(ctx, &snapVolOptions, sourceVolID, sID.SnapshotID) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } diff --git a/internal/cephfs/store/volumeoptions.go b/internal/cephfs/store/volumeoptions.go index de5b14b1d..068afd725 100644 --- a/internal/cephfs/store/volumeoptions.go +++ b/internal/cephfs/store/volumeoptions.go @@ -901,7 +901,7 @@ func IsEncrypted(ctx context.Context, volOptions map[string]string) (bool, error // CopyEncryptionConfig copies passphrases and initializes a fresh // Encryption struct if necessary from (vo, vID) to (cp, cpVID). -func (vo *VolumeOptions) CopyEncryptionConfig(cp *VolumeOptions, vID, cpVID string) error { +func (vo *VolumeOptions) CopyEncryptionConfig(ctx context.Context, cp *VolumeOptions, vID, cpVID string) error { var err error if !vo.IsEncrypted() { @@ -916,7 +916,7 @@ func (vo *VolumeOptions) CopyEncryptionConfig(cp *VolumeOptions, vID, cpVID stri if cp.Encryption == nil { cp.Encryption, err = util.NewVolumeEncryption(vo.Encryption.GetID(), vo.Encryption.KMS) if errors.Is(err, util.ErrDEKStoreNeeded) { - _, err := vo.Encryption.KMS.GetSecret("") + _, err := vo.Encryption.KMS.GetSecret(ctx, "") if errors.Is(err, kmsapi.ErrGetSecretUnsupported) { return err } @@ -924,13 +924,13 @@ func (vo *VolumeOptions) CopyEncryptionConfig(cp *VolumeOptions, vID, cpVID stri } if vo.Encryption.KMS.RequiresDEKStore() == kmsapi.DEKStoreIntegrated { - passphrase, err := vo.Encryption.GetCryptoPassphrase(vID) + passphrase, err := vo.Encryption.GetCryptoPassphrase(ctx, vID) if err != nil { return fmt.Errorf("failed to fetch passphrase for %q (%+v): %w", vID, vo, err) } - err = cp.Encryption.StoreCryptoPassphrase(cpVID, passphrase) + err = cp.Encryption.StoreCryptoPassphrase(ctx, cpVID, passphrase) if err != nil { return fmt.Errorf("failed to store passphrase for %q (%+v): %w", cpVID, cp, err) @@ -962,7 +962,7 @@ func (vo *VolumeOptions) ConfigureEncryption( // store. Since not all "metadata" KMS support // GetSecret, test for support here. Postpone any // other error handling - _, err := vo.Encryption.KMS.GetSecret("") + _, err := vo.Encryption.KMS.GetSecret(ctx, "") if errors.Is(err, kmsapi.ErrGetSecretUnsupported) { return err } diff --git a/internal/kms/aws_metadata.go b/internal/kms/aws_metadata.go index f74a5f581..a8a67bb5a 100644 --- a/internal/kms/aws_metadata.go +++ b/internal/kms/aws_metadata.go @@ -183,7 +183,7 @@ func (kms *awsMetadataKMS) getService() (*awsKMS.KMS, error) { } // EncryptDEK uses the Amazon KMS and the configured CMK to encrypt the DEK. -func (kms *awsMetadataKMS) EncryptDEK(volumeID, plainDEK string) (string, error) { +func (kms *awsMetadataKMS) EncryptDEK(ctx context.Context, volumeID, plainDEK string) (string, error) { svc, err := kms.getService() if err != nil { return "", fmt.Errorf("could not get KMS service: %w", err) @@ -205,7 +205,7 @@ func (kms *awsMetadataKMS) EncryptDEK(volumeID, plainDEK string) (string, error) } // DecryptDEK uses the Amazon KMS and the configured CMK to decrypt the DEK. -func (kms *awsMetadataKMS) DecryptDEK(volumeID, encryptedDEK string) (string, error) { +func (kms *awsMetadataKMS) DecryptDEK(ctx context.Context, volumeID, encryptedDEK string) (string, error) { svc, err := kms.getService() if err != nil { return "", fmt.Errorf("could not get KMS service: %w", err) @@ -227,6 +227,6 @@ func (kms *awsMetadataKMS) DecryptDEK(volumeID, encryptedDEK string) (string, er return string(result.Plaintext), nil } -func (kms *awsMetadataKMS) GetSecret(volumeID string) (string, error) { +func (kms *awsMetadataKMS) GetSecret(ctx context.Context, volumeID string) (string, error) { return "", ErrGetSecretUnsupported } diff --git a/internal/kms/aws_sts_metadata.go b/internal/kms/aws_sts_metadata.go index a0db764d8..7dd70ed59 100644 --- a/internal/kms/aws_sts_metadata.go +++ b/internal/kms/aws_sts_metadata.go @@ -193,7 +193,7 @@ func (as *awsSTSMetadataKMS) getServiceWithSTS() (*awsKMS.KMS, error) { } // EncryptDEK uses the Amazon KMS and the configured CMK to encrypt the DEK. -func (as *awsSTSMetadataKMS) EncryptDEK(_, plainDEK string) (string, error) { +func (as *awsSTSMetadataKMS) EncryptDEK(ctx context.Context, _, plainDEK string) (string, error) { svc, err := as.getServiceWithSTS() if err != nil { return "", fmt.Errorf("failed to get KMS service: %w", err) @@ -213,7 +213,7 @@ func (as *awsSTSMetadataKMS) EncryptDEK(_, plainDEK string) (string, error) { } // DecryptDEK uses the Amazon KMS and the configured CMK to decrypt the DEK. -func (as *awsSTSMetadataKMS) DecryptDEK(_, encryptedDEK string) (string, error) { +func (as *awsSTSMetadataKMS) DecryptDEK(ctx context.Context, _, encryptedDEK string) (string, error) { svc, err := as.getServiceWithSTS() if err != nil { return "", fmt.Errorf("failed to get KMS service: %w", err) diff --git a/internal/kms/keyprotect.go b/internal/kms/keyprotect.go index d020c75b5..fdb70a99b 100644 --- a/internal/kms/keyprotect.go +++ b/internal/kms/keyprotect.go @@ -204,14 +204,14 @@ func (kms *keyProtectKMS) getService() error { } // EncryptDEK uses the KeyProtect KMS and the configured CRK to encrypt the DEK. -func (kms *keyProtectKMS) EncryptDEK(volumeID, plainDEK string) (string, error) { +func (kms *keyProtectKMS) EncryptDEK(ctx context.Context, volumeID, plainDEK string) (string, error) { if err := kms.getService(); err != nil { return "", fmt.Errorf("could not get KMS service: %w", err) } dekByteSlice := []byte(plainDEK) aadVolID := []string{volumeID} - result, err := kms.client.Wrap(context.TODO(), kms.customerRootKey, dekByteSlice, &aadVolID) + result, err := kms.client.Wrap(ctx, kms.customerRootKey, dekByteSlice, &aadVolID) if err != nil { return "", fmt.Errorf("failed to wrap the DEK: %w", err) } @@ -223,7 +223,7 @@ func (kms *keyProtectKMS) EncryptDEK(volumeID, plainDEK string) (string, error) } // DecryptDEK uses the Key protect KMS and the configured CRK to decrypt the DEK. -func (kms *keyProtectKMS) DecryptDEK(volumeID, encryptedDEK string) (string, error) { +func (kms *keyProtectKMS) DecryptDEK(ctx context.Context, volumeID, encryptedDEK string) (string, error) { if err := kms.getService(); err != nil { return "", fmt.Errorf("could not get KMS service: %w", err) } @@ -235,7 +235,7 @@ func (kms *keyProtectKMS) DecryptDEK(volumeID, encryptedDEK string) (string, err } aadVolID := []string{volumeID} - result, err := kms.client.Unwrap(context.TODO(), kms.customerRootKey, ciphertextBlob, &aadVolID) + result, err := kms.client.Unwrap(ctx, kms.customerRootKey, ciphertextBlob, &aadVolID) if err != nil { return "", fmt.Errorf("failed to unwrap the DEK: %w", err) } @@ -243,6 +243,6 @@ func (kms *keyProtectKMS) DecryptDEK(volumeID, encryptedDEK string) (string, err return string(result), nil } -func (kms *keyProtectKMS) GetSecret(volumeID string) (string, error) { +func (kms *keyProtectKMS) GetSecret(ctx context.Context, volumeID string) (string, error) { return "", ErrGetSecretUnsupported } diff --git a/internal/kms/kmip.go b/internal/kms/kmip.go index f0e1fac2b..7296abd5b 100644 --- a/internal/kms/kmip.go +++ b/internal/kms/kmip.go @@ -180,7 +180,7 @@ func initKMIPKMS(args ProviderInitArgs) (EncryptionKMS, error) { } // EncryptDEK uses the KMIP encrypt operation to encrypt the DEK. -func (kms *kmipKMS) EncryptDEK(_, plainDEK string) (string, error) { +func (kms *kmipKMS) EncryptDEK(ctx context.Context, _, plainDEK string) (string, error) { conn, err := kms.connect() if err != nil { return "", err @@ -236,7 +236,7 @@ func (kms *kmipKMS) EncryptDEK(_, plainDEK string) (string, error) { } // DecryptDEK uses the KMIP decrypt operation to decrypt the DEK. -func (kms *kmipKMS) DecryptDEK(_, encryptedDEK string) (string, error) { +func (kms *kmipKMS) DecryptDEK(ctx context.Context, _, encryptedDEK string) (string, error) { conn, err := kms.connect() if err != nil { return "", err @@ -500,7 +500,7 @@ func (kms *kmipKMS) verifyResponse( return &batchItem, nil } -func (kms *kmipKMS) GetSecret(volumeID string) (string, error) { +func (kms *kmipKMS) GetSecret(ctx context.Context, volumeID string) (string, error) { return "", ErrGetSecretUnsupported } diff --git a/internal/kms/kms.go b/internal/kms/kms.go index dbe734fe1..732f271ed 100644 --- a/internal/kms/kms.go +++ b/internal/kms/kms.go @@ -331,18 +331,18 @@ type EncryptionKMS interface { // 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) + EncryptDEK(ctx context.Context, 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) + DecryptDEK(ctx context.Context, volumeID, encyptedDEK string) (string, error) // GetSecret allows external key management systems to // retrieve keys used in EncryptDEK / DecryptDEK to use them // directly. Example: fscrypt uses this to unlock raw protectors - GetSecret(volumeID string) (string, error) + GetSecret(ctx context.Context, volumeID string) (string, error) } // DEKStoreType describes what DEKStore needs to be configured when using a @@ -364,11 +364,11 @@ const ( // 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 + StoreDEK(ctx context.Context, volumeID string, dek string) error // FetchDEK reads the DEK from the configured store and returns it. - FetchDEK(volumeID string) (string, error) + FetchDEK(ctx context.Context, volumeID string) (string, error) // RemoveDEK deletes the DEK from the configured store. - RemoveDEK(volumeID string) error + RemoveDEK(ctx context.Context, volumeID string) error } // integratedDEK is a DEKStore that can not be configured. Either the KMS does @@ -380,15 +380,15 @@ func (i integratedDEK) RequiresDEKStore() DEKStoreType { return DEKStoreIntegrated } -func (i integratedDEK) EncryptDEK(volumeID, plainDEK string) (string, error) { +func (i integratedDEK) EncryptDEK(ctx context.Context, volumeID, plainDEK string) (string, error) { return plainDEK, nil } -func (i integratedDEK) DecryptDEK(volumeID, encyptedDEK string) (string, error) { +func (i integratedDEK) DecryptDEK(ctx context.Context, volumeID, encyptedDEK string) (string, error) { return encyptedDEK, nil } -func (i integratedDEK) GetSecret(volumeID string) (string, error) { +func (i integratedDEK) GetSecret(ctx context.Context, volumeID string) (string, error) { return "", ErrGetSecretIntegrated } diff --git a/internal/kms/secretskms.go b/internal/kms/secretskms.go index 4b4866c79..d20b53a0c 100644 --- a/internal/kms/secretskms.go +++ b/internal/kms/secretskms.go @@ -78,19 +78,19 @@ func (kms secretsKMS) Destroy() { } // FetchDEK returns passphrase from Kubernetes secrets. -func (kms secretsKMS) FetchDEK(key string) (string, error) { +func (kms secretsKMS) FetchDEK(ctx context.Context, key string) (string, error) { return kms.passphrase, nil } // StoreDEK does nothing, as there is no passphrase per key (volume), so // no need to store is anywhere. -func (kms secretsKMS) StoreDEK(key, value string) error { +func (kms secretsKMS) StoreDEK(ctx context.Context, key, value string) error { return nil } // RemoveDEK is doing nothing as no new passphrases are saved with // secretsKMS. -func (kms secretsKMS) RemoveDEK(key string) error { +func (kms secretsKMS) RemoveDEK(ctx context.Context, key string) error { return nil } @@ -206,9 +206,9 @@ type encryptedMetedataDEK struct { // the secretsKMS and the volumeID. // The resulting encryptedDEK contains a JSON with the encrypted DEK and the // nonce that was used for encrypting. -func (kms secretsMetadataKMS) EncryptDEK(volumeID, plainDEK string) (string, error) { +func (kms secretsMetadataKMS) EncryptDEK(ctx context.Context, volumeID, plainDEK string) (string, error) { // use the passphrase from the secretKMS - passphrase, err := kms.secretsKMS.FetchDEK(volumeID) + passphrase, err := kms.secretsKMS.FetchDEK(ctx, volumeID) if err != nil { return "", fmt.Errorf("failed to get passphrase: %w", err) } @@ -236,9 +236,9 @@ func (kms secretsMetadataKMS) EncryptDEK(volumeID, plainDEK string) (string, err // DecryptDEK takes the JSON formatted `encryptedMetadataDEK` contents, and it // fetches secretKMS passphrase to decrypt the DEK. -func (kms secretsMetadataKMS) DecryptDEK(volumeID, encryptedDEK string) (string, error) { +func (kms secretsMetadataKMS) DecryptDEK(ctx context.Context, volumeID, encryptedDEK string) (string, error) { // use the passphrase from the secretKMS - passphrase, err := kms.secretsKMS.FetchDEK(volumeID) + passphrase, err := kms.secretsKMS.FetchDEK(ctx, volumeID) if err != nil { return "", fmt.Errorf("failed to get passphrase: %w", err) } @@ -263,9 +263,9 @@ func (kms secretsMetadataKMS) DecryptDEK(volumeID, encryptedDEK string) (string, return string(dek), nil } -func (kms secretsMetadataKMS) GetSecret(volumeID string) (string, error) { +func (kms secretsMetadataKMS) GetSecret(ctx context.Context, volumeID string) (string, error) { // use the passphrase from the secretKMS - return kms.secretsKMS.FetchDEK(volumeID) + return kms.secretsKMS.FetchDEK(ctx, volumeID) } // generateCipher returns a AEAD cipher based on a passphrase and salt diff --git a/internal/kms/secretskms_test.go b/internal/kms/secretskms_test.go index 835d00db4..3845d76f0 100644 --- a/internal/kms/secretskms_test.go +++ b/internal/kms/secretskms_test.go @@ -17,6 +17,7 @@ limitations under the License. package kms import ( + "context" "testing" "github.com/stretchr/testify/assert" @@ -103,19 +104,21 @@ func TestWorkflowSecretsMetadataKMS(t *testing.T) { // plainDEK is the (LUKS) passphrase for the volume plainDEK := "usually created with generateNewEncryptionPassphrase()" - encryptedDEK, err := kms.EncryptDEK(volumeID, plainDEK) + ctx := context.TODO() + + encryptedDEK, err := kms.EncryptDEK(ctx, volumeID, plainDEK) assert.NoError(t, err) assert.NotEqual(t, "", encryptedDEK) assert.NotEqual(t, plainDEK, encryptedDEK) // with an incorrect volumeID, decrypting should fail - decryptedDEK, err := kms.DecryptDEK("incorrect-volumeID", encryptedDEK) + decryptedDEK, err := kms.DecryptDEK(ctx, "incorrect-volumeID", encryptedDEK) assert.Error(t, err) assert.Equal(t, "", decryptedDEK) assert.NotEqual(t, plainDEK, decryptedDEK) // with the right volumeID, decrypting should return the plainDEK - decryptedDEK, err = kms.DecryptDEK(volumeID, encryptedDEK) + decryptedDEK, err = kms.DecryptDEK(ctx, volumeID, encryptedDEK) assert.NoError(t, err) assert.NotEqual(t, "", decryptedDEK) assert.Equal(t, plainDEK, decryptedDEK) diff --git a/internal/kms/vault.go b/internal/kms/vault.go index 36622a28e..8735d93c8 100644 --- a/internal/kms/vault.go +++ b/internal/kms/vault.go @@ -17,6 +17,7 @@ limitations under the License. package kms import ( + "context" "errors" "fmt" "os" @@ -395,7 +396,7 @@ func initVaultKMS(args ProviderInitArgs) (EncryptionKMS, error) { // FetchDEK returns passphrase from Vault. The passphrase is stored in a // data.data.passphrase structure. -func (kms *vaultKMS) FetchDEK(key string) (string, error) { +func (kms *vaultKMS) FetchDEK(ctx context.Context, key string) (string, error) { // Since the second return variable loss.Version is not used, there it is ignored. s, _, err := kms.secrets.GetSecret(filepath.Join(kms.vaultPassphrasePath, key), kms.keyContext) if err != nil { @@ -415,7 +416,7 @@ func (kms *vaultKMS) FetchDEK(key string) (string, error) { } // StoreDEK saves new passphrase in Vault. -func (kms *vaultKMS) StoreDEK(key, value string) error { +func (kms *vaultKMS) StoreDEK(ctx context.Context, key, value string) error { data := map[string]interface{}{ "data": map[string]string{ "passphrase": value, @@ -433,7 +434,7 @@ func (kms *vaultKMS) StoreDEK(key, value string) error { } // RemoveDEK deletes passphrase from Vault. -func (kms *vaultKMS) RemoveDEK(key string) error { +func (kms *vaultKMS) RemoveDEK(ctx context.Context, key string) error { pathKey := filepath.Join(kms.vaultPassphrasePath, key) err := kms.secrets.DeleteSecret(pathKey, kms.getDeleteKeyContext()) if err != nil { diff --git a/internal/kms/vault_tokens.go b/internal/kms/vault_tokens.go index d31322ff5..e6a2d3056 100644 --- a/internal/kms/vault_tokens.go +++ b/internal/kms/vault_tokens.go @@ -459,7 +459,7 @@ func (vtc *vaultTenantConnection) getK8sClient() (*kubernetes.Clientset, error) // FetchDEK returns passphrase from Vault. The passphrase is stored in a // data.data.passphrase structure. -func (vtc *vaultTenantConnection) FetchDEK(key string) (string, error) { +func (vtc *vaultTenantConnection) FetchDEK(ctx context.Context, key string) (string, error) { // Since the second return variable loss.Version is not used, there it is ignored. s, _, err := vtc.secrets.GetSecret(key, vtc.keyContext) if err != nil { @@ -479,7 +479,7 @@ func (vtc *vaultTenantConnection) FetchDEK(key string) (string, error) { } // StoreDEK saves new passphrase in Vault. -func (vtc *vaultTenantConnection) StoreDEK(key, value string) error { +func (vtc *vaultTenantConnection) StoreDEK(ctx context.Context, key, value string) error { data := map[string]interface{}{ "data": map[string]string{ "passphrase": value, @@ -496,7 +496,7 @@ func (vtc *vaultTenantConnection) StoreDEK(key, value string) error { } // RemoveDEK deletes passphrase from Vault. -func (vtc *vaultTenantConnection) RemoveDEK(key string) error { +func (vtc *vaultTenantConnection) RemoveDEK(ctx context.Context, key string) error { err := vtc.secrets.DeleteSecret(key, vtc.getDeleteKeyContext()) if err != nil { return fmt.Errorf("delete passphrase at %s request to vault failed: %w", key, err) diff --git a/internal/rbd/clone.go b/internal/rbd/clone.go index a0faa468b..c5ff1e52f 100644 --- a/internal/rbd/clone.go +++ b/internal/rbd/clone.go @@ -155,7 +155,7 @@ func (rv *rbdVolume) createCloneFromImage(ctx context.Context, parentVol *rbdVol return err } - err = parentVol.copyEncryptionConfig(&rv.rbdImage, true) + err = parentVol.copyEncryptionConfig(ctx, &rv.rbdImage, true) if err != nil { return fmt.Errorf("failed to copy encryption config for %q: %w", rv, err) } @@ -232,7 +232,7 @@ func (rv *rbdVolume) doSnapClone(ctx context.Context, parentVol *rbdVolume) erro return errClone } - err = parentVol.copyEncryptionConfig(&rv.rbdImage, true) + err = parentVol.copyEncryptionConfig(ctx, &rv.rbdImage, true) if err != nil { return fmt.Errorf("failed to copy encryption config for %q: %w", rv, err) } diff --git a/internal/rbd/controllerserver.go b/internal/rbd/controllerserver.go index e3796b661..9e924710a 100644 --- a/internal/rbd/controllerserver.go +++ b/internal/rbd/controllerserver.go @@ -191,7 +191,7 @@ func (cs *ControllerServer) parseVolCreateRequest( // get the owner of the PVC which is required for few encryption related operations rbdVol.Owner = k8s.GetOwner(req.GetParameters()) - err = rbdVol.initKMS(req.GetParameters(), req.GetSecrets()) + err = rbdVol.initKMS(ctx, req.GetParameters(), req.GetSecrets()) if err != nil { return nil, status.Error(codes.InvalidArgument, err.Error()) } @@ -486,7 +486,7 @@ func (cs *ControllerServer) repairExistingVolume(ctx context.Context, req *csi.C return nil, err } - err = rbdSnap.repairEncryptionConfig(&rbdVol.rbdImage) + err = rbdSnap.repairEncryptionConfig(ctx, &rbdVol.rbdImage) if err != nil { return nil, err } @@ -677,7 +677,7 @@ func (cs *ControllerServer) createVolumeFromSnapshot( log.DebugLog(ctx, "create volume %s from snapshot %s", rbdVol, rbdSnap) - err = parentVol.copyEncryptionConfig(&rbdVol.rbdImage, true) + err = parentVol.copyEncryptionConfig(ctx, &rbdVol.rbdImage, true) if err != nil { return fmt.Errorf("failed to copy encryption config for %q: %w", rbdVol, err) } @@ -1229,7 +1229,7 @@ func cloneFromSnapshot( } defer vol.Destroy() - err = rbdVol.copyEncryptionConfig(&vol.rbdImage, false) + err = rbdVol.copyEncryptionConfig(ctx, &vol.rbdImage, false) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } @@ -1332,7 +1332,7 @@ func (cs *ControllerServer) doSnapshotClone( } }() - err = parentVol.copyEncryptionConfig(&cloneRbd.rbdImage, false) + err = parentVol.copyEncryptionConfig(ctx, &cloneRbd.rbdImage, false) if err != nil { log.ErrorLog(ctx, "failed to copy encryption "+ "config for %q: %v", cloneRbd, err) diff --git a/internal/rbd/encryption.go b/internal/rbd/encryption.go index 03ff15c52..828fafa12 100644 --- a/internal/rbd/encryption.go +++ b/internal/rbd/encryption.go @@ -116,7 +116,7 @@ func IsFileEncrypted(ctx context.Context, volOptions map[string]string) (bool, e // - 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 (ri *rbdImage) setupBlockEncryption(ctx context.Context) error { - err := ri.blockEncryption.StoreNewCryptoPassphrase(ri.VolID, encryptionPassphraseSize) + err := ri.blockEncryption.StoreNewCryptoPassphrase(ctx, ri.VolID, encryptionPassphraseSize) if err != nil { log.ErrorLog(ctx, "failed to save encryption passphrase for "+ "image %s: %s", ri, err) @@ -144,7 +144,7 @@ func (ri *rbdImage) setupBlockEncryption(ctx context.Context) error { // destination rbdImage's VolumeEncryption object which needs to be initialized // beforehand and is possibly different from the source VolumeEncryption // (Usecase: Restoring snapshot into a storageclass with different encryption config). -func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool) error { +func (ri *rbdImage) copyEncryptionConfig(ctx context.Context, cp *rbdImage, copyOnlyPassphrase bool) error { // nothing to do if parent image is not encrypted. if !ri.isBlockEncrypted() && !ri.isFileEncrypted() { return nil @@ -157,7 +157,7 @@ func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool) if ri.isBlockEncrypted() { // get the unencrypted passphrase - passphrase, err := ri.blockEncryption.GetCryptoPassphrase(ri.VolID) + passphrase, err := ri.blockEncryption.GetCryptoPassphrase(ctx, ri.VolID) if err != nil { return fmt.Errorf("failed to fetch passphrase for %q: %w", ri, err) @@ -171,7 +171,7 @@ func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool) } // re-encrypt the plain passphrase for the cloned volume - err = cp.blockEncryption.StoreCryptoPassphrase(cp.VolID, passphrase) + err = cp.blockEncryption.StoreCryptoPassphrase(ctx, cp.VolID, passphrase) if err != nil { return fmt.Errorf("failed to store passphrase for %q: %w", cp, err) @@ -182,7 +182,7 @@ func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool) var err error cp.fileEncryption, err = util.NewVolumeEncryption(ri.fileEncryption.GetID(), ri.fileEncryption.KMS) if errors.Is(err, util.ErrDEKStoreNeeded) { - _, err := ri.fileEncryption.KMS.GetSecret("") + _, err := ri.fileEncryption.KMS.GetSecret(ctx, "") if errors.Is(err, kmsapi.ErrGetSecretUnsupported) { return err } @@ -191,14 +191,14 @@ func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool) if ri.isFileEncrypted() && ri.fileEncryption.KMS.RequiresDEKStore() == kmsapi.DEKStoreIntegrated { // get the unencrypted passphrase - passphrase, err := ri.fileEncryption.GetCryptoPassphrase(ri.VolID) + passphrase, err := ri.fileEncryption.GetCryptoPassphrase(ctx, ri.VolID) if err != nil { return fmt.Errorf("failed to fetch passphrase for %q: %w", ri, err) } // re-encrypt the plain passphrase for the cloned volume - err = cp.fileEncryption.StoreCryptoPassphrase(cp.VolID, passphrase) + err = cp.fileEncryption.StoreCryptoPassphrase(ctx, cp.VolID, passphrase) if err != nil { return fmt.Errorf("failed to store passphrase for %q: %w", cp, err) @@ -223,7 +223,7 @@ func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool) // repairEncryptionConfig checks the encryption state of the current rbdImage, // and makes sure that the destination rbdImage has the same configuration. -func (ri *rbdImage) repairEncryptionConfig(dest *rbdImage) error { +func (ri *rbdImage) repairEncryptionConfig(ctx context.Context, dest *rbdImage) error { if !ri.isBlockEncrypted() && !ri.isFileEncrypted() { return nil } @@ -236,14 +236,14 @@ func (ri *rbdImage) repairEncryptionConfig(dest *rbdImage) error { dest.conn = ri.conn.Copy() } - return ri.copyEncryptionConfig(dest, true) + return ri.copyEncryptionConfig(ctx, dest, true) } return nil } func (ri *rbdImage) encryptDevice(ctx context.Context, devicePath string) error { - passphrase, err := ri.blockEncryption.GetCryptoPassphrase(ri.VolID) + passphrase, err := ri.blockEncryption.GetCryptoPassphrase(ctx, ri.VolID) if err != nil { log.ErrorLog(ctx, "failed to get crypto passphrase for %s: %v", ri, err) @@ -269,7 +269,7 @@ func (ri *rbdImage) encryptDevice(ctx context.Context, devicePath string) error } func (rv *rbdVolume) openEncryptedDevice(ctx context.Context, devicePath string) (string, error) { - passphrase, err := rv.blockEncryption.GetCryptoPassphrase(rv.VolID) + passphrase, err := rv.blockEncryption.GetCryptoPassphrase(ctx, rv.VolID) if err != nil { log.ErrorLog(ctx, "failed to get passphrase for encrypted device %s: %v", rv, err) @@ -300,7 +300,7 @@ func (rv *rbdVolume) openEncryptedDevice(ctx context.Context, devicePath string) return mapperFilePath, nil } -func (ri *rbdImage) initKMS(volOptions, credentials map[string]string) error { +func (ri *rbdImage) initKMS(ctx context.Context, volOptions, credentials map[string]string) error { kmsID, encType, err := ParseEncryptionOpts(volOptions, rbdDefaultEncryptionType) if err != nil { return err @@ -310,7 +310,7 @@ func (ri *rbdImage) initKMS(volOptions, credentials map[string]string) error { case util.EncryptionTypeBlock: err = ri.configureBlockEncryption(kmsID, credentials) case util.EncryptionTypeFile: - err = ri.configureFileEncryption(kmsID, credentials) + err = ri.configureFileEncryption(ctx, kmsID, credentials) case util.EncryptionTypeInvalid: return fmt.Errorf("invalid encryption type") case util.EncryptionTypeNone: @@ -376,7 +376,7 @@ func (ri *rbdImage) configureBlockEncryption(kmsID string, credentials map[strin // configureBlockDeviceEncryption sets up the VolumeEncryption for this rbdImage. Once // configured, use isEncrypted() to see if the volume supports encryption. -func (ri *rbdImage) configureFileEncryption(kmsID string, credentials map[string]string) error { +func (ri *rbdImage) configureFileEncryption(ctx context.Context, kmsID string, credentials map[string]string) error { kms, err := kmsapi.GetKMS(ri.Owner, kmsID, credentials) if err != nil { return err @@ -390,7 +390,7 @@ func (ri *rbdImage) configureFileEncryption(kmsID string, credentials map[string // store. Since not all "metadata" KMS support // GetSecret, test for support here. Postpone any // other error handling - _, err := ri.fileEncryption.KMS.GetSecret("") + _, err := ri.fileEncryption.KMS.GetSecret(ctx, "") if errors.Is(err, kmsapi.ErrGetSecretUnsupported) { return err } @@ -400,7 +400,7 @@ func (ri *rbdImage) configureFileEncryption(kmsID string, credentials map[string } // StoreDEK saves the DEK in the metadata, overwrites any existing contents. -func (ri *rbdImage) StoreDEK(volumeID, dek string) error { +func (ri *rbdImage) StoreDEK(ctx context.Context, volumeID, dek string) error { if ri.VolID == "" { return fmt.Errorf("BUG: %q does not have VolID set, call "+ "stack: %s", ri, util.CallStack()) @@ -413,7 +413,7 @@ func (ri *rbdImage) StoreDEK(volumeID, dek string) error { } // FetchDEK reads the DEK from the image metadata. -func (ri *rbdImage) FetchDEK(volumeID string) (string, error) { +func (ri *rbdImage) FetchDEK(ctx context.Context, volumeID string) (string, error) { if ri.VolID == "" { return "", fmt.Errorf("BUG: %q does not have VolID set, call "+ "stack: %s", ri, util.CallStack()) @@ -426,7 +426,7 @@ func (ri *rbdImage) FetchDEK(volumeID string) (string, error) { // RemoveDEK does not need to remove the DEK from the metadata, the image is // most likely getting removed. -func (ri *rbdImage) RemoveDEK(volumeID string) error { +func (ri *rbdImage) RemoveDEK(ctx context.Context, volumeID string) error { if ri.VolID == "" { return fmt.Errorf("BUG: %q does not have VolID set, call "+ "stack: %s", ri, util.CallStack()) diff --git a/internal/rbd/nodeserver.go b/internal/rbd/nodeserver.go index 773557e0c..b1170b905 100644 --- a/internal/rbd/nodeserver.go +++ b/internal/rbd/nodeserver.go @@ -232,7 +232,7 @@ func (ns *NodeServer) populateRbdVol( return nil, status.Error(codes.Internal, err.Error()) } - err = rv.initKMS(req.GetVolumeContext(), req.GetSecrets()) + err = rv.initKMS(ctx, req.GetVolumeContext(), req.GetSecrets()) if err != nil { return nil, status.Error(codes.Internal, err.Error()) } diff --git a/internal/rbd/rbd_journal.go b/internal/rbd/rbd_journal.go index 55c6a033e..cba62c841 100644 --- a/internal/rbd/rbd_journal.go +++ b/internal/rbd/rbd_journal.go @@ -334,7 +334,7 @@ func (rv *rbdVolume) Exists(ctx context.Context, parentVol *rbdVolume) (bool, er } if parentVol != nil { - err = parentVol.copyEncryptionConfig(&rv.rbdImage, true) + err = parentVol.copyEncryptionConfig(ctx, &rv.rbdImage, true) if err != nil { log.ErrorLog(ctx, err.Error()) diff --git a/internal/rbd/rbd_util.go b/internal/rbd/rbd_util.go index 08f9f7598..401711a9b 100644 --- a/internal/rbd/rbd_util.go +++ b/internal/rbd/rbd_util.go @@ -635,14 +635,14 @@ func (ri *rbdImage) deleteImage(ctx context.Context) error { if ri.isBlockEncrypted() { log.DebugLog(ctx, "rbd: going to remove DEK for %q (block encryption)", ri) - if err = ri.blockEncryption.RemoveDEK(ri.VolID); err != nil { + if err = ri.blockEncryption.RemoveDEK(ctx, ri.VolID); err != nil { log.WarningLog(ctx, "failed to clean the passphrase for volume %s (block encryption): %s", ri.VolID, err) } } if ri.isFileEncrypted() { log.DebugLog(ctx, "rbd: going to remove DEK for %q (file encryption)", ri) - if err = ri.fileEncryption.RemoveDEK(ri.VolID); err != nil { + if err = ri.fileEncryption.RemoveDEK(ctx, ri.VolID); err != nil { log.WarningLog(ctx, "failed to clean the passphrase for volume %s (file encryption): %s", ri.VolID, err) } } @@ -1032,7 +1032,7 @@ func genSnapFromSnapID( } } if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == util.EncryptionTypeFile { - err = rbdSnap.configureFileEncryption(imageAttributes.KmsID, secrets) + err = rbdSnap.configureFileEncryption(ctx, imageAttributes.KmsID, secrets) if err != nil { return fmt.Errorf("failed to configure file encryption for "+ "%q: %w", rbdSnap, err) @@ -1133,7 +1133,7 @@ func generateVolumeFromVolumeID( } } if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == util.EncryptionTypeFile { - err = rbdVol.configureFileEncryption(imageAttributes.KmsID, secrets) + err = rbdVol.configureFileEncryption(ctx, imageAttributes.KmsID, secrets) if err != nil { return rbdVol, err } diff --git a/internal/util/crypto.go b/internal/util/crypto.go index 9eb67a1db..bae43808b 100644 --- a/internal/util/crypto.go +++ b/internal/util/crypto.go @@ -189,12 +189,12 @@ func (ve *VolumeEncryption) Destroy() { // RemoveDEK deletes the DEK for a particular volumeID from the DEKStore linked // with this VolumeEncryption instance. -func (ve *VolumeEncryption) RemoveDEK(volumeID string) error { +func (ve *VolumeEncryption) RemoveDEK(ctx context.Context, volumeID string) error { if ve.dekStore == nil { return ErrDEKStoreNotFound } - return ve.dekStore.RemoveDEK(volumeID) + return ve.dekStore.RemoveDEK(ctx, volumeID) } func (ve *VolumeEncryption) GetID() string { @@ -203,13 +203,13 @@ func (ve *VolumeEncryption) GetID() string { // StoreCryptoPassphrase takes an unencrypted passphrase, encrypts it and saves // it in the DEKStore. -func (ve *VolumeEncryption) StoreCryptoPassphrase(volumeID, passphrase string) error { - encryptedPassphrase, err := ve.KMS.EncryptDEK(volumeID, passphrase) +func (ve *VolumeEncryption) StoreCryptoPassphrase(ctx context.Context, volumeID, passphrase string) error { + encryptedPassphrase, err := ve.KMS.EncryptDEK(ctx, volumeID, passphrase) if err != nil { return fmt.Errorf("failed encrypt the passphrase for %s: %w", volumeID, err) } - err = ve.dekStore.StoreDEK(volumeID, encryptedPassphrase) + err = ve.dekStore.StoreDEK(ctx, volumeID, encryptedPassphrase) if err != nil { return fmt.Errorf("failed to save the passphrase for %s: %w", volumeID, err) } @@ -218,23 +218,23 @@ func (ve *VolumeEncryption) StoreCryptoPassphrase(volumeID, passphrase string) e } // StoreNewCryptoPassphrase generates a new passphrase and saves it in the KMS. -func (ve *VolumeEncryption) StoreNewCryptoPassphrase(volumeID string, length int) error { +func (ve *VolumeEncryption) StoreNewCryptoPassphrase(ctx context.Context, volumeID string, length int) error { passphrase, err := generateNewEncryptionPassphrase(length) if err != nil { return fmt.Errorf("failed to generate passphrase for %s: %w", volumeID, err) } - return ve.StoreCryptoPassphrase(volumeID, passphrase) + return ve.StoreCryptoPassphrase(ctx, volumeID, passphrase) } // GetCryptoPassphrase Retrieves passphrase to encrypt volume. -func (ve *VolumeEncryption) GetCryptoPassphrase(volumeID string) (string, error) { - passphrase, err := ve.dekStore.FetchDEK(volumeID) +func (ve *VolumeEncryption) GetCryptoPassphrase(ctx context.Context, volumeID string) (string, error) { + passphrase, err := ve.dekStore.FetchDEK(ctx, volumeID) if err != nil { return "", err } - return ve.KMS.DecryptDEK(volumeID, passphrase) + return ve.KMS.DecryptDEK(ctx, volumeID, passphrase) } // generateNewEncryptionPassphrase generates a random passphrase for encryption. diff --git a/internal/util/crypto_test.go b/internal/util/crypto_test.go index f4f0f5716..4f4340ad5 100644 --- a/internal/util/crypto_test.go +++ b/internal/util/crypto_test.go @@ -17,6 +17,7 @@ limitations under the License. package util import ( + "context" "encoding/base64" "testing" @@ -55,11 +56,12 @@ func TestKMSWorkflow(t *testing.T) { assert.Equal(t, kms.DefaultKMSType, ve.GetID()) volumeID := "volume-id" + ctx := context.TODO() - err = ve.StoreNewCryptoPassphrase(volumeID, defaultEncryptionPassphraseSize) + err = ve.StoreNewCryptoPassphrase(ctx, volumeID, defaultEncryptionPassphraseSize) assert.NoError(t, err) - passphrase, err := ve.GetCryptoPassphrase(volumeID) + passphrase, err := ve.GetCryptoPassphrase(ctx, volumeID) assert.NoError(t, err) assert.Equal(t, secrets["encryptionPassphrase"], passphrase) } diff --git a/internal/util/fscrypt/fscrypt.go b/internal/util/fscrypt/fscrypt.go index b848f9e33..f83453cb8 100644 --- a/internal/util/fscrypt/fscrypt.go +++ b/internal/util/fscrypt/fscrypt.go @@ -76,14 +76,14 @@ func getPassphrase(ctx context.Context, encryption util.VolumeEncryption, volID switch encryption.KMS.RequiresDEKStore() { case kms.DEKStoreIntegrated: - passphrase, err = encryption.GetCryptoPassphrase(volID) + passphrase, err = encryption.GetCryptoPassphrase(ctx, volID) if err != nil { log.ErrorLog(ctx, "fscrypt: failed to get passphrase from KMS: %v", err) return "", err } case kms.DEKStoreMetadata: - passphrase, err = encryption.KMS.GetSecret(volID) + passphrase, err = encryption.KMS.GetSecret(ctx, volID) if err != nil { log.ErrorLog(ctx, "fscrypt: failed to GetSecret: %v", err) @@ -453,7 +453,7 @@ func Unlock( if !kernelPolicyExists && !metadataDirExists { log.DebugLog(ctx, "fscrypt: Creating new protector and policy") if volEncryption.KMS.RequiresDEKStore() == kms.DEKStoreIntegrated { - if err := volEncryption.StoreNewCryptoPassphrase(volID, encryptionPassphraseSize); err != nil { + if err := volEncryption.StoreNewCryptoPassphrase(ctx, volID, encryptionPassphraseSize); err != nil { log.ErrorLog(ctx, "fscrypt: store new crypto passphrase failed: %v", err) return err diff --git a/internal/util/getsecret_test.go b/internal/util/getsecret_test.go index 59e61e992..06609d8ab 100644 --- a/internal/util/getsecret_test.go +++ b/internal/util/getsecret_test.go @@ -14,6 +14,7 @@ limitations under the License. package util import ( + "context" "errors" "testing" @@ -34,7 +35,7 @@ func TestGetPassphraseFromKMS(t *testing.T) { volEnc, err := NewVolumeEncryption(provider.UniqueID, kms) if errors.Is(err, ErrDEKStoreNeeded) { - _, err = volEnc.KMS.GetSecret("") + _, err = volEnc.KMS.GetSecret(context.TODO(), "") if errors.Is(err, kmsapi.ErrGetSecretUnsupported) { continue // currently unsupported by fscrypt integration } @@ -45,7 +46,7 @@ func TestGetPassphraseFromKMS(t *testing.T) { continue } - secret, err := kms.GetSecret("") + secret, err := kms.GetSecret(context.TODO(), "") assert.NoError(t, err, provider.UniqueID) assert.NotEmpty(t, secret, provider.UniqueID) }