diff --git a/app/app.go b/app/app.go index 766a3c7..8c535f2 100644 --- a/app/app.go +++ b/app/app.go @@ -120,6 +120,7 @@ import ( daomodule "planetmint-go/x/dao" daomodulekeeper "planetmint-go/x/dao/keeper" daomoduletypes "planetmint-go/x/dao/types" + // this line is used by starport scaffolding # stargate/app/moduleImport appparams "planetmint-go/app/params" @@ -311,6 +312,7 @@ func New( feegrant.StoreKey, evidencetypes.StoreKey, ibctransfertypes.StoreKey, icahosttypes.StoreKey, capabilitytypes.StoreKey, group.StoreKey, icacontrollertypes.StoreKey, consensusparamtypes.StoreKey, machinemoduletypes.StoreKey, machinemoduletypes.TAIndexKey, machinemoduletypes.IssuerPlanetmintIndexKey, machinemoduletypes.IssuerLiquidIndexKey, + machinemoduletypes.TrustAnchorKey, assetmoduletypes.StoreKey, daomoduletypes.StoreKey, // this line is used by starport scaffolding # stargate/app/storeKey diff --git a/tests/e2e/asset/suite.go b/tests/e2e/asset/suite.go index 68785da..6db1b68 100644 --- a/tests/e2e/asset/suite.go +++ b/tests/e2e/asset/suite.go @@ -68,7 +68,8 @@ func (s *E2ETestSuite) SetupSuite() { s.Require().NoError(s.network.WaitForNextBlock()) - machine := sample.Machine(sample.Name, sample.PubKey) + pubKey, prvKey := sample.KeyPair() + machine := sample.Machine(sample.Name, pubKey, prvKey) machineJSON, err := json.Marshal(&machine) s.Require().NoError(err) diff --git a/tests/e2e/machine/rest.go b/tests/e2e/machine/rest.go index f06b8fe..f57aaa1 100644 --- a/tests/e2e/machine/rest.go +++ b/tests/e2e/machine/rest.go @@ -21,7 +21,8 @@ func (s *E2ETestSuite) TestAttestMachineREST() { s.Require().NoError(err) // Create Attest Machine TX - machine := sample.Machine(sample.Name, sample.PubKey) + pubKey, prvKey := sample.KeyPair() + machine := sample.Machine(sample.Name, pubKey, prvKey) msg := machinetypes.MsgAttestMachine{ Creator: addr.String(), Machine: &machine, @@ -42,7 +43,7 @@ func (s *E2ETestSuite) TestAttestMachineREST() { s.Require().NoError(err) s.Require().Equal(uint32(0), txRes.TxResponse.Code) - queryMachineUrl := fmt.Sprintf("%s/planetmint-go/machine/get_machine_by_public_key/%s", baseURL, sample.PubKey) + queryMachineUrl := fmt.Sprintf("%s/planetmint-go/machine/get_machine_by_public_key/%s", baseURL, pubKey) queryMachineRes, err := testutil.GetRequest(queryMachineUrl) s.Require().NoError(err) diff --git a/tests/e2e/machine/suite.go b/tests/e2e/machine/suite.go index 08ccb09..e32bc29 100644 --- a/tests/e2e/machine/suite.go +++ b/tests/e2e/machine/suite.go @@ -73,20 +73,19 @@ func (s *E2ETestSuite) TestAttestMachine() { val := s.network.Validators[0] // register Ta + prvKey, pubKey := sample.KeyPair() - machine := sample.Machine(sample.Name, sample.PubKey) - machineJSON, err := json.Marshal(&machine) + ta := sample.TrustAnchor(pubKey) + taJSON, err := json.Marshal(&ta) s.Require().NoError(err) - args := []string{ fmt.Sprintf("--%s=%s", flags.FlagChainID, s.network.Config.ChainID), fmt.Sprintf("--%s=%s", flags.FlagFrom, sample.Name), fmt.Sprintf("--%s=%s", flags.FlagFees, sample.Fees), "--yes", - string(machineJSON), + string(taJSON), } - - out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, machinecli.CmdAttestMachine(), args) + out, err := clitestutil.ExecTestCLICmd(val.ClientCtx, machinecli.CmdRegisterTrustAnchor(), args) s.Require().NoError(err) txResponse, err := clitestutil.GetTxResponseFromOut(out) @@ -96,10 +95,34 @@ func (s *E2ETestSuite) TestAttestMachine() { rawLog, err := clitestutil.GetRawLogFromTxResponse(val, txResponse) s.Require().NoError(err) + assert.Contains(s.T(), rawLog, "planetmintgo.machine.MsgRegisterTrustAnchor") + + machine := sample.Machine(sample.Name, pubKey, prvKey) + machineJSON, err := json.Marshal(&machine) + s.Require().NoError(err) + + args = []string{ + fmt.Sprintf("--%s=%s", flags.FlagChainID, s.network.Config.ChainID), + fmt.Sprintf("--%s=%s", flags.FlagFrom, sample.Name), + fmt.Sprintf("--%s=%s", flags.FlagFees, sample.Fees), + "--yes", + string(machineJSON), + } + + out, err = clitestutil.ExecTestCLICmd(val.ClientCtx, machinecli.CmdAttestMachine(), args) + s.Require().NoError(err) + + txResponse, err = clitestutil.GetTxResponseFromOut(out) + s.Require().NoError(err) + + s.Require().NoError(s.network.WaitForNextBlock()) + rawLog, err = clitestutil.GetRawLogFromTxResponse(val, txResponse) + s.Require().NoError(err) + assert.Contains(s.T(), rawLog, "planetmintgo.machine.MsgAttestMachine") args = []string{ - sample.PubKey, + pubKey, } _, err = clitestutil.ExecTestCLICmd(val.ClientCtx, machinecli.CmdGetMachineByPublicKey(), args) diff --git a/testutil/keeper/asset.go b/testutil/keeper/asset.go index 8d4e314..a407574 100644 --- a/testutil/keeper/asset.go +++ b/testutil/keeper/asset.go @@ -54,8 +54,8 @@ func AssetKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) { id := sample.MachineIndex(pk, ppk, lpk) mk.EXPECT().GetMachineIndex(ctx, pk).Return(id, true).AnyTimes() mk.EXPECT().GetMachineIndex(ctx, sk).Return(id, false).AnyTimes() - mk.EXPECT().GetMachine(ctx, id).Return(sample.Machine(pk, pk), true).AnyTimes() - mk.EXPECT().GetMachine(ctx, sk).Return(sample.Machine(pk, pk), false).AnyTimes() + mk.EXPECT().GetMachine(ctx, id).Return(sample.Machine(pk, pk, sk), true).AnyTimes() + mk.EXPECT().GetMachine(ctx, sk).Return(sample.Machine(pk, pk, sk), false).AnyTimes() k := keeper.NewKeeper( cdc, diff --git a/testutil/sample/sample.go b/testutil/sample/sample.go index 6158f7c..f924ad3 100644 --- a/testutil/sample/sample.go +++ b/testutil/sample/sample.go @@ -54,22 +54,30 @@ func Secp256k1AccAddress() sdk.AccAddress { return sdk.AccAddress(addr) } -func Machine(name, pubKey string) machinetypes.Machine { +func Machine(name, pubKey string, prvKey string) machinetypes.Machine { metadata := Metadata() _, liquidPubKey := ExtendedKeyPair(config.LiquidNetParams) _, planetmintPubKey := ExtendedKeyPair(config.PlmntNetParams) + + prvKeyBytes, _ := hex.DecodeString(prvKey) + sk := &secp256k1.PrivKey{Key: prvKeyBytes} + pubKeyBytes := []byte(pubKey) + sign, _ := sk.Sign(pubKeyBytes) + signatureHex := hex.EncodeToString(sign) + m := machinetypes.Machine{ - Name: name, - Ticker: name + "_ticker", - Domain: "lab.r3c.network", - Reissue: true, - Amount: 1000, - Precision: 8, - IssuerPlanetmint: planetmintPubKey, - IssuerLiquid: liquidPubKey, - MachineId: pubKey, - Metadata: &metadata, - Type: 1, + Name: name, + Ticker: name + "_ticker", + Domain: "lab.r3c.network", + Reissue: true, + Amount: 1000, + Precision: 8, + IssuerPlanetmint: planetmintPubKey, + IssuerLiquid: liquidPubKey, + MachineId: pubKey, + Metadata: &metadata, + Type: 1, + MachineIdSignature: signatureHex, } return m } @@ -121,8 +129,8 @@ func ExtendedKeyPair(cfg chaincfg.Params) (string, string) { return xprivKey.String(), xpubKey.String() } -func TrustAnchor() machinetypes.TrustAnchor { +func TrustAnchor(pubkey string) machinetypes.TrustAnchor { return machinetypes.TrustAnchor{ - Pubkey: PubKey, + Pubkey: pubkey, } } diff --git a/util/validate_signature.go b/util/validate_signature.go new file mode 100644 index 0000000..72959b8 --- /dev/null +++ b/util/validate_signature.go @@ -0,0 +1,22 @@ +package util + +import ( + "encoding/hex" + + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" +) + +func ValidateSignature(message string, signature string, publicKey string) bool { + // Convert the message, signature, and public key from hex to bytes + messageBytes := []byte(message) + signatureBytes, _ := hex.DecodeString(signature) + publicKeyBytes, _ := hex.DecodeString(publicKey) + + // Create a secp256k1 public key object + pubKey := &secp256k1.PubKey{Key: publicKeyBytes} + + // Verify the signature + isValid := pubKey.VerifySignature(messageBytes, signatureBytes) + + return isValid +} diff --git a/x/asset/keeper/msg_server_notarize_asset.go b/x/asset/keeper/msg_server_notarize_asset.go index bd596d1..3f2ed10 100644 --- a/x/asset/keeper/msg_server_notarize_asset.go +++ b/x/asset/keeper/msg_server_notarize_asset.go @@ -2,12 +2,11 @@ package keeper import ( "context" - "encoding/hex" "errors" + "planetmint-go/util" "planetmint-go/x/asset/types" - "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -20,7 +19,7 @@ func (k msgServer) NotarizeAsset(goCtx context.Context, msg *types.MsgNotarizeAs return nil, errors.New("machine not found") } - valid := ValidateSignature(msg.Hash, msg.Signature, msg.PubKey) + valid := util.ValidateSignature(msg.Hash, msg.Signature, msg.PubKey) if !valid { return nil, errors.New("invalid signature") } @@ -35,18 +34,3 @@ func (k msgServer) NotarizeAsset(goCtx context.Context, msg *types.MsgNotarizeAs return &types.MsgNotarizeAssetResponse{}, nil } - -func ValidateSignature(message string, signature string, publicKey string) bool { - // Convert the message, signature, and public key from hex to bytes - messageBytes := []byte(message) - signatureBytes, _ := hex.DecodeString(signature) - publicKeyBytes, _ := hex.DecodeString(publicKey) - - // Create a secp256k1 public key object - pubKey := &secp256k1.PubKey{Key: publicKeyBytes} - - // Verify the signature - isValid := pubKey.VerifySignature(messageBytes, signatureBytes) - - return isValid -} diff --git a/x/machine/keeper/msg_server_attest_machine.go b/x/machine/keeper/msg_server_attest_machine.go index 86600b8..61bb9a9 100644 --- a/x/machine/keeper/msg_server_attest_machine.go +++ b/x/machine/keeper/msg_server_attest_machine.go @@ -6,6 +6,7 @@ import ( "strconv" config "planetmint-go/config" + "planetmint-go/util" "planetmint-go/x/machine/types" "github.com/btcsuite/btcd/btcutil/hdkeychain" @@ -32,6 +33,11 @@ func (k msgServer) AttestMachine(goCtx context.Context, msg *types.MsgAttestMach return nil, errors.New("trust anchor has already been used for attestation") } + isValidMachineId := util.ValidateSignature(msg.Machine.MachineId, msg.Machine.MachineIdSignature, msg.Machine.MachineId) + if !isValidMachineId { + return nil, errors.New("invalid machine id") + } + isValidIssuerPlanetmint := validateExtendedPublicKey(msg.Machine.IssuerPlanetmint, config.PlmntNetParams) if !isValidIssuerPlanetmint { return nil, errors.New("invalid planetmint key") diff --git a/x/machine/keeper/msg_server_test.go b/x/machine/keeper/msg_server_test.go index b7d2ccd..09889ba 100644 --- a/x/machine/keeper/msg_server_test.go +++ b/x/machine/keeper/msg_server_test.go @@ -27,10 +27,10 @@ func TestMsgServer(t *testing.T) { } func TestMsgServerAttestMachine(t *testing.T) { - _, pk := sample.KeyPair() - ta := sample.TrustAnchor() + sk, pk := sample.KeyPair() + ta := sample.TrustAnchor(pk) taMsg := types.NewMsgRegisterTrustAnchor(pk, &ta) - machine := sample.Machine(pk, ta.Pubkey) + machine := sample.Machine(pk, pk, sk) msg := types.NewMsgAttestMachine(pk, &machine) msgServer, ctx := setupMsgServer(t) _, err := msgServer.RegisterTrustAnchor(ctx, taMsg) @@ -42,10 +42,10 @@ func TestMsgServerAttestMachine(t *testing.T) { } func TestMsgServerAttestMachineInvalidLiquidKey(t *testing.T) { - _, pk := sample.KeyPair() - ta := sample.TrustAnchor() + sk, pk := sample.KeyPair() + ta := sample.TrustAnchor(pk) taMsg := types.NewMsgRegisterTrustAnchor(pk, &ta) - machine := sample.Machine(pk, ta.Pubkey) + machine := sample.Machine(pk, pk, sk) machine.IssuerLiquid = "invalidkey" msg := types.NewMsgAttestMachine(pk, &machine) msgServer, ctx := setupMsgServer(t) @@ -57,7 +57,7 @@ func TestMsgServerAttestMachineInvalidLiquidKey(t *testing.T) { func TestMsgServerRegisterTrustAnchor(t *testing.T) { _, pk := sample.KeyPair() - ta := sample.TrustAnchor() + ta := sample.TrustAnchor(pk) msg := types.NewMsgRegisterTrustAnchor(pk, &ta) msgServer, ctx := setupMsgServer(t) res, err := msgServer.RegisterTrustAnchor(ctx, msg) @@ -68,7 +68,7 @@ func TestMsgServerRegisterTrustAnchor(t *testing.T) { func TestMsgServerRegisterTrustAnchorTwice(t *testing.T) { _, pk := sample.KeyPair() - ta := sample.TrustAnchor() + ta := sample.TrustAnchor(pk) msg := types.NewMsgRegisterTrustAnchor(pk, &ta) msgServer, ctx := setupMsgServer(t) res, err := msgServer.RegisterTrustAnchor(ctx, msg)