From 0162cabe6f539770b4d24634651e029056cd81ee Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 21 Aug 2024 08:15:33 +0200 Subject: [PATCH 1/3] fix(config): panic when loading invalid node key file --- config/config.go | 5 +++++ types/node_key.go | 11 +++++++++++ 2 files changed, 16 insertions(+) diff --git a/config/config.go b/config/config.go index 61345faebc..afc0ced999 100644 --- a/config/config.go +++ b/config/config.go @@ -300,6 +300,11 @@ func (cfg BaseConfig) LoadNodeKeyID() (types.NodeID, error) { if err != nil { return "", err } + + if err = nodeKey.Validate(); err != nil { + return "", fmt.Errorf("invalid node key file %s: %w", cfg.NodeKeyFile(), err) + } + nodeKey.ID = types.NodeIDFromPubKey(nodeKey.PubKey()) return nodeKey.ID, nil } diff --git a/types/node_key.go b/types/node_key.go index 91fbe09b31..07ccf0e30f 100644 --- a/types/node_key.go +++ b/types/node_key.go @@ -2,6 +2,7 @@ package types import ( "encoding/json" + "fmt" "os" "github.com/dashpay/tenderdash/crypto" @@ -38,6 +39,16 @@ func (nk NodeKey) MarshalJSON() ([]byte, error) { }) } +func (nk *NodeKey) Validate() error { + if nk.PrivKey == nil { + return fmt.Errorf("invalid or empty private key") + } + if err := nk.ID.Validate(); err != nil { + return fmt.Errorf("invalid key ID: %w", err) + } + return nil +} + func (nk *NodeKey) UnmarshalJSON(data []byte) error { var nkjson nodeKeyJSON if err := json.Unmarshal(data, &nkjson); err != nil { From dd10bcd42eff8eb3d8621473915f16c1fd9d7706 Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 21 Aug 2024 08:36:23 +0200 Subject: [PATCH 2/3] chore: verify node key id matches pubkey --- types/node_key.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/types/node_key.go b/types/node_key.go index 07ccf0e30f..257f42abef 100644 --- a/types/node_key.go +++ b/types/node_key.go @@ -44,7 +44,11 @@ func (nk *NodeKey) Validate() error { return fmt.Errorf("invalid or empty private key") } if err := nk.ID.Validate(); err != nil { - return fmt.Errorf("invalid key ID: %w", err) + return fmt.Errorf("invalid node ID: %w", err) + } + keyID := NodeIDFromPubKey(nk.PrivKey.PubKey()) + if nk.ID != keyID { + return fmt.Errorf("saved node ID %s does not match public key %s", nk.ID, keyID) } return nil } From f10f30359cf08c4c2832536045e3e135e700ac7a Mon Sep 17 00:00:00 2001 From: Lukasz Klimek <842586+lklimek@users.noreply.github.com> Date: Wed, 21 Aug 2024 08:36:49 +0200 Subject: [PATCH 3/3] test(config): TestLoadNodeKeyID --- config/config_test.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/config/config_test.go b/config/config_test.go index 5833f00e1b..03c70fe81c 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1,6 +1,7 @@ package config import ( + "os" "reflect" "testing" "time" @@ -223,3 +224,39 @@ func TestP2PConfigValidateBasic(t *testing.T) { reflect.ValueOf(cfg).Elem().FieldByName(fieldName).SetInt(0) } } + +// Given some invalid node key file, when I try to load it, I get an error +func TestLoadNodeKeyID(t *testing.T) { + + testCases := []string{ + `{ + "type": "tendermint/PrivKeyEd25519", + "value": "wIVaBy3v4bKcrBxGsgFen9qJeqXiK4h18iWCM2LSYxMyH8PomXsANUb3KoucY9EBDj0NQi4LqrmG8DyT5D6xWQ==" +}`, + `{ + "id":"0d846d89021b617026c3a3d4051ebcf4cdd09f7c", + "priv_key":{ + "type":"tendermint/PrivKeyEd25519", + "value":"J5EWnwSixAZuuw2Gf5nbXXNbyliaURFgBawfwN+zU/N7ucjnxu0GLcVi107XEj2Myq95101jcPPcJE+dCncY1A==" + } +}`, + } + + for _, tc := range testCases { + t.Run("", func(t *testing.T) { + cfg := DefaultBaseConfig() + tmpDir := t.TempDir() + + // create invalid node key file + cfg.NodeKey = tmpDir + "/node_key.json" + err := os.WriteFile(cfg.NodeKey, []byte(tc), 0600) + require.NoError(t, err) + + // when I try to load the node key + _, err = cfg.LoadNodeKeyID() + + // then I get an error + assert.Error(t, err) + }) + } +}