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 <marcel.lauhoff@suse.com>
This commit is contained in:
Marcel Lauhoff 2022-03-11 19:51:18 +01:00 committed by mergify[bot]
parent 0599089de0
commit cb02a9beb9
4 changed files with 28 additions and 0 deletions

View File

@ -226,3 +226,7 @@ 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) {
return "", ErrGetSecretUnsupported
}

View File

@ -242,3 +242,7 @@ 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) {
return "", ErrGetSecretUnsupported
}

View File

@ -19,6 +19,7 @@ package kms
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"os" "os"
@ -53,6 +54,11 @@ const (
DefaultKMSType = "default" 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. // GetKMS returns an instance of Key Management System.
// //
// - tenant is the owner of the Volume, used to fetch the Vault Token from the // - 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 // 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(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 // 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 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 // getKeys takes a map that uses strings for keys and returns a slice with the
// keys. // keys.
func getKeys(m map[string]interface{}) []string { func getKeys(m map[string]interface{}) []string {

View File

@ -263,6 +263,11 @@ func (kms secretsMetadataKMS) DecryptDEK(volumeID, encryptedDEK string) (string,
return string(dek), nil 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 // generateCipher returns a AEAD cipher based on a passphrase and salt
// (volumeID). The cipher can then be used to encrypt/decrypt the DEK. // (volumeID). The cipher can then be used to encrypt/decrypt the DEK.
func generateCipher(passphrase, salt string) (cipher.AEAD, error) { func generateCipher(passphrase, salt string) (cipher.AEAD, error) {