2023-03-18 15:52:50 -04:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
|
|
|
|
|
|
package kms_test
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
stdcrypto "crypto"
|
|
|
|
|
"crypto/rand"
|
|
|
|
|
"fmt"
|
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
|
|
stdLibEd25519 "crypto/ed25519"
|
|
|
|
|
|
|
|
|
|
"github.com/hashicorp/boundary/internal/bsr/kms"
|
|
|
|
|
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
|
|
|
|
|
"github.com/hashicorp/go-kms-wrapping/v2/aead"
|
|
|
|
|
"github.com/hashicorp/go-kms-wrapping/v2/ed25519"
|
|
|
|
|
crypto "github.com/hashicorp/go-kms-wrapping/v2/extras/crypto"
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
"google.golang.org/protobuf/proto"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestCreateBsrKeys(t *testing.T) {
|
|
|
|
|
const (
|
|
|
|
|
ed25519_PrivKey_Length = 64
|
|
|
|
|
ed25519_PubKey_Length = 32
|
|
|
|
|
bsrKey_Length = 32
|
|
|
|
|
|
|
|
|
|
testMsg = "test-msg"
|
|
|
|
|
)
|
|
|
|
|
t.Parallel()
|
|
|
|
|
testCtx := context.Background()
|
|
|
|
|
testBsrKmsWrapper := kms.TestWrapper(t)
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
ctx context.Context
|
|
|
|
|
bsrWrapper wrapping.Wrapper
|
|
|
|
|
opt []kms.Option
|
|
|
|
|
sessionId string
|
|
|
|
|
wantErr bool
|
|
|
|
|
wantErrMatch error
|
|
|
|
|
wantErrContains string
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "success",
|
|
|
|
|
ctx: testCtx,
|
|
|
|
|
bsrWrapper: testBsrKmsWrapper,
|
|
|
|
|
sessionId: "session-id",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "success-WithRandomReader",
|
|
|
|
|
ctx: testCtx,
|
|
|
|
|
bsrWrapper: testBsrKmsWrapper,
|
|
|
|
|
sessionId: "session-id",
|
|
|
|
|
opt: []kms.Option{kms.WithRandomReader(rand.Reader)},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-session-id",
|
|
|
|
|
ctx: testCtx,
|
|
|
|
|
bsrWrapper: testBsrKmsWrapper,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing session id",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-bsr-wrapper",
|
|
|
|
|
ctx: testCtx,
|
|
|
|
|
sessionId: "session-id",
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing external bsr wrapper",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "rand-err-first-read",
|
|
|
|
|
ctx: testCtx,
|
|
|
|
|
bsrWrapper: testBsrKmsWrapper,
|
|
|
|
|
sessionId: "session-id",
|
|
|
|
|
opt: []kms.Option{
|
|
|
|
|
kms.WithRandomReader(
|
|
|
|
|
&kms.MockReader{
|
|
|
|
|
WithError: fmt.Errorf("rand err"),
|
|
|
|
|
WithBytesRead: 32,
|
|
|
|
|
WithMockReadOn: 1,
|
|
|
|
|
Reader: rand.Reader,
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrGenKey,
|
|
|
|
|
wantErrContains: "error reading random bytes for bsr",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "rand-bytes-read-first-read",
|
|
|
|
|
ctx: testCtx,
|
|
|
|
|
bsrWrapper: testBsrKmsWrapper,
|
|
|
|
|
sessionId: "session-id",
|
|
|
|
|
opt: []kms.Option{
|
|
|
|
|
kms.WithRandomReader(
|
|
|
|
|
&kms.MockReader{
|
|
|
|
|
WithBytesRead: 1,
|
|
|
|
|
WithMockReadOn: 1,
|
|
|
|
|
Reader: rand.Reader,
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrGenKey,
|
|
|
|
|
wantErrContains: "wanted 32 bytes and got 1",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "encrypt-bsr-err",
|
|
|
|
|
ctx: testCtx,
|
|
|
|
|
bsrWrapper: &kms.MockWrapper{
|
|
|
|
|
Wrapper: testBsrKmsWrapper,
|
|
|
|
|
WithEncryptErrorOn: 1,
|
|
|
|
|
EncryptErr: fmt.Errorf("bsr-encrypt-err"),
|
|
|
|
|
},
|
|
|
|
|
sessionId: "session-id",
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrEncrypt,
|
|
|
|
|
wantErrContains: "unable to encrypt bsr key",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "ed25519.Generate-err",
|
|
|
|
|
ctx: testCtx,
|
|
|
|
|
bsrWrapper: testBsrKmsWrapper,
|
|
|
|
|
sessionId: "session-id",
|
|
|
|
|
opt: []kms.Option{
|
|
|
|
|
kms.WithRandomReader(
|
|
|
|
|
&kms.MockReader{
|
|
|
|
|
WithError: fmt.Errorf("rand err"),
|
|
|
|
|
WithBytesRead: 1,
|
|
|
|
|
WithMockReadOn: 2,
|
|
|
|
|
Reader: rand.Reader,
|
|
|
|
|
},
|
|
|
|
|
),
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrGenKey,
|
|
|
|
|
wantErrContains: "unable to generate bsr ed25519 key-pair",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "encrypt-priv-key-err",
|
|
|
|
|
ctx: testCtx,
|
|
|
|
|
bsrWrapper: &kms.MockWrapper{
|
|
|
|
|
Wrapper: testBsrKmsWrapper,
|
|
|
|
|
WithEncryptErrorOn: 2,
|
|
|
|
|
EncryptErr: fmt.Errorf("encrypt-priv-key-err"),
|
|
|
|
|
},
|
|
|
|
|
sessionId: "session-id",
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrEncrypt,
|
|
|
|
|
wantErrContains: "unable to encrypt bsr ed25519 priv key",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
for _, tc := range tests {
|
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
|
|
|
got, err := kms.CreateKeys(tc.ctx, tc.bsrWrapper, tc.sessionId, tc.opt...)
|
|
|
|
|
if tc.wantErr {
|
|
|
|
|
require.Error(err)
|
|
|
|
|
assert.Empty(got)
|
|
|
|
|
if tc.wantErrMatch != nil {
|
|
|
|
|
assert.ErrorIsf(err, tc.wantErrMatch, "expected %q and got err: %+v", tc.wantErrMatch, err)
|
|
|
|
|
}
|
|
|
|
|
if tc.wantErrContains != "" {
|
|
|
|
|
assert.Contains(err.Error(), tc.wantErrContains)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.NotNil(got)
|
|
|
|
|
|
|
|
|
|
// check the WrappedBsrKey
|
|
|
|
|
assert.NotEmpty(got.WrappedBsrKey)
|
|
|
|
|
assert.NotEmpty(got.WrappedBsrKey.WrappedKey)
|
|
|
|
|
assert.Empty(got.WrappedBsrKey.Key)
|
|
|
|
|
assert.Equal(tc.sessionId, got.WrappedBsrKey.KeyId)
|
|
|
|
|
assert.Equal(wrapping.KeyType_Aes256, got.WrappedBsrKey.KeyType)
|
|
|
|
|
assert.Equal(wrapping.KeyEncoding_Bytes, got.WrappedBsrKey.KeyEncoding)
|
|
|
|
|
assert.Equal([]wrapping.KeyPurpose{wrapping.KeyPurpose_Sign, wrapping.KeyPurpose_Encrypt, wrapping.KeyPurpose_Decrypt}, got.WrappedBsrKey.KeyPurposes)
|
|
|
|
|
var bsrBlob wrapping.BlobInfo
|
|
|
|
|
require.NoError(proto.Unmarshal(got.WrappedBsrKey.WrappedKey, &bsrBlob))
|
|
|
|
|
bsrKeyBytes, err := tc.bsrWrapper.Decrypt(testCtx, &bsrBlob)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.NotEmpty(bsrKeyBytes)
|
|
|
|
|
assert.Len(bsrKeyBytes, bsrKey_Length)
|
|
|
|
|
|
|
|
|
|
// check the WrappedPrivKey
|
|
|
|
|
assert.NotEmpty(got.WrappedPrivKey)
|
|
|
|
|
assert.NotEmpty(got.WrappedPrivKey.WrappedKey)
|
|
|
|
|
assert.Empty(got.WrappedPrivKey.Key)
|
|
|
|
|
assert.Equal(tc.sessionId, got.WrappedPrivKey.KeyId)
|
|
|
|
|
assert.Equal(wrapping.KeyType_Ed25519, got.WrappedPrivKey.KeyType)
|
|
|
|
|
assert.Equal(wrapping.KeyEncoding_Bytes, got.WrappedPrivKey.KeyEncoding)
|
|
|
|
|
assert.Equal([]wrapping.KeyPurpose{wrapping.KeyPurpose_Sign}, got.WrappedPrivKey.KeyPurposes)
|
|
|
|
|
var privKeyBlob wrapping.BlobInfo
|
|
|
|
|
require.NoError(proto.Unmarshal(got.WrappedPrivKey.WrappedKey, &privKeyBlob))
|
|
|
|
|
privKeyBytes, err := tc.bsrWrapper.Decrypt(testCtx, &privKeyBlob)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.NotEmpty(privKeyBytes)
|
|
|
|
|
assert.Len(privKeyBytes, ed25519_PrivKey_Length)
|
|
|
|
|
|
|
|
|
|
// check the bsr key (unwrapped)
|
|
|
|
|
assert.NotEmpty(got.BsrKey)
|
|
|
|
|
assert.NotEmpty(got.BsrKey.Key)
|
|
|
|
|
assert.Empty(got.BsrKey.WrappedKey)
|
|
|
|
|
assert.Equal(tc.sessionId, got.BsrKey.KeyId)
|
|
|
|
|
assert.Equal(wrapping.KeyType_Aes256, got.BsrKey.KeyType)
|
|
|
|
|
assert.Equal(wrapping.KeyEncoding_Bytes, got.BsrKey.KeyEncoding)
|
|
|
|
|
assert.Equal([]wrapping.KeyPurpose{wrapping.KeyPurpose_Sign, wrapping.KeyPurpose_Encrypt, wrapping.KeyPurpose_Decrypt}, got.BsrKey.KeyPurposes)
|
|
|
|
|
assert.Len(got.BsrKey.Key, bsrKey_Length)
|
|
|
|
|
|
|
|
|
|
// check the priv key (unwrapped)
|
|
|
|
|
assert.NotEmpty(got.PrivKey)
|
|
|
|
|
assert.NotEmpty(got.PrivKey.Key)
|
|
|
|
|
assert.Empty(got.PrivKey.WrappedKey)
|
|
|
|
|
assert.Equal(tc.sessionId, got.PrivKey.KeyId)
|
|
|
|
|
assert.Equal(wrapping.KeyType_Ed25519, got.PrivKey.KeyType)
|
|
|
|
|
assert.Equal(wrapping.KeyEncoding_Bytes, got.PrivKey.KeyEncoding)
|
|
|
|
|
assert.Equal([]wrapping.KeyPurpose{wrapping.KeyPurpose_Sign}, got.PrivKey.KeyPurposes)
|
|
|
|
|
assert.Len(got.PrivKey.Key, ed25519_PrivKey_Length)
|
|
|
|
|
|
|
|
|
|
// check the pub key (unwrapped)
|
|
|
|
|
assert.NotEmpty(got.PubKey)
|
|
|
|
|
assert.NotEmpty(got.PubKey.Key)
|
|
|
|
|
assert.Empty(got.PubKey.WrappedKey)
|
|
|
|
|
assert.Equal(tc.sessionId, got.PubKey.KeyId)
|
|
|
|
|
assert.Equal(wrapping.KeyType_Ed25519, got.PubKey.KeyType)
|
|
|
|
|
assert.Equal(wrapping.KeyEncoding_Bytes, got.PubKey.KeyEncoding)
|
|
|
|
|
assert.Equal([]wrapping.KeyPurpose{wrapping.KeyPurpose_Verify}, got.PubKey.KeyPurposes)
|
|
|
|
|
assert.Len(got.PubKey.Key, ed25519_PubKey_Length)
|
|
|
|
|
|
|
|
|
|
// check the pub key self-signature
|
|
|
|
|
// first we'll check it "by hand"
|
|
|
|
|
assert.NotEmpty(got.PubKeySelfSignature)
|
|
|
|
|
s, err := ed25519.NewSigner(testCtx, ed25519.WithPrivKey(stdLibEd25519.PrivateKey(got.PrivKey.Key)))
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
testSig, err := s.Sign(testCtx, stdLibEd25519.PublicKey(got.PubKey.Key))
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
v, err := ed25519.NewVerifier(testCtx, ed25519.WithPubKey(stdLibEd25519.PublicKey(got.PubKey.Key)), wrapping.WithKeyId("session-id"))
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
verified, err := v.Verify(testCtx, stdLibEd25519.PublicKey(got.PubKey.Key), testSig)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.True(verified)
|
|
|
|
|
// check the keys match
|
|
|
|
|
privKey, err := got.UnwrapPrivKey(testCtx, tc.bsrWrapper)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.Equal(got.PrivKey.Key, []byte(privKey))
|
|
|
|
|
// now lets' check via the provided oracle
|
|
|
|
|
verified, err = got.VerifyPubKeySelfSignature(testCtx)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.True(verified)
|
|
|
|
|
|
|
|
|
|
// check the pub key bsr signature
|
|
|
|
|
// first we'll check it "by hand"
|
|
|
|
|
assert.NotEmpty(got.PubKeyBsrSignature)
|
|
|
|
|
bsrKeyWrapper := aead.NewWrapper()
|
|
|
|
|
_, err = bsrKeyWrapper.SetConfig(testCtx, wrapping.WithKeyId(got.WrappedBsrKey.KeyId))
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
err = bsrKeyWrapper.SetAesGcmKeyBytes(bsrKeyBytes)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
marshaledTestSigInfo, err := crypto.HmacSha256(testCtx, stdLibEd25519.PublicKey(got.PubKey.Key), bsrKeyWrapper, crypto.WithMarshaledSigInfo())
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
var testSigInfo wrapping.SigInfo
|
|
|
|
|
err = proto.Unmarshal([]byte(marshaledTestSigInfo), &testSigInfo)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.Equal(&testSigInfo, got.PubKeyBsrSignature)
|
|
|
|
|
// do the wrappers match
|
|
|
|
|
unwrappedBsrKey, err := got.UnwrapBsrKey(testCtx, tc.bsrWrapper)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.Equal(bsrKeyWrapper, unwrappedBsrKey)
|
|
|
|
|
// now let's check via the provided oracle using the plaintext
|
|
|
|
|
// got.PrivKey
|
|
|
|
|
verified, err = got.VerifyPubKeyBsrSignature(testCtx)
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.True(verified)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestBsrKeys_UnwrapBsrKey(t *testing.T) {
|
|
|
|
|
t.Parallel()
|
|
|
|
|
testCtx := context.Background()
|
|
|
|
|
testBsrWrapper := kms.TestWrapper(t)
|
|
|
|
|
|
|
|
|
|
testBytes := make([]byte, 32)
|
|
|
|
|
_, err := rand.Read(testBytes)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
testAeadWrapper := aead.NewWrapper()
|
|
|
|
|
_, err = testAeadWrapper.SetConfig(testCtx, wrapping.WithKeyId("session-id"))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
err = testAeadWrapper.SetAesGcmKeyBytes(testBytes)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
bsrBlob, err := testBsrWrapper.Encrypt(testCtx, testBytes)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
marshaledBsrBlob, err := proto.Marshal(bsrBlob)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
bsrKeys *kms.Keys
|
|
|
|
|
bsrWrapper wrapping.Wrapper
|
|
|
|
|
want *aead.Wrapper
|
|
|
|
|
wantErr bool
|
|
|
|
|
wantErrMatch error
|
|
|
|
|
wantErrContains string
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "success",
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedBsrKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
KeyPurposes: []wrapping.KeyPurpose{wrapping.KeyPurpose_Sign, wrapping.KeyPurpose_Encrypt, wrapping.KeyPurpose_Decrypt},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
want: testAeadWrapper,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "nil-bsr-keys",
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "nil bsr keys",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-bsr-wrapper",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedBsrKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
KeyPurposes: []wrapping.KeyPurpose{wrapping.KeyPurpose_Sign, wrapping.KeyPurpose_Encrypt, wrapping.KeyPurpose_Decrypt},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing bsr wrapper",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-wrapped-bsr-key",
|
|
|
|
|
bsrKeys: &kms.Keys{},
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing wrapped bsr key",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-wrapped-bsr-key-id",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedBsrKey: &wrapping.KeyInfo{
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing wrapped bsr key id",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-wrapped-key-bytes",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedBsrKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing wrapped bsr key bytes",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "unexpected-key-type",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedBsrKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "unexpected key type \"Unknown_KeyType\"; expected \"Aes256\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-key-encoding",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedBsrKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "unexpected key encoding \"Unknown_KeyEncoding\"; expected \"Bytes\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "blob-info-err",
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedBsrKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
WrappedKey: []byte("not-blob-info"),
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrDecode,
|
|
|
|
|
wantErrContains: "error unmarshaling wrapped bsr key",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "decrypt-err",
|
|
|
|
|
bsrWrapper: kms.TestWrapper(t),
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedBsrKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrDecrypt,
|
|
|
|
|
wantErrContains: "error decrypting wrapped bsr key",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
for _, tc := range tests {
|
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
|
|
|
got, err := tc.bsrKeys.UnwrapBsrKey(testCtx, tc.bsrWrapper)
|
|
|
|
|
if tc.wantErr {
|
|
|
|
|
require.Error(err)
|
|
|
|
|
assert.Empty(got)
|
|
|
|
|
if tc.wantErrMatch != nil {
|
|
|
|
|
assert.ErrorIsf(err, tc.wantErrMatch, "expected %q and got err: %+v", tc.wantErrMatch, err)
|
|
|
|
|
}
|
|
|
|
|
if tc.wantErrContains != "" {
|
|
|
|
|
assert.Contains(err.Error(), tc.wantErrContains)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.NotNil(got)
|
|
|
|
|
assert.Equal(tc.want, got)
|
|
|
|
|
assert.Equal(&wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
Key: testBytes,
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
KeyPurposes: []wrapping.KeyPurpose{wrapping.KeyPurpose_Sign, wrapping.KeyPurpose_Encrypt, wrapping.KeyPurpose_Decrypt},
|
|
|
|
|
}, tc.bsrKeys.BsrKey)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestBsrKeys_UnwrapPrivKey(t *testing.T) {
|
|
|
|
|
t.Parallel()
|
|
|
|
|
testCtx := context.Background()
|
|
|
|
|
testBsrWrapper := kms.TestWrapper(t)
|
|
|
|
|
|
|
|
|
|
_, priv, err := stdLibEd25519.GenerateKey(rand.Reader)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
bsrBlob, err := testBsrWrapper.Encrypt(testCtx, priv)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
marshaledBsrBlob, err := proto.Marshal(bsrBlob)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
badBlob, err := testBsrWrapper.Encrypt(testCtx, []byte("bad-key-len"))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
marshaledBadBlob, err := proto.Marshal(badBlob)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
bsrKeys *kms.Keys
|
|
|
|
|
bsrWrapper wrapping.Wrapper
|
|
|
|
|
want stdLibEd25519.PrivateKey
|
|
|
|
|
wantErr bool
|
|
|
|
|
wantErrMatch error
|
|
|
|
|
wantErrContains string
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "success",
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedPrivKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
KeyPurposes: []wrapping.KeyPurpose{wrapping.KeyPurpose_Sign},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
want: priv,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "nil-bsr-keys",
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "nil bsr keys",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-bsr-wrapper",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedPrivKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing bsr wrapper",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-wrapped-priv-key",
|
|
|
|
|
bsrKeys: &kms.Keys{},
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing wrapped priv key",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-wrapped-bsr-key-id",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedPrivKey: &wrapping.KeyInfo{
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing wrapped priv key id",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-wrapped-key-bytes",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedPrivKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing wrapped priv key bytes",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-key-type",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedPrivKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "unexpected key type \"Unknown_KeyType\"; expected \"Ed25519\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-key-encoding",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedPrivKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "unexpected key encoding \"Unknown_KeyEncoding\"; expected \"Bytes\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "blob-info-err",
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedPrivKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
WrappedKey: []byte("not-blob-info"),
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrDecode,
|
|
|
|
|
wantErrContains: "error unmarshaling wrapped priv key",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "decrypt-err",
|
|
|
|
|
bsrWrapper: kms.TestWrapper(t),
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedPrivKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrDecrypt,
|
|
|
|
|
wantErrContains: "error decrypting wrapped priv key",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "invalid-key-len-err",
|
|
|
|
|
bsrWrapper: testBsrWrapper,
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedPrivKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
WrappedKey: marshaledBadBlob,
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "priv key must be 64 bytes; got 11",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
for _, tc := range tests {
|
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
|
|
|
got, err := tc.bsrKeys.UnwrapPrivKey(testCtx, tc.bsrWrapper)
|
|
|
|
|
if tc.wantErr {
|
|
|
|
|
require.Error(err)
|
|
|
|
|
assert.Empty(got)
|
|
|
|
|
if tc.wantErrMatch != nil {
|
|
|
|
|
assert.ErrorIsf(err, tc.wantErrMatch, "expected %q and got err: %+v", tc.wantErrMatch, err)
|
|
|
|
|
}
|
|
|
|
|
if tc.wantErrContains != "" {
|
|
|
|
|
assert.Contains(err.Error(), tc.wantErrContains)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.NotNil(got)
|
|
|
|
|
assert.Equal(tc.want, got)
|
|
|
|
|
assert.Equal(&wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
Key: priv,
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
KeyPurposes: []wrapping.KeyPurpose{wrapping.KeyPurpose_Sign},
|
|
|
|
|
}, tc.bsrKeys.PrivKey)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestBsrKeys_VerifyPubBsrSignature(t *testing.T) {
|
|
|
|
|
t.Parallel()
|
|
|
|
|
testCtx := context.Background()
|
|
|
|
|
testBsrWrapper := kms.TestWrapper(t)
|
|
|
|
|
|
|
|
|
|
testBytes := make([]byte, 32)
|
|
|
|
|
_, err := rand.Read(testBytes)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
testAeadWrapper := aead.NewWrapper()
|
|
|
|
|
_, err = testAeadWrapper.SetConfig(testCtx, wrapping.WithKeyId("session-id"))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
err = testAeadWrapper.SetAesGcmKeyBytes(testBytes)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
bsrBlob, err := testBsrWrapper.Encrypt(testCtx, testBytes)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
marshaledBsrBlob, err := proto.Marshal(bsrBlob)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
pub, _, err := stdLibEd25519.GenerateKey(rand.Reader)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
sigStr, err := crypto.HmacSha256(testCtx, pub, testAeadWrapper, crypto.WithMarshaledSigInfo())
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
var testValidPubKeySignature wrapping.SigInfo
|
|
|
|
|
require.NoError(t, proto.Unmarshal([]byte(sigStr), &testValidPubKeySignature))
|
|
|
|
|
|
|
|
|
|
invalidPub, _, err := stdLibEd25519.GenerateKey(rand.Reader)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
sigStr, err = crypto.HmacSha256(testCtx, invalidPub, testAeadWrapper, crypto.WithMarshaledSigInfo())
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
var testInValidPubKeySignature wrapping.SigInfo
|
|
|
|
|
require.NoError(t, proto.Unmarshal([]byte(sigStr), &testInValidPubKeySignature))
|
|
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
bsrKeys *kms.Keys
|
|
|
|
|
opt []kms.Option
|
|
|
|
|
want bool
|
|
|
|
|
wantErr bool
|
|
|
|
|
wantErrMatch error
|
|
|
|
|
wantErrContains string
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "not-equal",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
BsrKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: testBytes,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeyBsrSignature: &testInValidPubKeySignature,
|
|
|
|
|
},
|
|
|
|
|
want: false,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "success",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
BsrKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: testBytes,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeyBsrSignature: &testValidPubKeySignature,
|
|
|
|
|
},
|
|
|
|
|
want: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "success-with-wrapper",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedBsrKey: &wrapping.KeyInfo{
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeyBsrSignature: &testValidPubKeySignature,
|
|
|
|
|
},
|
|
|
|
|
opt: []kms.Option{kms.WithBsrWrapper(testBsrWrapper)},
|
|
|
|
|
want: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "nil-bsr-keys",
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "nil bsr keys",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-bsr-key-and-wrapped-bsr-key",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeyBsrSignature: &testValidPubKeySignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing bsr key and wrapped bsr key",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-bsr-key-bytes",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
BsrKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeyBsrSignature: &testValidPubKeySignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing bsr key bytes",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-wrapped-bsr-key-bytes",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedBsrKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeyBsrSignature: &testValidPubKeySignature,
|
|
|
|
|
},
|
|
|
|
|
opt: []kms.Option{kms.WithBsrWrapper(testBsrWrapper)},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing wrapped bsr key bytes",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-pub-key",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
BsrKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: testBytes,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeyBsrSignature: &testValidPubKeySignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing pub key",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-signature",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
BsrKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: testBytes,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing pub key signature",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "bsr-key-invalid-key-type",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
BsrKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: testBytes,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_EdsaP521,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeyBsrSignature: &testValidPubKeySignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "unexpected key type \"EdsaP521\"; expected \"Aes256\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "bsr-key-invalid-key-encoding",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
BsrKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: testBytes,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Pkix,
|
|
|
|
|
},
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeyBsrSignature: &testValidPubKeySignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "unexpected key encoding \"Pkix\"; expected \"Bytes\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "wrapped-bsr-key-missing-wrapper",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedBsrKey: &wrapping.KeyInfo{
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeyBsrSignature: &testValidPubKeySignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing bsr wrapper",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "wrapped-bsr-key-invalid-key-type",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedBsrKey: &wrapping.KeyInfo{
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Rsa4096,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeyBsrSignature: &testValidPubKeySignature,
|
|
|
|
|
},
|
|
|
|
|
opt: []kms.Option{kms.WithBsrWrapper(testBsrWrapper)},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "unexpected key type \"Rsa4096\"; expected \"Aes256\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "wrapped-bsr-key-invalid-key-encoding",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedBsrKey: &wrapping.KeyInfo{
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Pkix,
|
|
|
|
|
},
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeyBsrSignature: &testValidPubKeySignature,
|
|
|
|
|
},
|
|
|
|
|
opt: []kms.Option{kms.WithBsrWrapper(testBsrWrapper)},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "unexpected key encoding \"Pkix\"; expected \"Bytes\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "wrapped-bsr-key-invalid-wrapper",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
WrappedBsrKey: &wrapping.KeyInfo{
|
|
|
|
|
WrappedKey: marshaledBsrBlob,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeyBsrSignature: &testValidPubKeySignature,
|
|
|
|
|
},
|
|
|
|
|
opt: []kms.Option{kms.WithBsrWrapper(kms.TestWrapper(t))},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrDecrypt,
|
|
|
|
|
wantErrContains: "error unwrapping bsr key",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "mismatched-key-id",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
BsrKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: testBytes,
|
|
|
|
|
KeyId: "mismatched-key-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeyBsrSignature: &testValidPubKeySignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
2023-03-27 13:24:02 -04:00
|
|
|
wantErrContains: "signature key id \"session-id\" doesn't match verifying key id \"mismatched-key-id\"",
|
2023-03-18 15:52:50 -04:00
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
for _, tc := range tests {
|
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
|
|
|
got, err := tc.bsrKeys.VerifyPubKeyBsrSignature(testCtx, tc.opt...)
|
|
|
|
|
if tc.wantErr {
|
|
|
|
|
require.Error(err)
|
|
|
|
|
assert.Empty(got)
|
|
|
|
|
if tc.wantErrMatch != nil {
|
|
|
|
|
assert.ErrorIsf(err, tc.wantErrMatch, "expected %q and got err: %+v", tc.wantErrMatch, err)
|
|
|
|
|
}
|
|
|
|
|
if tc.wantErrContains != "" {
|
|
|
|
|
assert.Contains(err.Error(), tc.wantErrContains)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.Equal(tc.want, got)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func TestBsrKeys_VerifyPubKeySelfSignature(t *testing.T) {
|
|
|
|
|
t.Parallel()
|
|
|
|
|
testCtx := context.Background()
|
|
|
|
|
pub, priv, err := stdLibEd25519.GenerateKey(rand.Reader)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
privKeySigner, err := ed25519.NewSigner(testCtx, ed25519.WithPrivKey(priv), wrapping.WithKeyId("session-id"))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
testPubKeySelfSignature, err := privKeySigner.Sign(testCtx, pub)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
testInvalidPubKeySelfSignature, err := privKeySigner.Sign(testCtx, []byte("not-the-pub-key"))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
bsrKeys *kms.Keys
|
|
|
|
|
opt []kms.Option
|
|
|
|
|
want bool
|
|
|
|
|
wantErr bool
|
|
|
|
|
wantErrMatch error
|
|
|
|
|
wantErrContains string
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "not-equal",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeySelfSignature: testInvalidPubKeySelfSignature,
|
|
|
|
|
},
|
|
|
|
|
want: false,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "success",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeySelfSignature: testPubKeySelfSignature,
|
|
|
|
|
},
|
|
|
|
|
want: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-pub-key",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKeySelfSignature: testPubKeySelfSignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing pub key",
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
name: "missing-pub-key-bytes",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeySelfSignature: testPubKeySelfSignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing pub key bytes",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "invalid-key-type",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeySelfSignature: testPubKeySelfSignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "unexpected key type \"Aes256\"; expected \"Ed25519\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "invalid-key-encoding",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Pkcs8,
|
|
|
|
|
},
|
|
|
|
|
PubKeySelfSignature: testPubKeySelfSignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "unexpected key encoding \"Pkcs8\"; expected \"Bytes\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-signature",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing pub key self signature",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "mismatched-key-id",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: pub,
|
|
|
|
|
KeyId: "mismatched-key-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeySelfSignature: testPubKeySelfSignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "pub self signature key id \"session-id\" doesn't match verifying pub key id \"mismatched-key-id\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "bad-pub-key",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: []byte("bad-pub-key"),
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
},
|
|
|
|
|
PubKeySelfSignature: testPubKeySelfSignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "expected public key with 32 bytes and got 11",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
for _, tc := range tests {
|
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
|
|
|
got, err := tc.bsrKeys.VerifyPubKeySelfSignature(testCtx)
|
|
|
|
|
if tc.wantErr {
|
|
|
|
|
require.Error(err)
|
|
|
|
|
assert.Empty(got)
|
|
|
|
|
if tc.wantErrMatch != nil {
|
|
|
|
|
assert.ErrorIsf(err, tc.wantErrMatch, "expected %q and got err: %+v", tc.wantErrMatch, err)
|
|
|
|
|
}
|
|
|
|
|
if tc.wantErrContains != "" {
|
|
|
|
|
assert.Contains(err.Error(), tc.wantErrContains)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.Equal(tc.want, got)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-09 10:19:58 -04:00
|
|
|
func TestBsrKeys_VerifySignatureWithPubKey(t *testing.T) {
|
|
|
|
|
t.Parallel()
|
|
|
|
|
testCtx := context.Background()
|
|
|
|
|
|
|
|
|
|
keys, err := kms.CreateKeys(testCtx, kms.TestWrapper(t), "session")
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
message := "this is a super secret message!"
|
|
|
|
|
sig, err := keys.SignWithPrivKey(testCtx, []byte(message))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
require.NotNil(t, sig)
|
|
|
|
|
badMessage := "bad message###oh nooo"
|
|
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
bsrKeys *kms.Keys
|
|
|
|
|
verifyMessage string
|
|
|
|
|
opt []kms.Option
|
|
|
|
|
want bool
|
|
|
|
|
wantErr bool
|
|
|
|
|
wantErrMatch error
|
|
|
|
|
wantErrContains string
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "success",
|
|
|
|
|
bsrKeys: keys,
|
|
|
|
|
verifyMessage: message,
|
|
|
|
|
want: true,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "message-not-verified",
|
|
|
|
|
bsrKeys: keys,
|
|
|
|
|
verifyMessage: badMessage,
|
|
|
|
|
want: false,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-pub-key",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKeySelfSignature: keys.PubKeySelfSignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing pub key",
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
name: "missing-pub-key-bytes",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyId: keys.PubKey.KeyId,
|
|
|
|
|
KeyType: keys.PubKey.KeyType,
|
|
|
|
|
KeyEncoding: keys.PubKey.KeyEncoding,
|
|
|
|
|
},
|
|
|
|
|
PubKeySelfSignature: keys.PubKeySelfSignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing pub key bytes",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "invalid-key-type",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: keys.PubKey.Key,
|
|
|
|
|
KeyId: keys.PubKey.KeyId,
|
|
|
|
|
KeyType: wrapping.KeyType_Aes256,
|
|
|
|
|
KeyEncoding: keys.PubKey.KeyEncoding,
|
|
|
|
|
},
|
|
|
|
|
PubKeySelfSignature: keys.PubKeySelfSignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "unexpected key type \"Aes256\"; expected \"Ed25519\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "invalid-key-encoding",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: keys.PubKey.Key,
|
|
|
|
|
KeyId: keys.PubKey.KeyId,
|
|
|
|
|
KeyType: keys.PubKey.KeyType,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Pkcs8,
|
|
|
|
|
},
|
|
|
|
|
PubKeySelfSignature: keys.PubKeySelfSignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "unexpected key encoding \"Pkcs8\"; expected \"Bytes\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "bad-pub-key",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PubKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: []byte("bad-pub-key"),
|
|
|
|
|
KeyId: keys.PubKey.KeyId,
|
|
|
|
|
KeyType: keys.PubKey.KeyType,
|
|
|
|
|
KeyEncoding: keys.PubKey.KeyEncoding,
|
|
|
|
|
},
|
|
|
|
|
PubKeySelfSignature: keys.PubKeySelfSignature,
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "expected public key with 32 bytes and got 11",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
for _, tc := range tests {
|
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
|
|
|
|
|
|
|
|
got, err := tc.bsrKeys.VerifySignatureWithPubKey(testCtx, sig, []byte(tc.verifyMessage))
|
|
|
|
|
if tc.wantErr {
|
|
|
|
|
require.Error(err)
|
|
|
|
|
assert.Empty(got)
|
|
|
|
|
if tc.wantErrMatch != nil {
|
|
|
|
|
assert.ErrorIsf(err, tc.wantErrMatch, "expected %q and got err: %+v", tc.wantErrMatch, err)
|
|
|
|
|
}
|
|
|
|
|
if tc.wantErrContains != "" {
|
|
|
|
|
assert.Contains(err.Error(), tc.wantErrContains)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.Equal(tc.want, got)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-18 15:52:50 -04:00
|
|
|
func TestBsrKeys_SignWithPrivKey(t *testing.T) {
|
|
|
|
|
t.Parallel()
|
|
|
|
|
testCtx := context.Background()
|
|
|
|
|
|
|
|
|
|
_, priv, err := stdLibEd25519.GenerateKey(rand.Reader)
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
testMsg := []byte("test-msg")
|
|
|
|
|
testSig, err := priv.Sign(nil, testMsg, stdcrypto.Hash(0))
|
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
|
name string
|
|
|
|
|
bsrKeys *kms.Keys
|
|
|
|
|
msg []byte
|
|
|
|
|
want *wrapping.SigInfo
|
|
|
|
|
wantErr bool
|
|
|
|
|
wantErrMatch error
|
|
|
|
|
wantErrContains string
|
|
|
|
|
}{
|
|
|
|
|
{
|
|
|
|
|
name: "success",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PrivKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: priv,
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
KeyPurposes: []wrapping.KeyPurpose{wrapping.KeyPurpose_Sign},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
msg: testMsg,
|
|
|
|
|
want: &wrapping.SigInfo{
|
|
|
|
|
KeyInfo: &wrapping.KeyInfo{
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyPurposes: []wrapping.KeyPurpose{wrapping.KeyPurpose_Sign},
|
|
|
|
|
},
|
|
|
|
|
Signature: testSig,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-msg",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PrivKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: priv,
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
KeyPurposes: []wrapping.KeyPurpose{wrapping.KeyPurpose_Sign},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing msg",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-priv-key",
|
|
|
|
|
bsrKeys: &kms.Keys{},
|
|
|
|
|
msg: testMsg,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing priv key",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-priv-key-id",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PrivKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: priv,
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
KeyPurposes: []wrapping.KeyPurpose{wrapping.KeyPurpose_Sign},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
msg: testMsg,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing priv key id",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "missing-key-bytes",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PrivKey: &wrapping.KeyInfo{
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
KeyPurposes: []wrapping.KeyPurpose{wrapping.KeyPurpose_Sign},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
msg: testMsg,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "missing priv key bytes",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "invalid-key-type",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PrivKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: priv,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
KeyPurposes: []wrapping.KeyPurpose{wrapping.KeyPurpose_Sign},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
msg: testMsg,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "unexpected key type \"Unknown_KeyType\"; expected \"Ed25519\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "invalid-key-encoding",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PrivKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: priv,
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyPurposes: []wrapping.KeyPurpose{wrapping.KeyPurpose_Sign},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
msg: testMsg,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "unexpected key encoding \"Unknown_KeyEncoding\"; expected \"Bytes\"",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
name: "invalid-key-len",
|
|
|
|
|
bsrKeys: &kms.Keys{
|
|
|
|
|
PrivKey: &wrapping.KeyInfo{
|
|
|
|
|
Key: []byte("invalid-len"),
|
|
|
|
|
KeyType: wrapping.KeyType_Ed25519,
|
|
|
|
|
KeyId: "session-id",
|
|
|
|
|
KeyEncoding: wrapping.KeyEncoding_Bytes,
|
|
|
|
|
KeyPurposes: []wrapping.KeyPurpose{wrapping.KeyPurpose_Sign},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
msg: testMsg,
|
|
|
|
|
wantErr: true,
|
|
|
|
|
wantErrMatch: kms.ErrInvalidParameter,
|
|
|
|
|
wantErrContains: "expected priv key with 64 bytes and got 11",
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
for _, tc := range tests {
|
|
|
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
|
|
|
assert, require := assert.New(t), require.New(t)
|
|
|
|
|
got, err := tc.bsrKeys.SignWithPrivKey(testCtx, tc.msg)
|
|
|
|
|
if tc.wantErr {
|
|
|
|
|
require.Error(err)
|
|
|
|
|
assert.Empty(got)
|
|
|
|
|
if tc.wantErrMatch != nil {
|
|
|
|
|
assert.ErrorIsf(err, tc.wantErrMatch, "expected %q and got err: %+v", tc.wantErrMatch, err)
|
|
|
|
|
}
|
|
|
|
|
if tc.wantErrContains != "" {
|
|
|
|
|
assert.Contains(err.Error(), tc.wantErrContains)
|
|
|
|
|
}
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
require.NoError(err)
|
|
|
|
|
assert.Equal(tc.want, got)
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|