You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
boundary/internal/bsr/kms/testing.go

136 lines
3.8 KiB

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package kms
import (
"context"
"crypto/rand"
"encoding/base64"
"io"
"testing"
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
"github.com/hashicorp/go-kms-wrapping/v2/aead"
)
// TestWrapper initializes an AEAD wrapping.Wrapper for testing
func TestWrapper(t testing.TB) wrapping.Wrapper {
t.Helper()
rootKey := make([]byte, 32)
n, err := rand.Read(rootKey)
if err != nil {
t.Fatal(err)
}
if n != 32 {
t.Fatal(n)
}
root := aead.NewWrapper()
_, err = root.SetConfig(context.Background(), wrapping.WithKeyId(base64.StdEncoding.EncodeToString(rootKey)))
if err != nil {
t.Fatal(err)
}
if err := root.SetAesGcmKeyBytes(rootKey); err != nil {
t.Fatal(err)
}
return root
}
// MockReader provides a mock reader for testing
type MockReader struct {
readCount int
// WithMockReadOn determines which read attempt the mock read results should
// be returned on.
WithMockReadOn int
// WithError specifies a mock read result of the specified error
WithError error
// WithBytesRead specifies a mock read result of the specified bytes read
WithBytesRead int
// Reader is the underlying reader
Reader io.Reader
}
// Read implements the mock read operation. Mock values supported: WithBytesRead, WithMockReadOn
func (m *MockReader) Read(p []byte) (n int, err error) {
m.readCount++
if m.readCount == m.WithMockReadOn {
_, _ = m.Reader.Read(p)
return m.WithBytesRead, m.WithError
}
return m.Reader.Read(p)
}
type MockWrapper struct {
// Wrapper is the underlying wrapping.Wrapper which is used to provide the
// mock's default behavior
Wrapper wrapping.Wrapper
encryptCount int
// WithEncryptErrorOn determines which encrypt attempt the mock encrypt
// error should be returned on.
WithEncryptErrorOn int
// EncryptErr is a mock value to return for the Encrypt(...) operation
EncryptErr error
// DecryptErr is a mock value to return for the Decrypt(...) operation
DecryptErr error
// KeyIdErr is a mock value to return for the KeyId(...) operation
KeyIdErr error
// KeyIdReturned is a mock value to return for the KeyId(...) operation
KeyIdReturned string
keyBytesCount int
// WithKeyBytesErrorOn determines which key bytes attempt the mock key bytes
// error should be returned on.
WithKeyBytesErrorOn int
}
// Type of the wrapper. No mock values supported
func (w *MockWrapper) Type(ctx context.Context) (wrapping.WrapperType, error) {
return w.Wrapper.Type(ctx)
}
// KeyId is the id of the key currently used for encryption operations. Mock
// values supported: KeyIdErr, KeyIdReturned
func (w *MockWrapper) KeyId(ctx context.Context) (string, error) { // nolint
switch {
case w.KeyIdErr != nil:
return "", w.KeyIdErr
case w.KeyIdReturned != "":
return w.KeyIdReturned, nil
default:
return w.Wrapper.KeyId(ctx)
}
}
// SetConfig applies the given options to a wrapper and returns
// configuration information. No mock values supported.
func (w *MockWrapper) SetConfig(ctx context.Context, options ...wrapping.Option) (*wrapping.WrapperConfig, error) {
return w.Wrapper.SetConfig(ctx, options...)
}
// Decrypt decrypts the given byte slice and stores the resulting information in
// the returned byte slice. Mock values supported: DecryptErr
func (w *MockWrapper) Decrypt(ctx context.Context, ciphertext *wrapping.BlobInfo, options ...wrapping.Option) ([]byte, error) {
if w.DecryptErr != nil {
return nil, w.DecryptErr
}
return w.Wrapper.Decrypt(ctx, ciphertext, options...)
}
// Encrypt encrypts the given byte slice. Mock values supported: EncryptErr and WithEncryptErrorOn
func (w *MockWrapper) Encrypt(ctx context.Context, plaintext []byte, options ...wrapping.Option) (*wrapping.BlobInfo, error) {
w.encryptCount++
if w.encryptCount == w.WithEncryptErrorOn {
return nil, w.EncryptErr
}
return w.Wrapper.Encrypt(ctx, plaintext, options...)
}