瀏覽代碼

Node: Keygen changes (#3401)

bruce-riley 2 年之前
父節點
當前提交
06d8f2d268

+ 7 - 1
node/cmd/guardiand/adminclient.go

@@ -21,6 +21,7 @@ import (
 	"github.com/spf13/pflag"
 	"golang.org/x/crypto/sha3"
 
+	"github.com/certusone/wormhole/node/pkg/common"
 	gossipv1 "github.com/certusone/wormhole/node/pkg/proto/gossip/v1"
 	publicrpcv1 "github.com/certusone/wormhole/node/pkg/proto/publicrpc/v1"
 	"github.com/wormhole-foundation/wormhole/sdk"
@@ -39,6 +40,7 @@ import (
 var (
 	clientSocketPath *string
 	shouldBackfill   *bool
+	unsafeDevnetMode *bool
 )
 
 func init() {
@@ -68,6 +70,10 @@ func init() {
 	SignExistingVaaCmd.Flags().AddFlagSet(pf)
 	SignExistingVaasFromCSVCmd.Flags().AddFlagSet(pf)
 
+	adminClientSignWormchainAddressFlags := pflag.NewFlagSet("adminClientSignWormchainAddressFlags", pflag.ContinueOnError)
+	unsafeDevnetMode = adminClientSignWormchainAddressFlags.Bool("unsafeDevMode", false, "Run in unsafe devnet mode")
+	AdminClientSignWormchainAddress.Flags().AddFlagSet(adminClientSignWormchainAddressFlags)
+
 	AdminCmd.AddCommand(AdminClientInjectGuardianSetUpdateCmd)
 	AdminCmd.AddCommand(AdminClientFindMissingMessagesCmd)
 	AdminCmd.AddCommand(AdminClientGovernanceVAAVerifyCmd)
@@ -225,7 +231,7 @@ func runSignWormchainValidatorAddress(cmd *cobra.Command, args []string) error {
 	if !strings.HasPrefix(wormchainAddress, "wormhole") || strings.HasPrefix(wormchainAddress, "wormholeval") {
 		return fmt.Errorf("must provide a bech32 address that has 'wormhole' prefix")
 	}
-	gk, err := loadGuardianKey(guardianKeyPath)
+	gk, err := common.LoadGuardianKey(guardianKeyPath, *unsafeDevnetMode)
 	if err != nil {
 		return fmt.Errorf("failed to load guardian key: %w", err)
 	}

+ 44 - 0
node/cmd/guardiand/keygen.go

@@ -0,0 +1,44 @@
+package guardiand
+
+import (
+	"crypto/ecdsa"
+	"crypto/rand"
+	"log"
+
+	"github.com/certusone/wormhole/node/pkg/common"
+
+	ethcrypto "github.com/ethereum/go-ethereum/crypto"
+	"github.com/spf13/cobra"
+)
+
+var keyDescription *string
+var blockType *string
+
+func init() {
+	keyDescription = KeygenCmd.Flags().String("desc", "", "Human-readable key description (optional)")
+	blockType = KeygenCmd.Flags().String("block-type", common.GuardianKeyArmoredBlock, "block type of armored file (optional)")
+}
+
+var KeygenCmd = &cobra.Command{
+	Use:   "keygen [KEYFILE]",
+	Short: "Create guardian key at the specified path",
+	Run:   runKeygen,
+	Args:  cobra.ExactArgs(1),
+}
+
+func runKeygen(cmd *cobra.Command, args []string) {
+	common.LockMemory()
+	common.SetRestrictiveUmask()
+
+	log.Print("Creating new key at ", args[0])
+
+	gk, err := ecdsa.GenerateKey(ethcrypto.S256(), rand.Reader)
+	if err != nil {
+		log.Fatalf("failed to generate key: %v", err)
+	}
+
+	err = common.WriteArmoredKey(gk, *keyDescription, args[0], *blockType, false)
+	if err != nil {
+		log.Fatalf("failed to write key: %v", err)
+	}
+}

+ 2 - 7
node/cmd/guardiand/node.go

@@ -781,15 +781,10 @@ func runNode(cmd *cobra.Command, args []string) {
 
 	// In devnet mode, we generate a deterministic guardian key and write it to disk.
 	if *unsafeDevMode {
-		gk, err := generateDevnetGuardianKey()
+		err := devnet.GenerateAndStoreDevnetGuardianKey(*guardianKeyPath)
 		if err != nil {
 			logger.Fatal("failed to generate devnet guardian key", zap.Error(err))
 		}
-
-		err = writeGuardianKey(gk, "auto-generated deterministic devnet key", *guardianKeyPath, true)
-		if err != nil {
-			logger.Fatal("failed to write devnet guardian key", zap.Error(err))
-		}
 	}
 
 	// Database
@@ -797,7 +792,7 @@ func runNode(cmd *cobra.Command, args []string) {
 	defer db.Close()
 
 	// Guardian key
-	gk, err := loadGuardianKey(*guardianKeyPath)
+	gk, err := common.LoadGuardianKey(*guardianKeyPath, *unsafeDevMode)
 	if err != nil {
 		logger.Fatal("failed to load guardian key", zap.Error(err))
 	}

+ 1 - 49
node/hack/accountant/send_obs.go

@@ -7,24 +7,15 @@ import (
 	"context"
 	"crypto/ecdsa"
 	"encoding/hex"
-	"fmt"
-	"io"
-	"os"
 	"time"
 
 	"github.com/certusone/wormhole/node/pkg/accountant"
 	"github.com/certusone/wormhole/node/pkg/common"
-	nodev1 "github.com/certusone/wormhole/node/pkg/proto/node/v1"
 	"github.com/certusone/wormhole/node/pkg/wormconn"
 	"github.com/wormhole-foundation/wormhole/sdk/vaa"
 
 	sdktx "github.com/cosmos/cosmos-sdk/types/tx"
 
-	ethCrypto "github.com/ethereum/go-ethereum/crypto"
-
-	"golang.org/x/crypto/openpgp/armor" //nolint
-	"google.golang.org/protobuf/proto"
-
 	"go.uber.org/zap"
 )
 
@@ -54,7 +45,7 @@ func main() {
 	)
 
 	logger.Info("Loading guardian key", zap.String("guardianKeyPath", guardianKeyPath))
-	gk, err := loadGuardianKey(guardianKeyPath)
+	gk, err := common.LoadGuardianKey(guardianKeyPath, true)
 	if err != nil {
 		logger.Fatal("failed to load guardian key", zap.Error(err))
 	}
@@ -448,42 +439,3 @@ func submit(
 
 	return accountant.SubmitObservationsToContract(ctx, logger, gk, gsIndex, guardianIndex, wormchainConn, contract, msgs)
 }
-
-const (
-	GuardianKeyArmoredBlock = "WORMHOLE GUARDIAN PRIVATE KEY"
-)
-
-// loadGuardianKey loads a serialized guardian key from disk.
-func loadGuardianKey(filename string) (*ecdsa.PrivateKey, error) {
-	f, err := os.Open(filename)
-	if err != nil {
-		return nil, fmt.Errorf("failed to open file: %w", err)
-	}
-
-	p, err := armor.Decode(f)
-	if err != nil {
-		return nil, fmt.Errorf("failed to read armored file: %w", err)
-	}
-
-	if p.Type != GuardianKeyArmoredBlock {
-		return nil, fmt.Errorf("invalid block type: %s", p.Type)
-	}
-
-	b, err := io.ReadAll(p.Body)
-	if err != nil {
-		return nil, fmt.Errorf("failed to read file: %w", err)
-	}
-
-	var m nodev1.GuardianKey
-	err = proto.Unmarshal(b, &m)
-	if err != nil {
-		return nil, fmt.Errorf("failed to deserialize protobuf: %w", err)
-	}
-
-	gk, err := ethCrypto.ToECDSA(m.Data)
-	if err != nil {
-		return nil, fmt.Errorf("failed to deserialize raw key data: %w", err)
-	}
-
-	return gk, nil
-}

+ 11 - 54
node/cmd/guardiand/guardiankey.go → node/pkg/common/armoredKey.go

@@ -1,61 +1,30 @@
-package guardiand
+package common
 
 import (
 	"crypto/ecdsa"
-	"crypto/rand"
 	"errors"
 	"fmt"
 	"io"
-	"log"
 	"os"
 
-	"github.com/certusone/wormhole/node/pkg/common"
-
 	ethcrypto "github.com/ethereum/go-ethereum/crypto"
-	"github.com/spf13/cobra"
 	"golang.org/x/crypto/openpgp/armor" //nolint
 	"google.golang.org/protobuf/proto"
 
-	"github.com/certusone/wormhole/node/pkg/devnet"
 	nodev1 "github.com/certusone/wormhole/node/pkg/proto/node/v1"
 )
 
-var keyDescription *string
-
 const (
 	GuardianKeyArmoredBlock = "WORMHOLE GUARDIAN PRIVATE KEY"
 )
 
-func init() {
-	keyDescription = KeygenCmd.Flags().String("desc", "", "Human-readable key description (optional)")
-}
-
-var KeygenCmd = &cobra.Command{
-	Use:   "keygen [KEYFILE]",
-	Short: "Create guardian key at the specified path",
-	Run:   runKeygen,
-	Args:  cobra.ExactArgs(1),
-}
-
-func runKeygen(cmd *cobra.Command, args []string) {
-	common.LockMemory()
-	common.SetRestrictiveUmask()
-
-	log.Print("Creating new key at ", args[0])
-
-	gk, err := ecdsa.GenerateKey(ethcrypto.S256(), rand.Reader)
-	if err != nil {
-		log.Fatalf("failed to generate key: %v", err)
-	}
-
-	err = writeGuardianKey(gk, *keyDescription, args[0], false)
-	if err != nil {
-		log.Fatalf("failed to write key: %v", err)
-	}
+// LoadGuardianKey loads a serialized guardian key from disk.
+func LoadGuardianKey(filename string, unsafeDevMode bool) (*ecdsa.PrivateKey, error) {
+	return LoadArmoredKey(filename, GuardianKeyArmoredBlock, unsafeDevMode)
 }
 
-// loadGuardianKey loads a serialized guardian key from disk.
-func loadGuardianKey(filename string) (*ecdsa.PrivateKey, error) {
+// LoadArmoredKey loads a serialized key from disk.
+func LoadArmoredKey(filename string, blockType string, unsafeDevMode bool) (*ecdsa.PrivateKey, error) {
 	f, err := os.Open(filename)
 	if err != nil {
 		return nil, fmt.Errorf("failed to open file: %w", err)
@@ -66,7 +35,7 @@ func loadGuardianKey(filename string) (*ecdsa.PrivateKey, error) {
 		return nil, fmt.Errorf("failed to read armored file: %w", err)
 	}
 
-	if p.Type != GuardianKeyArmoredBlock {
+	if p.Type != blockType {
 		return nil, fmt.Errorf("invalid block type: %s", p.Type)
 	}
 
@@ -81,7 +50,7 @@ func loadGuardianKey(filename string) (*ecdsa.PrivateKey, error) {
 		return nil, fmt.Errorf("failed to deserialize protobuf: %w", err)
 	}
 
-	if !*unsafeDevMode && m.UnsafeDeterministicKey {
+	if !unsafeDevMode && m.UnsafeDeterministicKey {
 		return nil, errors.New("refusing to use deterministic key in production")
 	}
 
@@ -93,8 +62,8 @@ func loadGuardianKey(filename string) (*ecdsa.PrivateKey, error) {
 	return gk, nil
 }
 
-// writeGuardianKey serializes a guardian key and writes it to disk.
-func writeGuardianKey(key *ecdsa.PrivateKey, description string, filename string, unsafe bool) error {
+// WriteArmoredKey serializes a key and writes it to disk.
+func WriteArmoredKey(key *ecdsa.PrivateKey, description string, filename string, blockType string, unsafe bool) error {
 	if _, err := os.Stat(filename); !os.IsNotExist(err) {
 		return errors.New("refusing to override existing key")
 	}
@@ -122,7 +91,7 @@ func writeGuardianKey(key *ecdsa.PrivateKey, description string, filename string
 	if description != "" {
 		headers["Description"] = description
 	}
-	a, err := armor.Encode(f, GuardianKeyArmoredBlock, headers)
+	a, err := armor.Encode(f, blockType, headers)
 	if err != nil {
 		panic(err)
 	}
@@ -136,15 +105,3 @@ func writeGuardianKey(key *ecdsa.PrivateKey, description string, filename string
 	}
 	return f.Close()
 }
-
-// generateDevnetGuardianKey returns a deterministic testnet key.
-func generateDevnetGuardianKey() (*ecdsa.PrivateKey, error) {
-	// Figure out our devnet index
-	idx, err := devnet.GetDevnetIndex()
-	if err != nil {
-		return nil, err
-	}
-
-	// Generate guardian key
-	return devnet.InsecureDeterministicEcdsaKeyByIndex(ethcrypto.S256(), uint64(idx)), nil
-}

+ 28 - 0
node/pkg/devnet/guardiankey.go

@@ -0,0 +1,28 @@
+package devnet
+
+import (
+	"fmt"
+
+	"github.com/certusone/wormhole/node/pkg/common"
+
+	ethcrypto "github.com/ethereum/go-ethereum/crypto"
+)
+
+// GenerateAndStoreDevnetGuardianKey returns a deterministic testnet key.
+func GenerateAndStoreDevnetGuardianKey(filename string) error {
+	// Figure out our devnet index
+	idx, err := GetDevnetIndex()
+	if err != nil {
+		return err
+	}
+
+	// Generate the guardian key.
+	gk := InsecureDeterministicEcdsaKeyByIndex(ethcrypto.S256(), uint64(idx))
+
+	// Store it to disk.
+	if err := common.WriteArmoredKey(gk, "auto-generated deterministic devnet key", filename, common.GuardianKeyArmoredBlock, true); err != nil {
+		return fmt.Errorf("failed to store generated guardian key: %w", err)
+	}
+
+	return nil
+}