fix mismatched solomachine signature data type verification (#7882)
* fix mismatched signature data type verification * update godoc Co-authored-by: Federico Kunze <31522760+fedekunze@users.noreply.github.com>
This commit is contained in:
parent
0895a2ab92
commit
0bd46574f4
@ -15,32 +15,34 @@ import (
|
||||
|
||||
// VerifySignature verifies if the the provided public key generated the signature
|
||||
// over the given data. Single and Multi signature public keys are supported.
|
||||
// The type of the signature data determines how the public key is used to
|
||||
// verify the signature. An error is returned if signature verification fails
|
||||
// or an invalid SignatureData type is provided.
|
||||
// The signature data type must correspond to the public key type. An error is
|
||||
// returned if signature verification fails or an invalid SignatureData type is
|
||||
// provided.
|
||||
func VerifySignature(pubKey cryptotypes.PubKey, signBytes []byte, sigData signing.SignatureData) error {
|
||||
switch data := sigData.(type) {
|
||||
case *signing.SingleSignatureData:
|
||||
if !pubKey.VerifySignature(signBytes, data.Signature) {
|
||||
return ErrSignatureVerificationFailed
|
||||
}
|
||||
|
||||
case *signing.MultiSignatureData:
|
||||
multiPK, ok := pubKey.(multisig.PubKey)
|
||||
switch pubKey := pubKey.(type) {
|
||||
case multisig.PubKey:
|
||||
data, ok := sigData.(*signing.MultiSignatureData)
|
||||
if !ok {
|
||||
return sdkerrors.Wrapf(ErrSignatureVerificationFailed, "invalid pubkey type: expected %T, got %T", (multisig.PubKey)(nil), pubKey)
|
||||
return sdkerrors.Wrapf(ErrSignatureVerificationFailed, "invalid signature data type, expected %T, got %T", (*signing.MultiSignatureData)(nil), data)
|
||||
}
|
||||
|
||||
// The function supplied fulfills the VerifyMultisignature interface. No special
|
||||
// adjustments need to be made to the sign bytes based on the sign mode.
|
||||
if err := multiPK.VerifyMultisignature(func(signing.SignMode) ([]byte, error) {
|
||||
if err := pubKey.VerifyMultisignature(func(signing.SignMode) ([]byte, error) {
|
||||
return signBytes, nil
|
||||
}, data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
default:
|
||||
return sdkerrors.Wrapf(ErrSignatureVerificationFailed, "unsupported signature data type %T", data)
|
||||
data, ok := sigData.(*signing.SingleSignatureData)
|
||||
if !ok {
|
||||
return sdkerrors.Wrapf(ErrSignatureVerificationFailed, "invalid signature data type, expected %T, got %T", (*signing.SingleSignatureData)(nil), data)
|
||||
}
|
||||
|
||||
if !pubKey.VerifySignature(signBytes, data.Signature) {
|
||||
return ErrSignatureVerificationFailed
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@ -1,10 +1,72 @@
|
||||
package types_test
|
||||
|
||||
import (
|
||||
cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types"
|
||||
"github.com/cosmos/cosmos-sdk/types/tx/signing"
|
||||
"github.com/cosmos/cosmos-sdk/x/ibc/light-clients/06-solomachine/types"
|
||||
solomachinetypes "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/06-solomachine/types"
|
||||
ibctesting "github.com/cosmos/cosmos-sdk/x/ibc/testing"
|
||||
)
|
||||
|
||||
func (suite *SoloMachineTestSuite) TestVerifySignature() {
|
||||
cdc := suite.chainA.App.AppCodec()
|
||||
signBytes := []byte("sign bytes")
|
||||
|
||||
singleSignature := suite.solomachine.GenerateSignature(signBytes)
|
||||
singleSigData, err := solomachinetypes.UnmarshalSignatureData(cdc, singleSignature)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
multiSignature := suite.solomachineMulti.GenerateSignature(signBytes)
|
||||
multiSigData, err := solomachinetypes.UnmarshalSignatureData(cdc, multiSignature)
|
||||
suite.Require().NoError(err)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
publicKey cryptotypes.PubKey
|
||||
sigData signing.SignatureData
|
||||
expPass bool
|
||||
}{
|
||||
{
|
||||
"single signature with regular public key",
|
||||
suite.solomachine.PublicKey,
|
||||
singleSigData,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"multi signature with multisig public key",
|
||||
suite.solomachineMulti.PublicKey,
|
||||
multiSigData,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"single signature with multisig public key",
|
||||
suite.solomachineMulti.PublicKey,
|
||||
singleSigData,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"multi signature with regular public key",
|
||||
suite.solomachine.PublicKey,
|
||||
multiSigData,
|
||||
false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
|
||||
suite.Run(tc.name, func() {
|
||||
err := solomachinetypes.VerifySignature(tc.publicKey, signBytes, tc.sigData)
|
||||
|
||||
if tc.expPass {
|
||||
suite.Require().NoError(err)
|
||||
} else {
|
||||
suite.Require().Error(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *SoloMachineTestSuite) TestClientStateSignBytes() {
|
||||
cdc := suite.chainA.App.AppCodec()
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user