mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-29 17:52:32 +00:00
* Adding explicit MPL license for sub-package. This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Adding explicit MPL license for sub-package. This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Updating the license from MPL to Business Source License. Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at https://hashi.co/bsl-blog, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl. * add missing license headers * Update copyright file headers to BUS-1.1 * Fix test that expected exact offset on hcl file --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com> Co-authored-by: Sarah Thompson <sthompson@hashicorp.com> Co-authored-by: Brian Kassouf <bkassouf@hashicorp.com>
239 lines
7.4 KiB
Go
239 lines
7.4 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package transit
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"fmt"
|
|
"os"
|
|
"testing"
|
|
|
|
stepwise "github.com/hashicorp/vault-testing-stepwise"
|
|
dockerEnvironment "github.com/hashicorp/vault-testing-stepwise/environments/docker"
|
|
"github.com/hashicorp/vault/api"
|
|
"github.com/hashicorp/vault/sdk/helper/keysutil"
|
|
"github.com/mitchellh/mapstructure"
|
|
)
|
|
|
|
// TestBackend_basic_docker is an example test using the Docker Environment
|
|
func TestAccBackend_basic_docker(t *testing.T) {
|
|
decryptData := make(map[string]interface{})
|
|
envOptions := stepwise.MountOptions{
|
|
RegistryName: "updatedtransit",
|
|
PluginType: api.PluginTypeSecrets,
|
|
PluginName: "transit",
|
|
MountPathPrefix: "transit_temp",
|
|
}
|
|
stepwise.Run(t, stepwise.Case{
|
|
Environment: dockerEnvironment.NewEnvironment("updatedtransit", &envOptions),
|
|
Steps: []stepwise.Step{
|
|
testAccStepwiseListPolicy(t, "test", true),
|
|
testAccStepwiseWritePolicy(t, "test", true),
|
|
testAccStepwiseListPolicy(t, "test", false),
|
|
testAccStepwiseReadPolicy(t, "test", false, true),
|
|
testAccStepwiseEncryptContext(t, "test", testPlaintext, "my-cool-context", decryptData),
|
|
testAccStepwiseDecrypt(t, "test", testPlaintext, decryptData),
|
|
testAccStepwiseEnableDeletion(t, "test"),
|
|
testAccStepwiseDeletePolicy(t, "test"),
|
|
testAccStepwiseReadPolicy(t, "test", true, true),
|
|
},
|
|
})
|
|
}
|
|
|
|
func testAccStepwiseWritePolicy(t *testing.T, name string, derived bool) stepwise.Step {
|
|
ts := stepwise.Step{
|
|
Operation: stepwise.WriteOperation,
|
|
Path: "keys/" + name,
|
|
Data: map[string]interface{}{
|
|
"derived": derived,
|
|
},
|
|
}
|
|
if os.Getenv("TRANSIT_ACC_KEY_TYPE") == "CHACHA" {
|
|
ts.Data["type"] = "chacha20-poly1305"
|
|
}
|
|
return ts
|
|
}
|
|
|
|
func testAccStepwiseListPolicy(t *testing.T, name string, expectNone bool) stepwise.Step {
|
|
return stepwise.Step{
|
|
Operation: stepwise.ListOperation,
|
|
Path: "keys",
|
|
Assert: func(resp *api.Secret, err error) error {
|
|
if (resp == nil || len(resp.Data) == 0) && !expectNone {
|
|
return fmt.Errorf("missing response")
|
|
}
|
|
if expectNone && resp != nil {
|
|
return fmt.Errorf("response data when expecting none")
|
|
}
|
|
|
|
if expectNone && resp == nil {
|
|
return nil
|
|
}
|
|
|
|
var d struct {
|
|
Keys []string `mapstructure:"keys"`
|
|
}
|
|
if err := mapstructure.Decode(resp.Data, &d); err != nil {
|
|
return err
|
|
}
|
|
if len(d.Keys) == 0 {
|
|
return fmt.Errorf("missing keys")
|
|
}
|
|
if len(d.Keys) > 1 {
|
|
return fmt.Errorf("only 1 key expected, %d returned", len(d.Keys))
|
|
}
|
|
if d.Keys[0] != name {
|
|
return fmt.Errorf("Actual key: %s\nExpected key: %s", d.Keys[0], name)
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func testAccStepwiseReadPolicy(t *testing.T, name string, expectNone, derived bool) stepwise.Step {
|
|
t.Helper()
|
|
return testAccStepwiseReadPolicyWithVersions(t, name, expectNone, derived, 1, 0)
|
|
}
|
|
|
|
func testAccStepwiseReadPolicyWithVersions(t *testing.T, name string, expectNone, derived bool, minDecryptionVersion int, minEncryptionVersion int) stepwise.Step {
|
|
t.Helper()
|
|
return stepwise.Step{
|
|
Operation: stepwise.ReadOperation,
|
|
Path: "keys/" + name,
|
|
Assert: func(resp *api.Secret, err error) error {
|
|
t.Helper()
|
|
if resp == nil && !expectNone {
|
|
return fmt.Errorf("missing response")
|
|
} else if expectNone {
|
|
if resp != nil {
|
|
return fmt.Errorf("response when expecting none")
|
|
}
|
|
return nil
|
|
}
|
|
var d struct {
|
|
Name string `mapstructure:"name"`
|
|
Key []byte `mapstructure:"key"`
|
|
Keys map[string]int64 `mapstructure:"keys"`
|
|
Type string `mapstructure:"type"`
|
|
Derived bool `mapstructure:"derived"`
|
|
KDF string `mapstructure:"kdf"`
|
|
DeletionAllowed bool `mapstructure:"deletion_allowed"`
|
|
ConvergentEncryption bool `mapstructure:"convergent_encryption"`
|
|
MinDecryptionVersion int `mapstructure:"min_decryption_version"`
|
|
MinEncryptionVersion int `mapstructure:"min_encryption_version"`
|
|
}
|
|
if err := mapstructure.Decode(resp.Data, &d); err != nil {
|
|
return err
|
|
}
|
|
|
|
if d.Name != name {
|
|
return fmt.Errorf("bad name: %#v", d)
|
|
}
|
|
if os.Getenv("TRANSIT_ACC_KEY_TYPE") == "CHACHA" {
|
|
if d.Type != keysutil.KeyType(keysutil.KeyType_ChaCha20_Poly1305).String() {
|
|
return fmt.Errorf("bad key type: %#v", d)
|
|
}
|
|
} else if d.Type != keysutil.KeyType(keysutil.KeyType_AES256_GCM96).String() {
|
|
return fmt.Errorf("bad key type: %#v", d)
|
|
}
|
|
// Should NOT get a key back
|
|
if d.Key != nil {
|
|
return fmt.Errorf("unexpected key found")
|
|
}
|
|
if d.Keys == nil {
|
|
return fmt.Errorf("no keys found")
|
|
}
|
|
if d.MinDecryptionVersion != minDecryptionVersion {
|
|
return fmt.Errorf("minimum decryption version mismatch, expected (%#v), found (%#v)", minEncryptionVersion, d.MinDecryptionVersion)
|
|
}
|
|
if d.MinEncryptionVersion != minEncryptionVersion {
|
|
return fmt.Errorf("minimum encryption version mismatch, expected (%#v), found (%#v)", minEncryptionVersion, d.MinDecryptionVersion)
|
|
}
|
|
if d.DeletionAllowed {
|
|
return fmt.Errorf("expected DeletionAllowed to be false, but got true")
|
|
}
|
|
if d.Derived != derived {
|
|
return fmt.Errorf("derived mismatch, expected (%t), got (%t)", derived, d.Derived)
|
|
}
|
|
if derived && d.KDF != "hkdf_sha256" {
|
|
return fmt.Errorf("expected KDF to be hkdf_sha256, but got (%s)", d.KDF)
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func testAccStepwiseEncryptContext(
|
|
t *testing.T, name, plaintext, context string, decryptData map[string]interface{},
|
|
) stepwise.Step {
|
|
return stepwise.Step{
|
|
Operation: stepwise.UpdateOperation,
|
|
Path: "encrypt/" + name,
|
|
Data: map[string]interface{}{
|
|
"plaintext": base64.StdEncoding.EncodeToString([]byte(plaintext)),
|
|
"context": base64.StdEncoding.EncodeToString([]byte(context)),
|
|
},
|
|
Assert: func(resp *api.Secret, err error) error {
|
|
var d struct {
|
|
Ciphertext string `mapstructure:"ciphertext"`
|
|
}
|
|
if err := mapstructure.Decode(resp.Data, &d); err != nil {
|
|
return err
|
|
}
|
|
if d.Ciphertext == "" {
|
|
return fmt.Errorf("missing ciphertext")
|
|
}
|
|
decryptData["ciphertext"] = d.Ciphertext
|
|
decryptData["context"] = base64.StdEncoding.EncodeToString([]byte(context))
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func testAccStepwiseDecrypt(
|
|
t *testing.T, name, plaintext string, decryptData map[string]interface{},
|
|
) stepwise.Step {
|
|
return stepwise.Step{
|
|
Operation: stepwise.UpdateOperation,
|
|
Path: "decrypt/" + name,
|
|
Data: decryptData,
|
|
Assert: func(resp *api.Secret, err error) error {
|
|
var d struct {
|
|
Plaintext string `mapstructure:"plaintext"`
|
|
}
|
|
if err := mapstructure.Decode(resp.Data, &d); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Decode the base64
|
|
plainRaw, err := base64.StdEncoding.DecodeString(d.Plaintext)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if string(plainRaw) != plaintext {
|
|
return fmt.Errorf("plaintext mismatch: %s expect: %s, decryptData was %#v", plainRaw, plaintext, decryptData)
|
|
}
|
|
return nil
|
|
},
|
|
}
|
|
}
|
|
|
|
func testAccStepwiseEnableDeletion(t *testing.T, name string) stepwise.Step {
|
|
return stepwise.Step{
|
|
Operation: stepwise.UpdateOperation,
|
|
Path: "keys/" + name + "/config",
|
|
Data: map[string]interface{}{
|
|
"deletion_allowed": true,
|
|
},
|
|
}
|
|
}
|
|
|
|
func testAccStepwiseDeletePolicy(t *testing.T, name string) stepwise.Step {
|
|
return stepwise.Step{
|
|
Operation: stepwise.DeleteOperation,
|
|
Path: "keys/" + name,
|
|
}
|
|
}
|