mirror of
https://github.com/ceph/ceph-csi.git
synced 2024-12-18 11:00:25 +00:00
cleanup: refactor functions to accept a context parameter
Signed-off-by: Praveen M <m.praveen@ibm.com>
This commit is contained in:
parent
c90f7ed777
commit
e345b26340
@ -77,7 +77,7 @@ func (cs *ControllerServer) createBackingVolume(
|
|||||||
&volOptions.SubVolume, volOptions.ClusterID, cs.ClusterName, cs.SetMetadata)
|
&volOptions.SubVolume, volOptions.ClusterID, cs.ClusterName, cs.SetMetadata)
|
||||||
|
|
||||||
if sID != nil {
|
if sID != nil {
|
||||||
err = parentVolOpt.CopyEncryptionConfig(volOptions, sID.SnapshotID, vID.VolumeID)
|
err = parentVolOpt.CopyEncryptionConfig(ctx, volOptions, sID.SnapshotID, vID.VolumeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return status.Error(codes.Internal, err.Error())
|
return status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
@ -86,7 +86,7 @@ func (cs *ControllerServer) createBackingVolume(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if parentVolOpt != nil {
|
if parentVolOpt != nil {
|
||||||
err = parentVolOpt.CopyEncryptionConfig(volOptions, pvID.VolumeID, vID.VolumeID)
|
err = parentVolOpt.CopyEncryptionConfig(ctx, volOptions, pvID.VolumeID, vID.VolumeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return status.Error(codes.Internal, err.Error())
|
return status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
@ -596,7 +596,7 @@ func (cs *ControllerServer) cleanUpBackingVolume(
|
|||||||
// GetSecret enabled KMS the DEKs are stored by
|
// GetSecret enabled KMS the DEKs are stored by
|
||||||
// fscrypt on the volume that is going to be deleted anyway.
|
// 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())
|
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",
|
log.WarningLog(ctx, "failed to clean the passphrase for volume %q (file encryption): %s",
|
||||||
volOptions.VolID, err)
|
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
|
// 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
|
// available under the snapshot id for CreateVolume to use this snap as a backing volume
|
||||||
snapVolOptions := store.VolumeOptions{}
|
snapVolOptions := store.VolumeOptions{}
|
||||||
err = parentVolOptions.CopyEncryptionConfig(&snapVolOptions, sourceVolID, sID.SnapshotID)
|
err = parentVolOptions.CopyEncryptionConfig(ctx, &snapVolOptions, sourceVolID, sID.SnapshotID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -901,7 +901,7 @@ func IsEncrypted(ctx context.Context, volOptions map[string]string) (bool, error
|
|||||||
|
|
||||||
// CopyEncryptionConfig copies passphrases and initializes a fresh
|
// CopyEncryptionConfig copies passphrases and initializes a fresh
|
||||||
// Encryption struct if necessary from (vo, vID) to (cp, cpVID).
|
// 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
|
var err error
|
||||||
|
|
||||||
if !vo.IsEncrypted() {
|
if !vo.IsEncrypted() {
|
||||||
@ -916,7 +916,7 @@ func (vo *VolumeOptions) CopyEncryptionConfig(cp *VolumeOptions, vID, cpVID stri
|
|||||||
if cp.Encryption == nil {
|
if cp.Encryption == nil {
|
||||||
cp.Encryption, err = util.NewVolumeEncryption(vo.Encryption.GetID(), vo.Encryption.KMS)
|
cp.Encryption, err = util.NewVolumeEncryption(vo.Encryption.GetID(), vo.Encryption.KMS)
|
||||||
if errors.Is(err, util.ErrDEKStoreNeeded) {
|
if errors.Is(err, util.ErrDEKStoreNeeded) {
|
||||||
_, err := vo.Encryption.KMS.GetSecret("")
|
_, err := vo.Encryption.KMS.GetSecret(ctx, "")
|
||||||
if errors.Is(err, kmsapi.ErrGetSecretUnsupported) {
|
if errors.Is(err, kmsapi.ErrGetSecretUnsupported) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -924,13 +924,13 @@ func (vo *VolumeOptions) CopyEncryptionConfig(cp *VolumeOptions, vID, cpVID stri
|
|||||||
}
|
}
|
||||||
|
|
||||||
if vo.Encryption.KMS.RequiresDEKStore() == kmsapi.DEKStoreIntegrated {
|
if vo.Encryption.KMS.RequiresDEKStore() == kmsapi.DEKStoreIntegrated {
|
||||||
passphrase, err := vo.Encryption.GetCryptoPassphrase(vID)
|
passphrase, err := vo.Encryption.GetCryptoPassphrase(ctx, vID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to fetch passphrase for %q (%+v): %w",
|
return fmt.Errorf("failed to fetch passphrase for %q (%+v): %w",
|
||||||
vID, vo, err)
|
vID, vo, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = cp.Encryption.StoreCryptoPassphrase(cpVID, passphrase)
|
err = cp.Encryption.StoreCryptoPassphrase(ctx, cpVID, passphrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to store passphrase for %q (%+v): %w",
|
return fmt.Errorf("failed to store passphrase for %q (%+v): %w",
|
||||||
cpVID, cp, err)
|
cpVID, cp, err)
|
||||||
@ -962,7 +962,7 @@ func (vo *VolumeOptions) ConfigureEncryption(
|
|||||||
// store. Since not all "metadata" KMS support
|
// store. Since not all "metadata" KMS support
|
||||||
// GetSecret, test for support here. Postpone any
|
// GetSecret, test for support here. Postpone any
|
||||||
// other error handling
|
// other error handling
|
||||||
_, err := vo.Encryption.KMS.GetSecret("")
|
_, err := vo.Encryption.KMS.GetSecret(ctx, "")
|
||||||
if errors.Is(err, kmsapi.ErrGetSecretUnsupported) {
|
if errors.Is(err, kmsapi.ErrGetSecretUnsupported) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ func (kms *awsMetadataKMS) getService() (*awsKMS.KMS, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EncryptDEK uses the Amazon KMS and the configured CMK to encrypt the DEK.
|
// 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()
|
svc, err := kms.getService()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("could not get KMS service: %w", err)
|
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.
|
// 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()
|
svc, err := kms.getService()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("could not get KMS service: %w", err)
|
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
|
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
|
return "", ErrGetSecretUnsupported
|
||||||
}
|
}
|
||||||
|
@ -193,7 +193,7 @@ func (as *awsSTSMetadataKMS) getServiceWithSTS() (*awsKMS.KMS, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EncryptDEK uses the Amazon KMS and the configured CMK to encrypt the DEK.
|
// 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()
|
svc, err := as.getServiceWithSTS()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to get KMS service: %w", err)
|
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.
|
// 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()
|
svc, err := as.getServiceWithSTS()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to get KMS service: %w", err)
|
return "", fmt.Errorf("failed to get KMS service: %w", err)
|
||||||
|
@ -204,14 +204,14 @@ func (kms *keyProtectKMS) getService() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EncryptDEK uses the KeyProtect KMS and the configured CRK to encrypt the DEK.
|
// 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 {
|
if err := kms.getService(); err != nil {
|
||||||
return "", fmt.Errorf("could not get KMS service: %w", err)
|
return "", fmt.Errorf("could not get KMS service: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
dekByteSlice := []byte(plainDEK)
|
dekByteSlice := []byte(plainDEK)
|
||||||
aadVolID := []string{volumeID}
|
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 {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to wrap the DEK: %w", err)
|
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.
|
// 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 {
|
if err := kms.getService(); err != nil {
|
||||||
return "", fmt.Errorf("could not get KMS service: %w", err)
|
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}
|
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 {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to unwrap the DEK: %w", err)
|
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
|
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
|
return "", ErrGetSecretUnsupported
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ func initKMIPKMS(args ProviderInitArgs) (EncryptionKMS, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// EncryptDEK uses the KMIP encrypt operation to encrypt the DEK.
|
// 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()
|
conn, err := kms.connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -236,7 +236,7 @@ func (kms *kmipKMS) EncryptDEK(_, plainDEK string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DecryptDEK uses the KMIP decrypt operation to decrypt the DEK.
|
// 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()
|
conn, err := kms.connect()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -500,7 +500,7 @@ func (kms *kmipKMS) verifyResponse(
|
|||||||
return &batchItem, nil
|
return &batchItem, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (kms *kmipKMS) GetSecret(volumeID string) (string, error) {
|
func (kms *kmipKMS) GetSecret(ctx context.Context, volumeID string) (string, error) {
|
||||||
return "", ErrGetSecretUnsupported
|
return "", ErrGetSecretUnsupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,18 +331,18 @@ type EncryptionKMS interface {
|
|||||||
// EncryptDEK provides a way for a KMS to encrypt a DEK. In case the
|
// EncryptDEK provides a way for a KMS to encrypt a DEK. In case the
|
||||||
// encryption is done transparently inside the KMS service, the
|
// encryption is done transparently inside the KMS service, the
|
||||||
// function can return an unencrypted value.
|
// 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
|
// DecryptDEK provides a way for a KMS to decrypt a DEK. In case the
|
||||||
// encryption is done transparently inside the KMS service, the
|
// encryption is done transparently inside the KMS service, the
|
||||||
// function does not need to do anything except return the encyptedDEK
|
// function does not need to do anything except return the encyptedDEK
|
||||||
// as it was received.
|
// 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
|
// GetSecret allows external key management systems to
|
||||||
// retrieve keys used in EncryptDEK / DecryptDEK to use them
|
// retrieve keys used in EncryptDEK / DecryptDEK to use them
|
||||||
// directly. Example: fscrypt uses this to unlock raw protectors
|
// 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
|
// DEKStoreType describes what DEKStore needs to be configured when using a
|
||||||
@ -364,11 +364,11 @@ const (
|
|||||||
// the KMS can not store passphrases for volumes.
|
// the KMS can not store passphrases for volumes.
|
||||||
type DEKStore interface {
|
type DEKStore interface {
|
||||||
// StoreDEK saves the DEK in the configured store.
|
// 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 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 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
|
// integratedDEK is a DEKStore that can not be configured. Either the KMS does
|
||||||
@ -380,15 +380,15 @@ func (i integratedDEK) RequiresDEKStore() DEKStoreType {
|
|||||||
return DEKStoreIntegrated
|
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
|
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
|
return encyptedDEK, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i integratedDEK) GetSecret(volumeID string) (string, error) {
|
func (i integratedDEK) GetSecret(ctx context.Context, volumeID string) (string, error) {
|
||||||
return "", ErrGetSecretIntegrated
|
return "", ErrGetSecretIntegrated
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,19 +78,19 @@ func (kms secretsKMS) Destroy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// FetchDEK returns passphrase from Kubernetes secrets.
|
// 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
|
return kms.passphrase, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// StoreDEK 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.
|
// 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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveDEK is doing nothing as no new passphrases are saved with
|
// RemoveDEK is doing nothing as no new passphrases are saved with
|
||||||
// secretsKMS.
|
// secretsKMS.
|
||||||
func (kms secretsKMS) RemoveDEK(key string) error {
|
func (kms secretsKMS) RemoveDEK(ctx context.Context, key string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,9 +206,9 @@ type encryptedMetedataDEK struct {
|
|||||||
// the secretsKMS and the volumeID.
|
// the secretsKMS and the volumeID.
|
||||||
// The resulting encryptedDEK contains a JSON with the encrypted DEK and the
|
// The resulting encryptedDEK contains a JSON with the encrypted DEK and the
|
||||||
// nonce that was used for encrypting.
|
// 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
|
// use the passphrase from the secretKMS
|
||||||
passphrase, err := kms.secretsKMS.FetchDEK(volumeID)
|
passphrase, err := kms.secretsKMS.FetchDEK(ctx, volumeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to get passphrase: %w", err)
|
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
|
// DecryptDEK takes the JSON formatted `encryptedMetadataDEK` contents, and it
|
||||||
// fetches secretKMS passphrase to decrypt the DEK.
|
// 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
|
// use the passphrase from the secretKMS
|
||||||
passphrase, err := kms.secretsKMS.FetchDEK(volumeID)
|
passphrase, err := kms.secretsKMS.FetchDEK(ctx, volumeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to get passphrase: %w", err)
|
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
|
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
|
// 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
|
// generateCipher returns a AEAD cipher based on a passphrase and salt
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package kms
|
package kms
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -103,19 +104,21 @@ func TestWorkflowSecretsMetadataKMS(t *testing.T) {
|
|||||||
// plainDEK is the (LUKS) passphrase for the volume
|
// plainDEK is the (LUKS) passphrase for the volume
|
||||||
plainDEK := "usually created with generateNewEncryptionPassphrase()"
|
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.NoError(t, err)
|
||||||
assert.NotEqual(t, "", encryptedDEK)
|
assert.NotEqual(t, "", encryptedDEK)
|
||||||
assert.NotEqual(t, plainDEK, encryptedDEK)
|
assert.NotEqual(t, plainDEK, encryptedDEK)
|
||||||
|
|
||||||
// with an incorrect volumeID, decrypting should fail
|
// 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.Error(t, err)
|
||||||
assert.Equal(t, "", decryptedDEK)
|
assert.Equal(t, "", decryptedDEK)
|
||||||
assert.NotEqual(t, plainDEK, decryptedDEK)
|
assert.NotEqual(t, plainDEK, decryptedDEK)
|
||||||
|
|
||||||
// with the right volumeID, decrypting should return the plainDEK
|
// 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.NoError(t, err)
|
||||||
assert.NotEqual(t, "", decryptedDEK)
|
assert.NotEqual(t, "", decryptedDEK)
|
||||||
assert.Equal(t, plainDEK, decryptedDEK)
|
assert.Equal(t, plainDEK, decryptedDEK)
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package kms
|
package kms
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
@ -395,7 +396,7 @@ func initVaultKMS(args ProviderInitArgs) (EncryptionKMS, error) {
|
|||||||
|
|
||||||
// FetchDEK 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.
|
// 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.
|
// 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)
|
s, _, err := kms.secrets.GetSecret(filepath.Join(kms.vaultPassphrasePath, key), kms.keyContext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -415,7 +416,7 @@ func (kms *vaultKMS) FetchDEK(key string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StoreDEK saves new passphrase in Vault.
|
// 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]interface{}{
|
||||||
"data": map[string]string{
|
"data": map[string]string{
|
||||||
"passphrase": value,
|
"passphrase": value,
|
||||||
@ -433,7 +434,7 @@ func (kms *vaultKMS) StoreDEK(key, value string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RemoveDEK deletes passphrase from Vault.
|
// 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)
|
pathKey := filepath.Join(kms.vaultPassphrasePath, key)
|
||||||
err := kms.secrets.DeleteSecret(pathKey, kms.getDeleteKeyContext())
|
err := kms.secrets.DeleteSecret(pathKey, kms.getDeleteKeyContext())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -459,7 +459,7 @@ func (vtc *vaultTenantConnection) getK8sClient() (*kubernetes.Clientset, error)
|
|||||||
|
|
||||||
// FetchDEK 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.
|
// 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.
|
// Since the second return variable loss.Version is not used, there it is ignored.
|
||||||
s, _, err := vtc.secrets.GetSecret(key, vtc.keyContext)
|
s, _, err := vtc.secrets.GetSecret(key, vtc.keyContext)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -479,7 +479,7 @@ func (vtc *vaultTenantConnection) FetchDEK(key string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StoreDEK saves new passphrase in Vault.
|
// 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]interface{}{
|
||||||
"data": map[string]string{
|
"data": map[string]string{
|
||||||
"passphrase": value,
|
"passphrase": value,
|
||||||
@ -496,7 +496,7 @@ func (vtc *vaultTenantConnection) StoreDEK(key, value string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// RemoveDEK deletes passphrase from Vault.
|
// 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())
|
err := vtc.secrets.DeleteSecret(key, vtc.getDeleteKeyContext())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("delete passphrase at %s request to vault failed: %w", key, err)
|
return fmt.Errorf("delete passphrase at %s request to vault failed: %w", key, err)
|
||||||
|
@ -155,7 +155,7 @@ func (rv *rbdVolume) createCloneFromImage(ctx context.Context, parentVol *rbdVol
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = parentVol.copyEncryptionConfig(&rv.rbdImage, true)
|
err = parentVol.copyEncryptionConfig(ctx, &rv.rbdImage, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to copy encryption config for %q: %w", rv, err)
|
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
|
return errClone
|
||||||
}
|
}
|
||||||
|
|
||||||
err = parentVol.copyEncryptionConfig(&rv.rbdImage, true)
|
err = parentVol.copyEncryptionConfig(ctx, &rv.rbdImage, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to copy encryption config for %q: %w", rv, err)
|
return fmt.Errorf("failed to copy encryption config for %q: %w", rv, err)
|
||||||
}
|
}
|
||||||
|
@ -191,7 +191,7 @@ func (cs *ControllerServer) parseVolCreateRequest(
|
|||||||
// get the owner of the PVC which is required for few encryption related operations
|
// get the owner of the PVC which is required for few encryption related operations
|
||||||
rbdVol.Owner = k8s.GetOwner(req.GetParameters())
|
rbdVol.Owner = k8s.GetOwner(req.GetParameters())
|
||||||
|
|
||||||
err = rbdVol.initKMS(req.GetParameters(), req.GetSecrets())
|
err = rbdVol.initKMS(ctx, req.GetParameters(), req.GetSecrets())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.InvalidArgument, err.Error())
|
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
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = rbdSnap.repairEncryptionConfig(&rbdVol.rbdImage)
|
err = rbdSnap.repairEncryptionConfig(ctx, &rbdVol.rbdImage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -677,7 +677,7 @@ func (cs *ControllerServer) createVolumeFromSnapshot(
|
|||||||
|
|
||||||
log.DebugLog(ctx, "create volume %s from snapshot %s", rbdVol, rbdSnap)
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to copy encryption config for %q: %w", rbdVol, err)
|
return fmt.Errorf("failed to copy encryption config for %q: %w", rbdVol, err)
|
||||||
}
|
}
|
||||||
@ -1229,7 +1229,7 @@ func cloneFromSnapshot(
|
|||||||
}
|
}
|
||||||
defer vol.Destroy()
|
defer vol.Destroy()
|
||||||
|
|
||||||
err = rbdVol.copyEncryptionConfig(&vol.rbdImage, false)
|
err = rbdVol.copyEncryptionConfig(ctx, &vol.rbdImage, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
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 {
|
if err != nil {
|
||||||
log.ErrorLog(ctx, "failed to copy encryption "+
|
log.ErrorLog(ctx, "failed to copy encryption "+
|
||||||
"config for %q: %v", cloneRbd, err)
|
"config for %q: %v", cloneRbd, err)
|
||||||
|
@ -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 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.
|
// - the RBD image will be marked to support encryption in its metadata.
|
||||||
func (ri *rbdImage) setupBlockEncryption(ctx context.Context) error {
|
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 {
|
if err != nil {
|
||||||
log.ErrorLog(ctx, "failed to save encryption passphrase for "+
|
log.ErrorLog(ctx, "failed to save encryption passphrase for "+
|
||||||
"image %s: %s", ri, err)
|
"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
|
// destination rbdImage's VolumeEncryption object which needs to be initialized
|
||||||
// beforehand and is possibly different from the source VolumeEncryption
|
// beforehand and is possibly different from the source VolumeEncryption
|
||||||
// (Usecase: Restoring snapshot into a storageclass with different encryption config).
|
// (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.
|
// nothing to do if parent image is not encrypted.
|
||||||
if !ri.isBlockEncrypted() && !ri.isFileEncrypted() {
|
if !ri.isBlockEncrypted() && !ri.isFileEncrypted() {
|
||||||
return nil
|
return nil
|
||||||
@ -157,7 +157,7 @@ func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool)
|
|||||||
|
|
||||||
if ri.isBlockEncrypted() {
|
if ri.isBlockEncrypted() {
|
||||||
// get the unencrypted passphrase
|
// get the unencrypted passphrase
|
||||||
passphrase, err := ri.blockEncryption.GetCryptoPassphrase(ri.VolID)
|
passphrase, err := ri.blockEncryption.GetCryptoPassphrase(ctx, ri.VolID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to fetch passphrase for %q: %w",
|
return fmt.Errorf("failed to fetch passphrase for %q: %w",
|
||||||
ri, err)
|
ri, err)
|
||||||
@ -171,7 +171,7 @@ func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// re-encrypt the plain passphrase for the cloned volume
|
// 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 {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to store passphrase for %q: %w",
|
return fmt.Errorf("failed to store passphrase for %q: %w",
|
||||||
cp, err)
|
cp, err)
|
||||||
@ -182,7 +182,7 @@ func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool)
|
|||||||
var err error
|
var err error
|
||||||
cp.fileEncryption, err = util.NewVolumeEncryption(ri.fileEncryption.GetID(), ri.fileEncryption.KMS)
|
cp.fileEncryption, err = util.NewVolumeEncryption(ri.fileEncryption.GetID(), ri.fileEncryption.KMS)
|
||||||
if errors.Is(err, util.ErrDEKStoreNeeded) {
|
if errors.Is(err, util.ErrDEKStoreNeeded) {
|
||||||
_, err := ri.fileEncryption.KMS.GetSecret("")
|
_, err := ri.fileEncryption.KMS.GetSecret(ctx, "")
|
||||||
if errors.Is(err, kmsapi.ErrGetSecretUnsupported) {
|
if errors.Is(err, kmsapi.ErrGetSecretUnsupported) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -191,14 +191,14 @@ func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool)
|
|||||||
|
|
||||||
if ri.isFileEncrypted() && ri.fileEncryption.KMS.RequiresDEKStore() == kmsapi.DEKStoreIntegrated {
|
if ri.isFileEncrypted() && ri.fileEncryption.KMS.RequiresDEKStore() == kmsapi.DEKStoreIntegrated {
|
||||||
// get the unencrypted passphrase
|
// get the unencrypted passphrase
|
||||||
passphrase, err := ri.fileEncryption.GetCryptoPassphrase(ri.VolID)
|
passphrase, err := ri.fileEncryption.GetCryptoPassphrase(ctx, ri.VolID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to fetch passphrase for %q: %w",
|
return fmt.Errorf("failed to fetch passphrase for %q: %w",
|
||||||
ri, err)
|
ri, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// re-encrypt the plain passphrase for the cloned volume
|
// 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 {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to store passphrase for %q: %w",
|
return fmt.Errorf("failed to store passphrase for %q: %w",
|
||||||
cp, err)
|
cp, err)
|
||||||
@ -223,7 +223,7 @@ func (ri *rbdImage) copyEncryptionConfig(cp *rbdImage, copyOnlyPassphrase bool)
|
|||||||
|
|
||||||
// repairEncryptionConfig checks the encryption state of the current rbdImage,
|
// repairEncryptionConfig checks the encryption state of the current rbdImage,
|
||||||
// and makes sure that the destination rbdImage has the same configuration.
|
// 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() {
|
if !ri.isBlockEncrypted() && !ri.isFileEncrypted() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -236,14 +236,14 @@ func (ri *rbdImage) repairEncryptionConfig(dest *rbdImage) error {
|
|||||||
dest.conn = ri.conn.Copy()
|
dest.conn = ri.conn.Copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
return ri.copyEncryptionConfig(dest, true)
|
return ri.copyEncryptionConfig(ctx, dest, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ri *rbdImage) encryptDevice(ctx context.Context, devicePath string) error {
|
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 {
|
if err != nil {
|
||||||
log.ErrorLog(ctx, "failed to get crypto passphrase for %s: %v",
|
log.ErrorLog(ctx, "failed to get crypto passphrase for %s: %v",
|
||||||
ri, err)
|
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) {
|
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 {
|
if err != nil {
|
||||||
log.ErrorLog(ctx, "failed to get passphrase for encrypted device %s: %v",
|
log.ErrorLog(ctx, "failed to get passphrase for encrypted device %s: %v",
|
||||||
rv, err)
|
rv, err)
|
||||||
@ -300,7 +300,7 @@ func (rv *rbdVolume) openEncryptedDevice(ctx context.Context, devicePath string)
|
|||||||
return mapperFilePath, nil
|
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)
|
kmsID, encType, err := ParseEncryptionOpts(volOptions, rbdDefaultEncryptionType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -310,7 +310,7 @@ func (ri *rbdImage) initKMS(volOptions, credentials map[string]string) error {
|
|||||||
case util.EncryptionTypeBlock:
|
case util.EncryptionTypeBlock:
|
||||||
err = ri.configureBlockEncryption(kmsID, credentials)
|
err = ri.configureBlockEncryption(kmsID, credentials)
|
||||||
case util.EncryptionTypeFile:
|
case util.EncryptionTypeFile:
|
||||||
err = ri.configureFileEncryption(kmsID, credentials)
|
err = ri.configureFileEncryption(ctx, kmsID, credentials)
|
||||||
case util.EncryptionTypeInvalid:
|
case util.EncryptionTypeInvalid:
|
||||||
return fmt.Errorf("invalid encryption type")
|
return fmt.Errorf("invalid encryption type")
|
||||||
case util.EncryptionTypeNone:
|
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
|
// configureBlockDeviceEncryption sets up the VolumeEncryption for this rbdImage. Once
|
||||||
// configured, use isEncrypted() to see if the volume supports encryption.
|
// 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)
|
kms, err := kmsapi.GetKMS(ri.Owner, kmsID, credentials)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -390,7 +390,7 @@ func (ri *rbdImage) configureFileEncryption(kmsID string, credentials map[string
|
|||||||
// store. Since not all "metadata" KMS support
|
// store. Since not all "metadata" KMS support
|
||||||
// GetSecret, test for support here. Postpone any
|
// GetSecret, test for support here. Postpone any
|
||||||
// other error handling
|
// other error handling
|
||||||
_, err := ri.fileEncryption.KMS.GetSecret("")
|
_, err := ri.fileEncryption.KMS.GetSecret(ctx, "")
|
||||||
if errors.Is(err, kmsapi.ErrGetSecretUnsupported) {
|
if errors.Is(err, kmsapi.ErrGetSecretUnsupported) {
|
||||||
return err
|
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.
|
// 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 == "" {
|
if ri.VolID == "" {
|
||||||
return fmt.Errorf("BUG: %q does not have VolID set, call "+
|
return fmt.Errorf("BUG: %q does not have VolID set, call "+
|
||||||
"stack: %s", ri, util.CallStack())
|
"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.
|
// 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 == "" {
|
if ri.VolID == "" {
|
||||||
return "", fmt.Errorf("BUG: %q does not have VolID set, call "+
|
return "", fmt.Errorf("BUG: %q does not have VolID set, call "+
|
||||||
"stack: %s", ri, util.CallStack())
|
"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
|
// RemoveDEK does not need to remove the DEK from the metadata, the image is
|
||||||
// most likely getting removed.
|
// most likely getting removed.
|
||||||
func (ri *rbdImage) RemoveDEK(volumeID string) error {
|
func (ri *rbdImage) RemoveDEK(ctx context.Context, volumeID string) error {
|
||||||
if ri.VolID == "" {
|
if ri.VolID == "" {
|
||||||
return fmt.Errorf("BUG: %q does not have VolID set, call "+
|
return fmt.Errorf("BUG: %q does not have VolID set, call "+
|
||||||
"stack: %s", ri, util.CallStack())
|
"stack: %s", ri, util.CallStack())
|
||||||
|
@ -232,7 +232,7 @@ func (ns *NodeServer) populateRbdVol(
|
|||||||
return nil, status.Error(codes.Internal, err.Error())
|
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 {
|
if err != nil {
|
||||||
return nil, status.Error(codes.Internal, err.Error())
|
return nil, status.Error(codes.Internal, err.Error())
|
||||||
}
|
}
|
||||||
|
@ -334,7 +334,7 @@ func (rv *rbdVolume) Exists(ctx context.Context, parentVol *rbdVolume) (bool, er
|
|||||||
}
|
}
|
||||||
|
|
||||||
if parentVol != nil {
|
if parentVol != nil {
|
||||||
err = parentVol.copyEncryptionConfig(&rv.rbdImage, true)
|
err = parentVol.copyEncryptionConfig(ctx, &rv.rbdImage, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ErrorLog(ctx, err.Error())
|
log.ErrorLog(ctx, err.Error())
|
||||||
|
|
||||||
|
@ -635,14 +635,14 @@ func (ri *rbdImage) deleteImage(ctx context.Context) error {
|
|||||||
|
|
||||||
if ri.isBlockEncrypted() {
|
if ri.isBlockEncrypted() {
|
||||||
log.DebugLog(ctx, "rbd: going to remove DEK for %q (block encryption)", ri)
|
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)
|
log.WarningLog(ctx, "failed to clean the passphrase for volume %s (block encryption): %s", ri.VolID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ri.isFileEncrypted() {
|
if ri.isFileEncrypted() {
|
||||||
log.DebugLog(ctx, "rbd: going to remove DEK for %q (file encryption)", ri)
|
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)
|
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 {
|
if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == util.EncryptionTypeFile {
|
||||||
err = rbdSnap.configureFileEncryption(imageAttributes.KmsID, secrets)
|
err = rbdSnap.configureFileEncryption(ctx, imageAttributes.KmsID, secrets)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to configure file encryption for "+
|
return fmt.Errorf("failed to configure file encryption for "+
|
||||||
"%q: %w", rbdSnap, err)
|
"%q: %w", rbdSnap, err)
|
||||||
@ -1133,7 +1133,7 @@ func generateVolumeFromVolumeID(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == util.EncryptionTypeFile {
|
if imageAttributes.KmsID != "" && imageAttributes.EncryptionType == util.EncryptionTypeFile {
|
||||||
err = rbdVol.configureFileEncryption(imageAttributes.KmsID, secrets)
|
err = rbdVol.configureFileEncryption(ctx, imageAttributes.KmsID, secrets)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return rbdVol, err
|
return rbdVol, err
|
||||||
}
|
}
|
||||||
|
@ -189,12 +189,12 @@ func (ve *VolumeEncryption) Destroy() {
|
|||||||
|
|
||||||
// RemoveDEK deletes the DEK for a particular volumeID from the DEKStore linked
|
// RemoveDEK deletes the DEK for a particular volumeID from the DEKStore linked
|
||||||
// with this VolumeEncryption instance.
|
// 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 {
|
if ve.dekStore == nil {
|
||||||
return ErrDEKStoreNotFound
|
return ErrDEKStoreNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
return ve.dekStore.RemoveDEK(volumeID)
|
return ve.dekStore.RemoveDEK(ctx, volumeID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ve *VolumeEncryption) GetID() string {
|
func (ve *VolumeEncryption) GetID() string {
|
||||||
@ -203,13 +203,13 @@ func (ve *VolumeEncryption) GetID() string {
|
|||||||
|
|
||||||
// StoreCryptoPassphrase takes an unencrypted passphrase, encrypts it and saves
|
// StoreCryptoPassphrase takes an unencrypted passphrase, encrypts it and saves
|
||||||
// it in the DEKStore.
|
// it in the DEKStore.
|
||||||
func (ve *VolumeEncryption) StoreCryptoPassphrase(volumeID, passphrase string) error {
|
func (ve *VolumeEncryption) StoreCryptoPassphrase(ctx context.Context, volumeID, passphrase string) error {
|
||||||
encryptedPassphrase, err := ve.KMS.EncryptDEK(volumeID, passphrase)
|
encryptedPassphrase, err := ve.KMS.EncryptDEK(ctx, volumeID, passphrase)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed encrypt the passphrase for %s: %w", volumeID, err)
|
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 {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to save the passphrase for %s: %w", volumeID, err)
|
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.
|
// 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)
|
passphrase, err := generateNewEncryptionPassphrase(length)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to generate passphrase for %s: %w", volumeID, err)
|
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.
|
// GetCryptoPassphrase Retrieves passphrase to encrypt volume.
|
||||||
func (ve *VolumeEncryption) GetCryptoPassphrase(volumeID string) (string, error) {
|
func (ve *VolumeEncryption) GetCryptoPassphrase(ctx context.Context, volumeID string) (string, error) {
|
||||||
passphrase, err := ve.dekStore.FetchDEK(volumeID)
|
passphrase, err := ve.dekStore.FetchDEK(ctx, volumeID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ve.KMS.DecryptDEK(volumeID, passphrase)
|
return ve.KMS.DecryptDEK(ctx, volumeID, passphrase)
|
||||||
}
|
}
|
||||||
|
|
||||||
// generateNewEncryptionPassphrase generates a random passphrase for encryption.
|
// generateNewEncryptionPassphrase generates a random passphrase for encryption.
|
||||||
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -55,11 +56,12 @@ func TestKMSWorkflow(t *testing.T) {
|
|||||||
assert.Equal(t, kms.DefaultKMSType, ve.GetID())
|
assert.Equal(t, kms.DefaultKMSType, ve.GetID())
|
||||||
|
|
||||||
volumeID := "volume-id"
|
volumeID := "volume-id"
|
||||||
|
ctx := context.TODO()
|
||||||
|
|
||||||
err = ve.StoreNewCryptoPassphrase(volumeID, defaultEncryptionPassphraseSize)
|
err = ve.StoreNewCryptoPassphrase(ctx, volumeID, defaultEncryptionPassphraseSize)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
|
|
||||||
passphrase, err := ve.GetCryptoPassphrase(volumeID)
|
passphrase, err := ve.GetCryptoPassphrase(ctx, volumeID)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, secrets["encryptionPassphrase"], passphrase)
|
assert.Equal(t, secrets["encryptionPassphrase"], passphrase)
|
||||||
}
|
}
|
||||||
|
@ -76,14 +76,14 @@ func getPassphrase(ctx context.Context, encryption util.VolumeEncryption, volID
|
|||||||
|
|
||||||
switch encryption.KMS.RequiresDEKStore() {
|
switch encryption.KMS.RequiresDEKStore() {
|
||||||
case kms.DEKStoreIntegrated:
|
case kms.DEKStoreIntegrated:
|
||||||
passphrase, err = encryption.GetCryptoPassphrase(volID)
|
passphrase, err = encryption.GetCryptoPassphrase(ctx, volID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ErrorLog(ctx, "fscrypt: failed to get passphrase from KMS: %v", err)
|
log.ErrorLog(ctx, "fscrypt: failed to get passphrase from KMS: %v", err)
|
||||||
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
case kms.DEKStoreMetadata:
|
case kms.DEKStoreMetadata:
|
||||||
passphrase, err = encryption.KMS.GetSecret(volID)
|
passphrase, err = encryption.KMS.GetSecret(ctx, volID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.ErrorLog(ctx, "fscrypt: failed to GetSecret: %v", err)
|
log.ErrorLog(ctx, "fscrypt: failed to GetSecret: %v", err)
|
||||||
|
|
||||||
@ -453,7 +453,7 @@ func Unlock(
|
|||||||
if !kernelPolicyExists && !metadataDirExists {
|
if !kernelPolicyExists && !metadataDirExists {
|
||||||
log.DebugLog(ctx, "fscrypt: Creating new protector and policy")
|
log.DebugLog(ctx, "fscrypt: Creating new protector and policy")
|
||||||
if volEncryption.KMS.RequiresDEKStore() == kms.DEKStoreIntegrated {
|
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)
|
log.ErrorLog(ctx, "fscrypt: store new crypto passphrase failed: %v", err)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
@ -14,6 +14,7 @@ limitations under the License.
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -34,7 +35,7 @@ func TestGetPassphraseFromKMS(t *testing.T) {
|
|||||||
|
|
||||||
volEnc, err := NewVolumeEncryption(provider.UniqueID, kms)
|
volEnc, err := NewVolumeEncryption(provider.UniqueID, kms)
|
||||||
if errors.Is(err, ErrDEKStoreNeeded) {
|
if errors.Is(err, ErrDEKStoreNeeded) {
|
||||||
_, err = volEnc.KMS.GetSecret("")
|
_, err = volEnc.KMS.GetSecret(context.TODO(), "")
|
||||||
if errors.Is(err, kmsapi.ErrGetSecretUnsupported) {
|
if errors.Is(err, kmsapi.ErrGetSecretUnsupported) {
|
||||||
continue // currently unsupported by fscrypt integration
|
continue // currently unsupported by fscrypt integration
|
||||||
}
|
}
|
||||||
@ -45,7 +46,7 @@ func TestGetPassphraseFromKMS(t *testing.T) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
secret, err := kms.GetSecret("")
|
secret, err := kms.GetSecret(context.TODO(), "")
|
||||||
assert.NoError(t, err, provider.UniqueID)
|
assert.NoError(t, err, provider.UniqueID)
|
||||||
assert.NotEmpty(t, secret, provider.UniqueID)
|
assert.NotEmpty(t, secret, provider.UniqueID)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user