You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
2.5 KiB

  1. package types
  2. import (
  3. "encoding/json"
  4. "os"
  5. "github.com/tendermint/tendermint/crypto"
  6. "github.com/tendermint/tendermint/crypto/ed25519"
  7. "github.com/tendermint/tendermint/internal/jsontypes"
  8. tmos "github.com/tendermint/tendermint/libs/os"
  9. )
  10. //------------------------------------------------------------------------------
  11. // Persistent peer ID
  12. // TODO: encrypt on disk
  13. // NodeKey is the persistent peer key.
  14. // It contains the nodes private key for authentication.
  15. type NodeKey struct {
  16. // Canonical ID - hex-encoded pubkey's address (IDByteLength bytes)
  17. ID NodeID
  18. // Private key
  19. PrivKey crypto.PrivKey
  20. }
  21. type nodeKeyJSON struct {
  22. ID NodeID `json:"id"`
  23. PrivKey json.RawMessage `json:"priv_key"`
  24. }
  25. func (nk NodeKey) MarshalJSON() ([]byte, error) {
  26. pk, err := jsontypes.Marshal(nk.PrivKey)
  27. if err != nil {
  28. return nil, err
  29. }
  30. return json.Marshal(nodeKeyJSON{
  31. ID: nk.ID, PrivKey: pk,
  32. })
  33. }
  34. func (nk *NodeKey) UnmarshalJSON(data []byte) error {
  35. var nkjson nodeKeyJSON
  36. if err := json.Unmarshal(data, &nkjson); err != nil {
  37. return err
  38. }
  39. var pk crypto.PrivKey
  40. if err := jsontypes.Unmarshal(nkjson.PrivKey, &pk); err != nil {
  41. return err
  42. }
  43. *nk = NodeKey{ID: nkjson.ID, PrivKey: pk}
  44. return nil
  45. }
  46. // PubKey returns the peer's PubKey
  47. func (nk NodeKey) PubKey() crypto.PubKey {
  48. return nk.PrivKey.PubKey()
  49. }
  50. // SaveAs persists the NodeKey to filePath.
  51. func (nk NodeKey) SaveAs(filePath string) error {
  52. jsonBytes, err := json.Marshal(nk)
  53. if err != nil {
  54. return err
  55. }
  56. return os.WriteFile(filePath, jsonBytes, 0600)
  57. }
  58. // LoadOrGenNodeKey attempts to load the NodeKey from the given filePath. If
  59. // the file does not exist, it generates and saves a new NodeKey.
  60. func LoadOrGenNodeKey(filePath string) (NodeKey, error) {
  61. if tmos.FileExists(filePath) {
  62. nodeKey, err := LoadNodeKey(filePath)
  63. if err != nil {
  64. return NodeKey{}, err
  65. }
  66. return nodeKey, nil
  67. }
  68. nodeKey := GenNodeKey()
  69. if err := nodeKey.SaveAs(filePath); err != nil {
  70. return NodeKey{}, err
  71. }
  72. return nodeKey, nil
  73. }
  74. // GenNodeKey generates a new node key.
  75. func GenNodeKey() NodeKey {
  76. privKey := ed25519.GenPrivKey()
  77. return NodeKey{
  78. ID: NodeIDFromPubKey(privKey.PubKey()),
  79. PrivKey: privKey,
  80. }
  81. }
  82. // LoadNodeKey loads NodeKey located in filePath.
  83. func LoadNodeKey(filePath string) (NodeKey, error) {
  84. jsonBytes, err := os.ReadFile(filePath)
  85. if err != nil {
  86. return NodeKey{}, err
  87. }
  88. nodeKey := NodeKey{}
  89. err = json.Unmarshal(jsonBytes, &nodeKey)
  90. if err != nil {
  91. return NodeKey{}, err
  92. }
  93. nodeKey.ID = NodeIDFromPubKey(nodeKey.PubKey())
  94. return nodeKey, nil
  95. }