From b491c6d72a96dc846b30dbd9b41550de5ab3b8e6 Mon Sep 17 00:00:00 2001 From: ncabatoff Date: Mon, 27 Jul 2020 16:28:52 -0400 Subject: [PATCH] Fix parsing of seal stanzas that have an array for `purpose` (#9589) Hexadecimal integers will be converted to decimal, which is unfortunate but shouldn't have any negative effects other than perhaps confusion in the `vault debug` output. --- command/server/config_test_helpers.go | 4 +- internalshared/configutil/kms.go | 72 ++++++++++--------- sdk/helper/parseutil/parseutil.go | 8 +++ .../vault/sdk/helper/parseutil/parseutil.go | 8 +++ 4 files changed, 55 insertions(+), 37 deletions(-) diff --git a/command/server/config_test_helpers.go b/command/server/config_test_helpers.go index f9d2a617a..51f0aafa9 100644 --- a/command/server/config_test_helpers.go +++ b/command/server/config_test_helpers.go @@ -757,8 +757,8 @@ func testParseSeals(t *testing.T) { "slot": "0.0", "pin": "XXXXXXXX", "key_label": "HASHICORP", - "mechanism": "0x1082", - "hmac_mechanism": "0x0251", + "mechanism": "4226", + "hmac_mechanism": "593", "hmac_key_label": "vault-hsm-hmac-key", "default_hmac_key_label": "vault-hsm-hmac-key", "generate_key": "true", diff --git a/internalshared/configutil/kms.go b/internalshared/configutil/kms.go index 149053b3e..16e0ac505 100644 --- a/internalshared/configutil/kms.go +++ b/internalshared/configutil/kms.go @@ -68,49 +68,51 @@ func parseKMS(result *[]*KMS, list *ast.ObjectList, blockName string, maxKMS int key = item.Keys[0].Token.Value().(string) } - var disabled bool - var purpose []string - var err error - { - // 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)) - } - - 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) - } - } - - if v, ok := m["disabled"]; ok { - disabled, err = parseutil.ParseBool(v) - if err != nil { - return multierror.Prefix(err, fmt.Sprintf("%s.%s:", blockName, key)) - } - } - } - - var cfg map[string]string - if err := hcl.DecodeObject(&cfg, item.Val); err != nil { + // 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)) } - delete(cfg, "purpose") - delete(cfg, "disabled") + + 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") + } + + 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, } - if len(cfg) > 0 { - seal.Config = cfg + if len(strMap) > 0 { + seal.Config = strMap } seals = append(seals, seal) } diff --git a/sdk/helper/parseutil/parseutil.go b/sdk/helper/parseutil/parseutil.go index ea8289b43..face457f1 100644 --- a/sdk/helper/parseutil/parseutil.go +++ b/sdk/helper/parseutil/parseutil.go @@ -112,6 +112,14 @@ func ParseBool(in interface{}) (bool, error) { return result, nil } +func ParseString(in interface{}) (string, error) { + var result string + if err := mapstructure.WeakDecode(in, &result); err != nil { + return "", err + } + return result, nil +} + func ParseCommaStringSlice(in interface{}) ([]string, error) { rawString, ok := in.(string) if ok && rawString == "" { diff --git a/vendor/github.com/hashicorp/vault/sdk/helper/parseutil/parseutil.go b/vendor/github.com/hashicorp/vault/sdk/helper/parseutil/parseutil.go index ea8289b43..face457f1 100644 --- a/vendor/github.com/hashicorp/vault/sdk/helper/parseutil/parseutil.go +++ b/vendor/github.com/hashicorp/vault/sdk/helper/parseutil/parseutil.go @@ -112,6 +112,14 @@ func ParseBool(in interface{}) (bool, error) { return result, nil } +func ParseString(in interface{}) (string, error) { + var result string + if err := mapstructure.WeakDecode(in, &result); err != nil { + return "", err + } + return result, nil +} + func ParseCommaStringSlice(in interface{}) ([]string, error) { rawString, ok := in.(string) if ok && rawString == "" {