mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-29 01:32:33 +00:00
* Seal HA: Use new SealWrappedValue type to abstract seal wrapped values Introduce SealWrappedValue to abstract seal wrapped values. Make SealWrappedValue capable of marshalling into a BlobInfo, when there is plaintext or a single encryption, or to a custom serialization consisting of a header, length and a marshalled MultiWrapValue protobuf. * Vault-13769: Support configuring and using multiple seals for unsealing * Make sealWrapBackend start using multiple seals * Make seal.Access no longer implement wrapping.Wrapper. Instead, add the Encrypt and Decrypt methods to the Access interface. * Make raft snapshot system use funcs SealWrapValue + UnsealWrapValue. Move the snapshot.Sealer implementation to the vault package to avoid circular imports. * Update sealWrapBackend to use multiple seals for encryption. Use all the encryption wrappers when storing seal wrapped values. Try do decrypt using the highest priority wrapper, but try all combinations of encrypted values and wrappers if necessary. * Allow the use of multiple seals for entropy augmentation Add seal_name variable in entropy stanza Add new MultiSourcer to accommodate the new entropy augmentation behavior. * Individually health check each wrapper, and add a sys/seal-backend-status endpoint. * Address a race, and also a failed test mock that I didn't catch * Track partial wrapping failures... ... where one or more but not all access.Encrypts fail for a given write. Note these failures by adding a time ordered UUID storage entry containing the path in a special subdirectory of root storage. Adds a callback pattern to accomplish this, with certain high value writes like initial barrier key storage not allowing a partial failure. The followup work would be to detect return to health and iterate through these storage entries, rewrapping. * Add new data structure to track seal config generation (#4492) * Add new data structure to track seal config generation * Remove import cycle * Fix undefined variable errors * update comment * Update setSeal response * Fix setSealResponse in operator_diagnose * Scope the wrapper health check locks individually (#4491) * Refactor setSeal function in server.go. (#4505) Refactor setSeal function in server.go. * Decouple CreateSecureRandomReaderFunc from seal package. Instead of using a list of seal.SealInfo structs, make CreateSecureRandomReaderFunc use a list of new EntropySourcerInfo structs. This brakes the denpency of package configutil on the seal package. * Move SealGenerationInfo tracking to the seal Access. * Move SealGenerationInfo tracking to the seal Access. The SealGenerationInfo is now kept track by a Seal's Access instead of by the Config object. The access implementation now records the correct generation number on seal wrapped values. * Only store and read SealGenerationInfo if VAULT_ENABLE_SEAL_HA_BETA is true. * Add MultiWrapValue protobuf message MultiWrapValue can be used to keep track of different encryptions of a value. --------- Co-authored-by: Victor Rodriguez <vrizo@hashicorp.com> * Use generation to determine if a seal wrapped value is up-to-date. (#4542) * Add logging to seal Access implementation. * Seal HA buf format run (#4561) * Run buf format. * Add buf.lock to ensure go-kms-wrapping module is imported. * Vault-18958: Add unit tests for config checks * Add safety logic for seal configuration changes * Revert "Add safety logic for seal configuration changes" This reverts commit 7fec48035a5cf274e5a4d98901716d08d766ce90. * changes and tests for checking seal config * add ent tests * remove check for empty name and add type into test cases * add error message for empty name * fix no seals test --------- Co-authored-by: divyapola5 <divya@hashicorp.com> * Handle migrations between single-wrapper and multi-wrapper autoSeals * Extract method SetPhysicalSealConfig. * Extract function physicalSealConfig. The extracted function is the only code now reading SealConfig entries from storage. * Extract function setPhysicalSealConfig. The extracted function is the only code now writing SealConfig entries from storage (except for migration from the old recovery config path). * Move SealConfig to new file vault/seal_config.go. * Add SealConfigType quasy-enumeration. SealConfigType is to serve as the typed values for field SealConfig.Type. * Rename Seal.RecoveryType to RecoverySealConfigType. Make RecoverySealConfigType return a SealConfigType instead of a string. * Rename Seal.BarrierType to BarrierSealConfigType. Make BarrierSealConfigType return a SealConfigType. Remove seal.SealType (really a two-step rename to SealConfigType). * Add Seal methods ClearBarrierConfig and ClearRecoveryConfig. * Handle autoseal <-> multiseal migrations. While going between single-wrapper and multiple-wrapper autoseals are not migrations that require an unwrap seal (such as going from shamir to autoseal), the stored "barrier" SealConfig needs to be updated in these cases. Specifically, the value of SealConfg.Type is "multiseal" for autoSeals that have more than one wrapper; on the other hand, for autoseals with a single wrapper, SealConfig.Type is the type of the wrapper. * Remove error return value from NewAutoSeal constructor. * Automatically rewrap partially seal wrapped values on an interval * Add in rewrapping of partially wrapped values on an interval, regardless of seal health/status. * Don't set SealGenerationInfo Rewrapped flag in the partial rewrap call. * Unexport the SealGenerationInfo's Rewrapped field, add a mutex to it for thread safe access, and add accessor methods for it. * Add a success callback to the manual seal rewrap process that updates the SealGenerationInfo's rewrapped field. This is done via a callback to avoid an import cycle in the SealRewrap code. * Fix a failing seal wrap backend test which was broken by the unexporting of SealGenerationInfo's Rewrapped field. * Nil check the seal rewrap success callback before calling it. * Change SealGenerationInfo rewrapped parameter to an atomic.Bool rather than a sync.RWMutex for simplicity and performance. * Add nil check for SealAccess before updating SealGenerationInfo rewrapped status during seal rewrap call. * Update partial rewrap check interval from 10 seconds to 1 minute. * Update a reference to SealGenerationInfo Rewrapped field to use new getter method. * Fix up some data raciness in partial rewrapping. * Account for possibly nil storage entry when retrieving partially wrapped value. * Allow multi-wrapper autoSeals to include disabled seal wrappers. * Restore propagation of wrapper configuration errors by setSeal. Function setSeal is meant to propagate non KeyNotFound errors returned by calls to configutil.ConfigureWrapper. * Remove unused Access methods SetConfig and Type. * Allow multi-wrapper autoSeals to include disabled seal wrappers. Make it possible for an autoSeal that uses multiple wrappers to include disabled wrappers that can be used to decrypt entries, but are skipped for encryption. e an unwrapSeal when there are disabled seals. * Fix bug with not providing name (#4580) * add suffix to name defaults * add comment * only change name for disabled seal * Only attempt to rewrap partial values when all seals are healthy. * Only attempt to rewrap partial values when all seals are healthy. * Change logging level from info to debug for notice about rewrap skipping based on seal health. * Remove stale TODOs and commented out code. --------- Co-authored-by: rculpepper <rculpepper@hashicorp.com> Co-authored-by: Larroyo <95649169+DeLuci@users.noreply.github.com> Co-authored-by: Scott G. Miller <smiller@hashicorp.com> Co-authored-by: Divya Pola <87338962+divyapola5@users.noreply.github.com> Co-authored-by: Matt Schultz <matt.schultz@hashicorp.com> Co-authored-by: divyapola5 <divya@hashicorp.com> Co-authored-by: Rachel Culpepper <84159930+rculpepper@users.noreply.github.com>
440 lines
13 KiB
Go
440 lines
13 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package configutil
|
|
|
|
import (
|
|
"context"
|
|
"crypto/rand"
|
|
"errors"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/go-kms-wrapping/entropy/v2"
|
|
|
|
"github.com/hashicorp/errwrap"
|
|
"github.com/hashicorp/go-hclog"
|
|
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
|
|
aeadwrapper "github.com/hashicorp/go-kms-wrapping/wrappers/aead/v2"
|
|
"github.com/hashicorp/go-kms-wrapping/wrappers/alicloudkms/v2"
|
|
"github.com/hashicorp/go-kms-wrapping/wrappers/awskms/v2"
|
|
"github.com/hashicorp/go-kms-wrapping/wrappers/azurekeyvault/v2"
|
|
"github.com/hashicorp/go-kms-wrapping/wrappers/gcpckms/v2"
|
|
"github.com/hashicorp/go-kms-wrapping/wrappers/ocikms/v2"
|
|
"github.com/hashicorp/go-kms-wrapping/wrappers/transit/v2"
|
|
"github.com/hashicorp/go-multierror"
|
|
"github.com/hashicorp/go-secure-stdlib/parseutil"
|
|
"github.com/hashicorp/hcl"
|
|
"github.com/hashicorp/hcl/hcl/ast"
|
|
"github.com/hashicorp/vault/sdk/logical"
|
|
)
|
|
|
|
var (
|
|
ConfigureWrapper = configureWrapper
|
|
CreateSecureRandomReaderFunc = createSecureRandomReader
|
|
GetEnvConfigFunc = getEnvConfig
|
|
)
|
|
|
|
// Entropy contains Entropy configuration for the server
|
|
type EntropyMode int
|
|
|
|
const (
|
|
EntropyUnknown EntropyMode = iota
|
|
EntropyAugmentation
|
|
)
|
|
|
|
type Entropy struct {
|
|
Mode EntropyMode
|
|
SealName string
|
|
}
|
|
|
|
type EntropySourcerInfo struct {
|
|
Sourcer entropy.Sourcer
|
|
Name string
|
|
}
|
|
|
|
// KMS contains KMS configuration for the server
|
|
type KMS struct {
|
|
UnusedKeys []string `hcl:",unusedKeys"`
|
|
Type string
|
|
// Purpose can be used to allow a string-based specification of what this
|
|
// KMS is designated for, in situations where we want to allow more than
|
|
// one KMS to be specified
|
|
Purpose []string `hcl:"-"`
|
|
|
|
Disabled bool
|
|
Config map[string]string
|
|
|
|
Priority int `hcl:"priority"`
|
|
Name string `hcl:"name"`
|
|
}
|
|
|
|
func (k *KMS) GoString() string {
|
|
return fmt.Sprintf("*%#v", *k)
|
|
}
|
|
|
|
func parseKMS(result *[]*KMS, list *ast.ObjectList, blockName string, maxKMS int) error {
|
|
if len(list.Items) > maxKMS {
|
|
return fmt.Errorf("only %d or less %q blocks are permitted", maxKMS, blockName)
|
|
}
|
|
|
|
seals := make([]*KMS, 0, len(list.Items))
|
|
for _, item := range list.Items {
|
|
key := blockName
|
|
if len(item.Keys) > 0 {
|
|
key = item.Keys[0].Token.Value().(string)
|
|
}
|
|
|
|
// We first decode into a map[string]interface{} because purpose isn't
|
|
// necessarily a string. Then we migrate everything else over to
|
|
// map[string]string and error if it doesn't work.
|
|
var m map[string]interface{}
|
|
if err := hcl.DecodeObject(&m, item.Val); err != nil {
|
|
return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key))
|
|
}
|
|
|
|
var purpose []string
|
|
var err error
|
|
if v, ok := m["purpose"]; ok {
|
|
if purpose, err = parseutil.ParseCommaStringSlice(v); err != nil {
|
|
return multierror.Prefix(fmt.Errorf("unable to parse 'purpose' in kms type %q: %w", key, err), fmt.Sprintf("%s.%s:", blockName, key))
|
|
}
|
|
for i, p := range purpose {
|
|
purpose[i] = strings.ToLower(p)
|
|
}
|
|
delete(m, "purpose")
|
|
}
|
|
|
|
var disabled bool
|
|
if v, ok := m["disabled"]; ok {
|
|
disabled, err = parseutil.ParseBool(v)
|
|
if err != nil {
|
|
return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key))
|
|
}
|
|
delete(m, "disabled")
|
|
}
|
|
|
|
var priority int
|
|
if v, ok := m["priority"]; ok {
|
|
priority, err = parseutil.SafeParseInt(v)
|
|
if err != nil {
|
|
return multierror.Prefix(fmt.Errorf("unable to parse 'priority' in kms type %q: %w", key, err), fmt.Sprintf("%s.%s", blockName, key))
|
|
}
|
|
delete(m, "priority")
|
|
|
|
if priority < 1 {
|
|
return multierror.Prefix(fmt.Errorf("invalid priority in kms type %q: %d", key, priority), fmt.Sprintf("%s.%s", blockName, key))
|
|
}
|
|
}
|
|
|
|
name := strings.ToLower(key)
|
|
// ensure that seals of the same type will have unique names for seal migration
|
|
if disabled {
|
|
name += "-disabled"
|
|
}
|
|
if v, ok := m["name"]; ok {
|
|
name, ok = v.(string)
|
|
if !ok {
|
|
return multierror.Prefix(fmt.Errorf("unable to parse 'name' in kms type %q: unexpected type %T", key, v), fmt.Sprintf("%s.%s", blockName, key))
|
|
}
|
|
delete(m, "name")
|
|
|
|
if !regexp.MustCompile("^[a-zA-Z0-9-_]+$").MatchString(name) {
|
|
return multierror.Prefix(errors.New("'name' field can only include alphanumeric characters, hyphens, and underscores"), fmt.Sprintf("%s.%s", blockName, key))
|
|
}
|
|
}
|
|
|
|
strMap := make(map[string]string, len(m))
|
|
for k, v := range m {
|
|
s, err := parseutil.ParseString(v)
|
|
if err != nil {
|
|
return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key))
|
|
}
|
|
strMap[k] = s
|
|
}
|
|
|
|
seal := &KMS{
|
|
Type: strings.ToLower(key),
|
|
Purpose: purpose,
|
|
Disabled: disabled,
|
|
Priority: priority,
|
|
Name: name,
|
|
}
|
|
if len(strMap) > 0 {
|
|
seal.Config = strMap
|
|
}
|
|
seals = append(seals, seal)
|
|
}
|
|
|
|
*result = append(*result, seals...)
|
|
|
|
return nil
|
|
}
|
|
|
|
func ParseKMSes(d string) ([]*KMS, error) {
|
|
// Parse!
|
|
obj, err := hcl.Parse(d)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Start building the result
|
|
var result struct {
|
|
Seals []*KMS `hcl:"-"`
|
|
}
|
|
|
|
if err := hcl.DecodeObject(&result, obj); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
list, ok := obj.Node.(*ast.ObjectList)
|
|
if !ok {
|
|
return nil, fmt.Errorf("error parsing: file doesn't contain a root object")
|
|
}
|
|
|
|
if o := list.Filter("seal"); len(o.Items) > 0 {
|
|
if err := parseKMS(&result.Seals, o, "seal", 3); err != nil {
|
|
return nil, fmt.Errorf("error parsing 'seal': %w", err)
|
|
}
|
|
}
|
|
|
|
if o := list.Filter("kms"); len(o.Items) > 0 {
|
|
if err := parseKMS(&result.Seals, o, "kms", 3); err != nil {
|
|
return nil, fmt.Errorf("error parsing 'kms': %w", err)
|
|
}
|
|
}
|
|
|
|
return result.Seals, nil
|
|
}
|
|
|
|
func configureWrapper(configKMS *KMS, infoKeys *[]string, info *map[string]string, logger hclog.Logger, opts ...wrapping.Option) (wrapping.Wrapper, error) {
|
|
var wrapper wrapping.Wrapper
|
|
var kmsInfo map[string]string
|
|
var err error
|
|
|
|
envConfig := GetEnvConfigFunc(configKMS)
|
|
for name, val := range envConfig {
|
|
// for the token, config takes precedence over env vars
|
|
if name == "token" && configKMS.Config[name] != "" {
|
|
continue
|
|
}
|
|
configKMS.Config[name] = val
|
|
}
|
|
|
|
switch wrapping.WrapperType(configKMS.Type) {
|
|
case wrapping.WrapperTypeShamir:
|
|
return nil, nil
|
|
|
|
case wrapping.WrapperTypeAead:
|
|
wrapper, kmsInfo, err = GetAEADKMSFunc(configKMS, opts...)
|
|
|
|
case wrapping.WrapperTypeAliCloudKms:
|
|
wrapper, kmsInfo, err = GetAliCloudKMSFunc(configKMS, opts...)
|
|
|
|
case wrapping.WrapperTypeAwsKms:
|
|
wrapper, kmsInfo, err = GetAWSKMSFunc(configKMS, opts...)
|
|
|
|
case wrapping.WrapperTypeAzureKeyVault:
|
|
wrapper, kmsInfo, err = GetAzureKeyVaultKMSFunc(configKMS, opts...)
|
|
|
|
case wrapping.WrapperTypeGcpCkms:
|
|
wrapper, kmsInfo, err = GetGCPCKMSKMSFunc(configKMS, opts...)
|
|
|
|
case wrapping.WrapperTypeOciKms:
|
|
if keyId, ok := configKMS.Config["key_id"]; ok {
|
|
opts = append(opts, wrapping.WithKeyId(keyId))
|
|
}
|
|
wrapper, kmsInfo, err = GetOCIKMSKMSFunc(configKMS, opts...)
|
|
case wrapping.WrapperTypeTransit:
|
|
wrapper, kmsInfo, err = GetTransitKMSFunc(configKMS, opts...)
|
|
|
|
case wrapping.WrapperTypePkcs11:
|
|
return nil, fmt.Errorf("KMS type 'pkcs11' requires the Vault Enterprise HSM binary")
|
|
|
|
default:
|
|
return nil, fmt.Errorf("Unknown KMS type %q", configKMS.Type)
|
|
}
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if infoKeys != nil && info != nil {
|
|
for k, v := range kmsInfo {
|
|
*infoKeys = append(*infoKeys, k)
|
|
(*info)[k] = v
|
|
}
|
|
}
|
|
|
|
return wrapper, nil
|
|
}
|
|
|
|
func GetAEADKMSFunc(kms *KMS, opts ...wrapping.Option) (wrapping.Wrapper, map[string]string, error) {
|
|
wrapper := aeadwrapper.NewWrapper()
|
|
wrapperInfo, err := wrapper.SetConfig(context.Background(), append(opts, wrapping.WithConfigMap(kms.Config))...)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
info := make(map[string]string)
|
|
if wrapperInfo != nil {
|
|
str := "AEAD Type"
|
|
if len(kms.Purpose) > 0 {
|
|
str = fmt.Sprintf("%v %s", kms.Purpose, str)
|
|
}
|
|
info[str] = wrapperInfo.Metadata["aead_type"]
|
|
}
|
|
return wrapper, info, nil
|
|
}
|
|
|
|
func GetAliCloudKMSFunc(kms *KMS, opts ...wrapping.Option) (wrapping.Wrapper, map[string]string, error) {
|
|
wrapper := alicloudkms.NewWrapper()
|
|
wrapperInfo, err := wrapper.SetConfig(context.Background(), append(opts, wrapping.WithDisallowEnvVars(true), wrapping.WithConfigMap(kms.Config))...)
|
|
if err != nil {
|
|
// If the error is any other than logical.KeyNotFoundError, return the error
|
|
if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) {
|
|
return nil, nil, err
|
|
}
|
|
}
|
|
info := make(map[string]string)
|
|
if wrapperInfo != nil {
|
|
info["AliCloud KMS Region"] = wrapperInfo.Metadata["region"]
|
|
info["AliCloud KMS KeyID"] = wrapperInfo.Metadata["kms_key_id"]
|
|
if domain, ok := wrapperInfo.Metadata["domain"]; ok {
|
|
info["AliCloud KMS Domain"] = domain
|
|
}
|
|
}
|
|
return wrapper, info, nil
|
|
}
|
|
|
|
var GetAWSKMSFunc = func(kms *KMS, opts ...wrapping.Option) (wrapping.Wrapper, map[string]string, error) {
|
|
wrapper := awskms.NewWrapper()
|
|
wrapperInfo, err := wrapper.SetConfig(context.Background(), append(opts, wrapping.WithDisallowEnvVars(true), wrapping.WithConfigMap(kms.Config))...)
|
|
if err != nil {
|
|
// If the error is any other than logical.KeyNotFoundError, return the error
|
|
if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) {
|
|
return nil, nil, err
|
|
}
|
|
}
|
|
info := make(map[string]string)
|
|
if wrapperInfo != nil {
|
|
info["AWS KMS Region"] = wrapperInfo.Metadata["region"]
|
|
info["AWS KMS KeyID"] = wrapperInfo.Metadata["kms_key_id"]
|
|
if endpoint, ok := wrapperInfo.Metadata["endpoint"]; ok {
|
|
info["AWS KMS Endpoint"] = endpoint
|
|
}
|
|
}
|
|
return wrapper, info, nil
|
|
}
|
|
|
|
func GetAzureKeyVaultKMSFunc(kms *KMS, opts ...wrapping.Option) (wrapping.Wrapper, map[string]string, error) {
|
|
wrapper := azurekeyvault.NewWrapper()
|
|
wrapperInfo, err := wrapper.SetConfig(context.Background(), append(opts, wrapping.WithDisallowEnvVars(true), wrapping.WithConfigMap(kms.Config))...)
|
|
if err != nil {
|
|
// If the error is any other than logical.KeyNotFoundError, return the error
|
|
if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) {
|
|
return nil, nil, err
|
|
}
|
|
}
|
|
info := make(map[string]string)
|
|
if wrapperInfo != nil {
|
|
info["Azure Environment"] = wrapperInfo.Metadata["environment"]
|
|
info["Azure Vault Name"] = wrapperInfo.Metadata["vault_name"]
|
|
info["Azure Key Name"] = wrapperInfo.Metadata["key_name"]
|
|
}
|
|
return wrapper, info, nil
|
|
}
|
|
|
|
func GetGCPCKMSKMSFunc(kms *KMS, opts ...wrapping.Option) (wrapping.Wrapper, map[string]string, error) {
|
|
wrapper := gcpckms.NewWrapper()
|
|
wrapperInfo, err := wrapper.SetConfig(context.Background(), append(opts, wrapping.WithDisallowEnvVars(true), wrapping.WithConfigMap(kms.Config))...)
|
|
if err != nil {
|
|
// If the error is any other than logical.KeyNotFoundError, return the error
|
|
if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) {
|
|
return nil, nil, err
|
|
}
|
|
}
|
|
info := make(map[string]string)
|
|
if wrapperInfo != nil {
|
|
info["GCP KMS Project"] = wrapperInfo.Metadata["project"]
|
|
info["GCP KMS Region"] = wrapperInfo.Metadata["region"]
|
|
info["GCP KMS Key Ring"] = wrapperInfo.Metadata["key_ring"]
|
|
info["GCP KMS Crypto Key"] = wrapperInfo.Metadata["crypto_key"]
|
|
}
|
|
return wrapper, info, nil
|
|
}
|
|
|
|
func GetOCIKMSKMSFunc(kms *KMS, opts ...wrapping.Option) (wrapping.Wrapper, map[string]string, error) {
|
|
wrapper := ocikms.NewWrapper()
|
|
wrapperInfo, err := wrapper.SetConfig(context.Background(), append(opts, wrapping.WithDisallowEnvVars(true), wrapping.WithConfigMap(kms.Config))...)
|
|
if err != nil {
|
|
return nil, nil, err
|
|
}
|
|
info := make(map[string]string)
|
|
if wrapperInfo != nil {
|
|
info["OCI KMS KeyID"] = wrapperInfo.Metadata[ocikms.KmsConfigKeyId]
|
|
info["OCI KMS Crypto Endpoint"] = wrapperInfo.Metadata[ocikms.KmsConfigCryptoEndpoint]
|
|
info["OCI KMS Management Endpoint"] = wrapperInfo.Metadata[ocikms.KmsConfigManagementEndpoint]
|
|
info["OCI KMS Principal Type"] = wrapperInfo.Metadata["principal_type"]
|
|
}
|
|
return wrapper, info, nil
|
|
}
|
|
|
|
var GetTransitKMSFunc = func(kms *KMS, opts ...wrapping.Option) (wrapping.Wrapper, map[string]string, error) {
|
|
wrapper := transit.NewWrapper()
|
|
wrapperInfo, err := wrapper.SetConfig(context.Background(), append(opts, wrapping.WithDisallowEnvVars(true), wrapping.WithConfigMap(kms.Config))...)
|
|
if err != nil {
|
|
// If the error is any other than logical.KeyNotFoundError, return the error
|
|
if !errwrap.ContainsType(err, new(logical.KeyNotFoundError)) {
|
|
return nil, nil, err
|
|
}
|
|
}
|
|
info := make(map[string]string)
|
|
if wrapperInfo != nil {
|
|
info["Transit Address"] = wrapperInfo.Metadata["address"]
|
|
info["Transit Mount Path"] = wrapperInfo.Metadata["mount_path"]
|
|
info["Transit Key Name"] = wrapperInfo.Metadata["key_name"]
|
|
if namespace, ok := wrapperInfo.Metadata["namespace"]; ok {
|
|
info["Transit Namespace"] = namespace
|
|
}
|
|
}
|
|
return wrapper, info, nil
|
|
}
|
|
|
|
func createSecureRandomReader(_ *SharedConfig, _ []*EntropySourcerInfo, _ hclog.Logger) (io.Reader, error) {
|
|
return rand.Reader, nil
|
|
}
|
|
|
|
func getEnvConfig(kms *KMS) map[string]string {
|
|
envValues := make(map[string]string)
|
|
|
|
var wrapperEnvVars map[string]string
|
|
switch wrapping.WrapperType(kms.Type) {
|
|
case wrapping.WrapperTypeAliCloudKms:
|
|
wrapperEnvVars = AliCloudKMSEnvVars
|
|
case wrapping.WrapperTypeAwsKms:
|
|
wrapperEnvVars = AWSKMSEnvVars
|
|
case wrapping.WrapperTypeAzureKeyVault:
|
|
wrapperEnvVars = AzureEnvVars
|
|
case wrapping.WrapperTypeGcpCkms:
|
|
wrapperEnvVars = GCPCKMSEnvVars
|
|
case wrapping.WrapperTypeOciKms:
|
|
wrapperEnvVars = OCIKMSEnvVars
|
|
case wrapping.WrapperTypeTransit:
|
|
wrapperEnvVars = TransitEnvVars
|
|
default:
|
|
return nil
|
|
}
|
|
|
|
for envVar, configName := range wrapperEnvVars {
|
|
val := os.Getenv(envVar)
|
|
if val != "" {
|
|
envValues[configName] = val
|
|
}
|
|
}
|
|
|
|
return envValues
|
|
}
|