feat(bsr): add VerifySignatureWithPubKey to kms methods

This commit is contained in:
irenarindos authored and Timothy Messier committed 2023-05-31 12:18:16 +00:00
1 parent 18eca382c6
commit 3e9a4bf03e
3 files changed
+172 -12

No files matched your search

+4
View File
@@ -177,6 +177,10 @@ func TestFile(t *testing.T) {
err = proto.Unmarshal(tc.sig.Bytes(), sigInfo)
require.NoError(t, err)
verified, err := keys.VerifySignatureWithPubKey(ctx, sigInfo, []byte(tc.write))
require.NoError(t, err)
require.True(t, verified)
want, err := keys.SignWithPrivKey(ctx, []byte(tc.write))
require.NoError(t, err)
assert.Empty(t,
+41 -12
View File
@@ -325,8 +325,6 @@ func (k *Keys) VerifyPubKeySelfSignature(ctx context.Context) (bool, error) {
if k == nil {
return false, fmt.Errorf("%s: bsr keys: %w", op, ErrInvalidParameter)
}
k.l.RLock()
defer k.l.RUnlock()
switch {
case k.PubKey == nil:
@@ -345,16 +343,7 @@ func (k *Keys) VerifyPubKeySelfSignature(ctx context.Context) (bool, error) {
return false, fmt.Errorf("%s: pub self signature key id %q doesn't match verifying pub key id %q: %w", op, k.PubKeySelfSignature.KeyInfo.KeyId, k.PubKey.KeyId, ErrInvalidParameter)
}
verifier, err := wrappingEd.NewVerifier(ctx, wrappingEd.WithPubKey(k.PubKey.Key))
if err != nil {
return false, fmt.Errorf("%s: %w", op, err)
}
ok, err := verifier.Verify(ctx, k.PubKey.Key, k.PubKeySelfSignature)
if err != nil {
return false, fmt.Errorf("%s: %w", op, err)
}
return ok, nil
return k.VerifySignatureWithPubKey(ctx, k.PubKeySelfSignature, k.PubKey.Key)
}
// SignWithPrivKey will sign the msg with the BsrKeys.PrivKey (aka the BSR's
@@ -402,6 +391,46 @@ func (k *Keys) SignWithPrivKey(ctx context.Context, msg []byte) (*wrapping.SigIn
return si, nil
}
// VerifySignatureWithPubKey will verify a signature using the k.PubKey.
//
// This is a concurrently safe operation.
func (k *Keys) VerifySignatureWithPubKey(ctx context.Context, sig *wrapping.SigInfo, msg []byte) (bool, error) {
const op = "kms.(BsrKeys).VerifySignatureWithPubKey"
if k == nil {
return false, fmt.Errorf("%s: bsr keys: %w", op, ErrInvalidParameter)
}
k.l.RLock()
defer k.l.RUnlock()
switch {
case k.PubKey == nil:
return false, fmt.Errorf("%s: missing pub key: %w", op, ErrInvalidParameter)
case k.PubKey.Key == nil:
return false, fmt.Errorf("%s: missing pub key bytes: %w", op, ErrInvalidParameter)
case k.PubKey.KeyType != wrapping.KeyType_Ed25519:
return false, keyTypeError(ctx, op, wrapping.KeyType_Ed25519, k.PubKey.KeyType)
case k.PubKey.KeyEncoding != wrapping.KeyEncoding_Bytes:
return false, keyEncodingError(ctx, op, wrapping.KeyEncoding_Bytes, k.PubKey.KeyEncoding)
case len(k.PubKey.Key) != ed25519.PublicKeySize:
return false, fmt.Errorf("%s: expected public key with %d bytes and got %d: %w", op, ed25519.PublicKeySize, len(k.PubKey.Key), ErrInvalidParameter)
case sig == nil:
return false, fmt.Errorf("%s: missing signature info: %w", op, ErrInvalidParameter)
case msg == nil:
return false, fmt.Errorf("%s: missing message: %w", op, ErrInvalidParameter)
}
verifier, err := wrappingEd.NewVerifier(ctx, wrappingEd.WithPubKey(k.PubKey.Key))
if err != nil {
return false, fmt.Errorf("%s: %w", op, err)
}
ok, err := verifier.Verify(ctx, msg, sig)
if err != nil {
return false, fmt.Errorf("%s: %w", op, err)
}
return ok, nil
}
func (k *Keys) VerifySignatureWithBsrKey(ctx context.Context, sig *wrapping.SigInfo, msg []byte, opt ...Option) (bool, error) {
const op = "kms.(BsrKeys).VerifySignatureWithBsrKey"
if k == nil {
+127
View File
@@ -1206,6 +1206,133 @@ func TestBsrKeys_VerifyPubKeySelfSignature(t *testing.T) {
}
}
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)
})
}
}
func TestBsrKeys_SignWithPrivKey(t *testing.T) {
t.Parallel()
testCtx := context.Background()