From cb02a9beb9d30b479323f3e7ff21def5d7249042 Mon Sep 17 00:00:00 2001 From: Marcel Lauhoff Date: Fri, 11 Mar 2022 19:51:18 +0100 Subject: [PATCH] kms: Add GetSecret() to metadata KMS Add GetSecret() to allow direct access to passphrases without KDF and wrapping by a DEKStore. This will be used by fscrypt, which has its own KDF and wrapping. It will allow users to take a k8s secret, for example, and use that directly as a password in fscrypt. Signed-off-by: Marcel Lauhoff --- internal/kms/aws_metadata.go | 4 ++++ internal/kms/keyprotect.go | 4 ++++ internal/kms/kms.go | 15 +++++++++++++++ internal/kms/secretskms.go | 5 +++++ 4 files changed, 28 insertions(+) diff --git a/internal/kms/aws_metadata.go b/internal/kms/aws_metadata.go index f77bce6f3..f74a5f581 100644 --- a/internal/kms/aws_metadata.go +++ b/internal/kms/aws_metadata.go @@ -226,3 +226,7 @@ func (kms *awsMetadataKMS) DecryptDEK(volumeID, encryptedDEK string) (string, er return string(result.Plaintext), nil } + +func (kms *awsMetadataKMS) GetSecret(volumeID string) (string, error) { + return "", ErrGetSecretUnsupported +} diff --git a/internal/kms/keyprotect.go b/internal/kms/keyprotect.go index fdc795053..d020c75b5 100644 --- a/internal/kms/keyprotect.go +++ b/internal/kms/keyprotect.go @@ -242,3 +242,7 @@ func (kms *keyProtectKMS) DecryptDEK(volumeID, encryptedDEK string) (string, err return string(result), nil } + +func (kms *keyProtectKMS) GetSecret(volumeID string) (string, error) { + return "", ErrGetSecretUnsupported +} diff --git a/internal/kms/kms.go b/internal/kms/kms.go index a42e6d0df..82eadfd3e 100644 --- a/internal/kms/kms.go +++ b/internal/kms/kms.go @@ -19,6 +19,7 @@ package kms import ( "context" "encoding/json" + "errors" "fmt" "os" @@ -53,6 +54,11 @@ const ( DefaultKMSType = "default" ) +var ( + ErrGetSecretUnsupported = errors.New("KMS does not support access to user provided secret") + ErrGetSecretIntegrated = errors.New("integrated DEK stores do not allow GetSecret") +) + // GetKMS returns an instance of Key Management System. // // - tenant is the owner of the Volume, used to fetch the Vault Token from the @@ -332,6 +338,11 @@ type EncryptionKMS interface { // function does not need to do anything except return the encyptedDEK // as it was received. DecryptDEK(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) } // DEKStoreType describes what DEKStore needs to be configured when using a @@ -377,6 +388,10 @@ func (i integratedDEK) DecryptDEK(volumeID, encyptedDEK string) (string, error) return encyptedDEK, nil } +func (i integratedDEK) GetSecret(volumeID string) (string, error) { + return "", ErrGetSecretIntegrated +} + // getKeys takes a map that uses strings for keys and returns a slice with the // keys. func getKeys(m map[string]interface{}) []string { diff --git a/internal/kms/secretskms.go b/internal/kms/secretskms.go index 6fb479310..4b4866c79 100644 --- a/internal/kms/secretskms.go +++ b/internal/kms/secretskms.go @@ -263,6 +263,11 @@ func (kms secretsMetadataKMS) DecryptDEK(volumeID, encryptedDEK string) (string, return string(dek), nil } +func (kms secretsMetadataKMS) GetSecret(volumeID string) (string, error) { + // use the passphrase from the secretKMS + return kms.secretsKMS.FetchDEK(volumeID) +} + // generateCipher returns a AEAD cipher based on a passphrase and salt // (volumeID). The cipher can then be used to encrypt/decrypt the DEK. func generateCipher(passphrase, salt string) (cipher.AEAD, error) {