mirror of
https://github.com/hashicorp/vault.git
synced 2026-02-03 20:40:45 -05:00
* Vault 42177 Add Backend Field (#12092) * add a new struct for the total number of successful requests for transit and transform * implement tracking for encrypt path * implement tracking in encrypt path * add tracking in rewrap * add tracking to datakey path * add tracking to hmac path * add tracking to sign path * add tracking to verify path * unit tests for verify path * add tracking to cmac path * reset the global counter in each unit test * add tracking to hmac verify * add methods to retrieve and flush transit count * modify the methods that store and update data protection call counts * update the methods * add a helper method to combine replicated and local data call counts * add tracking to the endpoint * fix some formatting errors * add unit tests to path encrypt for tracking * add unit tests to decrypt path * fix linter error * add unit tests to test update and store methods for data protection calls * stub fix: do not create separate files * fix the tracking by coordinating replicated and local data, add unit tests * update all reference to the new data struct * revert to previous design with just one global counter for all calls for each cluster * complete external test * no need to check if current count is greater than 0, remove it * feedback: remove unnacassary comments about atomic addition, standardize comments * leave jira id on todo comment, remove unused method * rename mathods by removing HWM and max in names, update jira id in todo comment, update response field key name * feedback: remove explicit counter in cmac tests, instead put in the expected number * feedback: remove explicit tracking in the rest of the tests * feedback: separate transit testing into its own external test * Update vault/consumption_billing_util_test.go Co-authored-by: divyaac <divya.chandrasekaran@hashicorp.com> * update comment after test name change * fix comments * fix comments in test * another comment fix * feedback: remove incorrect comment * fix a CE test * fix the update method: instead of storing max, increment by the current count value * update the unit test, remove local prefix as argument to the methods since we store only to non-replicated paths * update the external test * Adds a field to backend to track billing data removed file * Changed implementation to use a map instead * Some more comments * Add more implementation * Edited grpc server backend * Refactored a bit * Fix one more test * Modified map: * Revert "Modified map:" This reverts commit 1730fe1f358b210e6abae43fbdca09e585aaaaa8. * Removed some other things * Edited consumption billing files a bit * Testing function * Fix transit stuff and make sure tests pass * Changes * More changes * More changes * Edited external test * Edited some more tests * Edited and fixed tests * One more fix * Fix some more tests * Moved some testing structures around and added error checking * Fixed some nits * Update builtin/logical/transit/path_sign_verify.go Co-authored-by: Nick Cabatoff <ncabatoff@hashicorp.com> * Edited some errors * Fixed error logs * Edited one more thing * Decorate the error * Update vault/consumption_billing.go Co-authored-by: Nick Cabatoff <ncabatoff@hashicorp.com> --------- Co-authored-by: Amir Aslamov <amir.aslamov@hashicorp.com> Co-authored-by: Nick Cabatoff <ncabatoff@hashicorp.com> * Edited stub function --------- Co-authored-by: divyaac <divya.chandrasekaran@hashicorp.com> Co-authored-by: Amir Aslamov <amir.aslamov@hashicorp.com> Co-authored-by: Nick Cabatoff <ncabatoff@hashicorp.com> Co-authored-by: divyaac <divyaac@berkeley.edu>
129 lines
4 KiB
Go
129 lines
4 KiB
Go
// Copyright IBM Corp. 2016, 2025
|
|
// 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)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
// We expect 8 successful requests ((3 valid cases x 2 operations) + (2 invalid cases x 1 operation))
|
|
require.Equal(t, uint64(8), b.billingDataCounts.Transit.Load())
|
|
}
|
|
|
|
// 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")
|
|
// We expect 0 successful requests
|
|
require.Equal(t, uint64(0), b.billingDataCounts.Transit.Load())
|
|
}
|