package keymanager import ( "context" "crypto/rand" "fmt" wrapping "github.com/hashicorp/go-kms-wrapping/v2" "github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2" ) var _ KeyManager = (*PassthroughKeyManager)(nil) type PassthroughKeyManager struct { wrapper *aead.Wrapper } // NewPassthroughKeyManager returns a new instance of the Kube encryption key. // If a key is provided, it will be used as the encryption key for the wrapper, // otherwise one will be generated. func NewPassthroughKeyManager(ctx context.Context, key []byte) (*PassthroughKeyManager, error) { var rootKey []byte = nil switch len(key) { case 0: newKey := make([]byte, 32) _, err := rand.Read(newKey) if err != nil { return nil, err } rootKey = newKey case 32: rootKey = key default: return nil, fmt.Errorf("invalid key size, should be 32, got %d", len(key)) } wrapper := aead.NewWrapper() if _, err := wrapper.SetConfig(ctx, wrapping.WithConfigMap(map[string]string{"key_id": KeyID})); err != nil { return nil, err } if err := wrapper.SetAesGcmKeyBytes(rootKey); err != nil { return nil, err } k := &PassthroughKeyManager{ wrapper: wrapper, } return k, nil } // Wrapper returns the manager's wrapper for key operations. func (w *PassthroughKeyManager) Wrapper() wrapping.Wrapper { return w.wrapper } // RetrievalToken returns the key that was used on the wrapper since this key // manager is simply a passthrough and does not provide a mechanism to abstract // this key. func (w *PassthroughKeyManager) RetrievalToken(ctx context.Context) ([]byte, error) { if w.wrapper == nil { return nil, fmt.Errorf("unable to get wrapper for token retrieval") } return w.wrapper.KeyBytes(ctx) }