forked from gnolang/gno
-
Notifications
You must be signed in to change notification settings - Fork 0
/
secrets_verify.go
161 lines (131 loc) · 4.36 KB
/
secrets_verify.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package main
import (
"context"
"flag"
"fmt"
"path/filepath"
"github.com/gnolang/gno/tm2/pkg/bft/privval"
"github.com/gnolang/gno/tm2/pkg/commands"
"github.com/gnolang/gno/tm2/pkg/p2p"
)
type secretsVerifyCfg struct {
commonAllCfg
}
// newSecretsVerifyCmd creates the secrets verify command
func newSecretsVerifyCmd(io commands.IO) *commands.Command {
cfg := &secretsVerifyCfg{}
return commands.NewCommand(
commands.Metadata{
Name: "verify",
ShortUsage: "secrets verify [flags] [<key>]",
ShortHelp: "verifies all Gno secrets in a common directory",
LongHelp: fmt.Sprintf(
"verifies the validator private key, the node p2p key and the validator's last sign state. "+
"If a key is provided, it verifies the specified key value. Available keys: %s",
getAvailableSecretsKeys(),
),
},
cfg,
func(_ context.Context, args []string) error {
return execSecretsVerify(cfg, args, io)
},
)
}
func (c *secretsVerifyCfg) RegisterFlags(fs *flag.FlagSet) {
c.commonAllCfg.RegisterFlags(fs)
}
func execSecretsVerify(cfg *secretsVerifyCfg, args []string, io commands.IO) error {
// Make sure the directory is there
if cfg.dataDir == "" || !isValidDirectory(cfg.dataDir) {
return errInvalidDataDir
}
// Verify the secrets key
if err := verifySecretsKey(args); err != nil {
return err
}
var key string
if len(args) > 0 {
key = args[0]
}
// Construct the paths
var (
validatorKeyPath = filepath.Join(cfg.dataDir, defaultValidatorKeyName)
validatorStatePath = filepath.Join(cfg.dataDir, defaultValidatorStateName)
nodeKeyPath = filepath.Join(cfg.dataDir, defaultNodeKeyName)
)
switch key {
case validatorPrivateKeyKey:
// Validate the validator's private key
_, err := readAndVerifyValidatorKey(validatorKeyPath, io)
return err
case validatorStateKey:
// Validate the validator's last sign state
validatorState, err := readAndVerifyValidatorState(validatorStatePath, io)
if err != nil {
return err
}
// Attempt to read the validator key
if validatorKey, err := readAndVerifyValidatorKey(validatorKeyPath, io); validatorKey != nil && err == nil {
// Validate the signature bytes
return validateValidatorStateSignature(validatorState, validatorKey.PubKey)
} else {
io.Println("WARN: Skipped verification of validator state, as validator key is not present")
}
return nil
case nodeIDKey:
return readAndVerifyNodeKey(nodeKeyPath, io)
default:
// Validate the validator's private key
validatorKey, err := readAndVerifyValidatorKey(validatorKeyPath, io)
if err != nil {
return err
}
// Validate the validator's last sign state
validatorState, err := readAndVerifyValidatorState(validatorStatePath, io)
if err != nil {
return err
}
// Validate the signature bytes
if err = validateValidatorStateSignature(validatorState, validatorKey.PubKey); err != nil {
return err
}
// Validate the node's p2p key
return readAndVerifyNodeKey(nodeKeyPath, io)
}
}
// readAndVerifyValidatorKey reads the validator key from the given path and verifies it
func readAndVerifyValidatorKey(path string, io commands.IO) (*privval.FilePVKey, error) {
validatorKey, err := readSecretData[privval.FilePVKey](path)
if err != nil {
return nil, fmt.Errorf("unable to read validator key, %w", err)
}
if err := validateValidatorKey(validatorKey); err != nil {
return nil, err
}
io.Printfln("Validator Private Key at %s is valid", path)
return validatorKey, nil
}
// readAndVerifyValidatorState reads the validator state from the given path and verifies it
func readAndVerifyValidatorState(path string, io commands.IO) (*privval.FilePVLastSignState, error) {
validatorState, err := readSecretData[privval.FilePVLastSignState](path)
if err != nil {
return nil, fmt.Errorf("unable to read last validator sign state, %w", err)
}
if err := validateValidatorState(validatorState); err != nil {
return nil, err
}
io.Printfln("Last Validator Sign state at %s is valid", path)
return validatorState, nil
}
// readAndVerifyNodeKey reads the node p2p key from the given path and verifies it
func readAndVerifyNodeKey(path string, io commands.IO) error {
nodeKey, err := readSecretData[p2p.NodeKey](path)
if err != nil {
return fmt.Errorf("unable to read node p2p key, %w", err)
}
if err := validateNodeKey(nodeKey); err != nil {
return err
}
io.Printfln("Node P2P key at %s is valid", path)
return nil
}