Files
vault/builtin/logical/transit/path_datakey_test.go
Scott Miller 3c0656e4c4 Update marcellanz/transit_pkcs1v15 RSA encryption support (#25486)
* [transit-pkcs1v15] transit support for the pkcs1v15 padding scheme – without UI tests (yet).

* [transit-pkcs1v15] renamed padding_scheme parameter in transit documentation.

* [transit-pkcs1v15] add changelog file.

* [transit-pkcs1v15] remove the algorithm path as padding_scheme is chosen by parameter.

* Update ui/app/templates/components/transit-key-action/datakey.hbs

Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com>

* Update ui/app/templates/components/transit-key-action/datakey.hbs

Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com>

* Update ui/app/templates/components/transit-key-action/datakey.hbs

Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com>

* Update website/content/api-docs/secret/transit.mdx

Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com>

* Update website/content/api-docs/secret/transit.mdx

Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com>

* Update website/content/api-docs/secret/transit.mdx

Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com>

* Add warnings to PKCS1v1.5 usage

* Update transit

* Update transit, including separating encrypt/decrypt paddings for rewrap

* Clean up factory use in the presence of padding

* address review feedback

* remove defaults

* lint

* more lint

* Some fixes for UI issues

 - Fix padding scheme dropdown console error by adding values
   to the transit-key-actions.hbs
 - Populate both padding scheme drop down menus within rewrap,
   not just the one padding_scheme
 - Do not submit a padding_scheme value through POST for non-rsa keys

* Fix Transit rewrap API to use decrypt_padding_scheme, encrypt_padding_scheme

 - Map the appropriate API fields for the RSA padding scheme to the
   batch items within the rewrap API
 - Add the ability to create RSA keys within the encrypt API endpoint
 - Add test case for rewrap api that leverages the padding_scheme fields

* Fix code linting issues

* simply padding scheme enum

* Apply suggestions from code review

Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com>

* Fix padding_scheme processing on data key api

 - The data key api was using the incorrect parameter name for
   the padding scheme
 - Enforce that padding_scheme is only used on RSA keys, we
   are punting on supporting it for managed keys at the moment.

* Add tests for parsePaddingSchemeArg

* Add missing copywrite headers

* Some small UI fixes

* Add missing param to datakey in api-docs

* Do not send padding_scheme for non-RSA key types within UI

* add UI tests for transit key actions form

---------

Co-authored-by: Marcel Lanz <marcellanz@n-1.ch>
Co-authored-by: claire bontempo <68122737+hellobontempo@users.noreply.github.com>
Co-authored-by: Sarah Chavis <62406755+schavis@users.noreply.github.com>
Co-authored-by: Steve Clark <steven.clark@hashicorp.com>
Co-authored-by: claire bontempo <cbontempo@hashicorp.com>
2024-10-09 09:30:14 -05:00

126 lines
3.8 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package transit
import (
"context"
"testing"
"github.com/hashicorp/vault/sdk/logical"
"github.com/mitchellh/mapstructure"
"github.com/stretchr/testify/require"
)
// TestDataKeyWithPaddingScheme validates that we properly leverage padding scheme
// args for the returned keys
func TestDataKeyWithPaddingScheme(t *testing.T) {
b, s := createBackendWithStorage(t)
keyName := "test"
createKeyReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "keys/" + keyName,
Storage: s,
Data: map[string]interface{}{
"type": "rsa-2048",
},
}
resp, err := b.HandleRequest(context.Background(), createKeyReq)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("failed key creation: err: %v resp: %#v", err, resp)
}
tests := []struct {
Name string
PaddingScheme string
DecryptPaddingScheme string
ShouldFailToDecrypt bool
}{
{"no-padding-scheme", "", "", false},
{"oaep", "oaep", "oaep", false},
{"pkcs1v15", "pkcs1v15", "pkcs1v15", false},
{"mixed-should-fail", "pkcs1v15", "oaep", true},
{"mixed-based-on-default-should-fail", "", "pkcs1v15", true},
}
for _, tc := range tests {
t.Run(tc.Name, func(t *testing.T) {
dataKeyReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "datakey/wrapped/" + keyName,
Storage: s,
Data: map[string]interface{}{},
}
if len(tc.PaddingScheme) > 0 {
dataKeyReq.Data["padding_scheme"] = tc.PaddingScheme
}
resp, err = b.HandleRequest(context.Background(), dataKeyReq)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("failed data key api: err: %v resp: %#v", err, resp)
}
require.NotNil(t, resp, "Got nil nil response")
var d struct {
Ciphertext string `mapstructure:"ciphertext"`
}
err = mapstructure.Decode(resp.Data, &d)
require.NoError(t, err, "failed decoding datakey api response")
require.NotEmpty(t, d.Ciphertext, "ciphertext should not be empty")
// Attempt to decrypt with data key with the same padding scheme
decryptReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "decrypt/" + keyName,
Storage: s,
Data: map[string]interface{}{
"ciphertext": d.Ciphertext,
},
}
if len(tc.DecryptPaddingScheme) > 0 {
decryptReq.Data["padding_scheme"] = tc.DecryptPaddingScheme
}
resp, err = b.HandleRequest(context.Background(), decryptReq)
if tc.ShouldFailToDecrypt {
require.Error(t, err, "Should have failed decryption as padding schemes are mixed")
} else {
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("failed to decrypt data key: err: %v resp: %#v", err, resp)
}
}
})
}
}
// TestDataKeyWithPaddingSchemeInvalidKeyType validates we fail when we specify a
// padding_scheme value on an invalid key type (non-RSA)
func TestDataKeyWithPaddingSchemeInvalidKeyType(t *testing.T) {
b, s := createBackendWithStorage(t)
keyName := "test"
createKeyReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "keys/" + keyName,
Storage: s,
Data: map[string]interface{}{},
}
resp, err := b.HandleRequest(context.Background(), createKeyReq)
if err != nil || (resp != nil && resp.IsError()) {
t.Fatalf("failed key creation: err: %v resp: %#v", err, resp)
}
dataKeyReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "datakey/wrapped/" + keyName,
Storage: s,
Data: map[string]interface{}{
"padding_scheme": "oaep",
},
}
resp, err = b.HandleRequest(context.Background(), dataKeyReq)
require.ErrorContains(t, err, "invalid request")
require.NotNil(t, resp, "response should not be nil")
require.Contains(t, resp.Error().Error(), "padding_scheme argument invalid: unsupported key")
}