Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change private key loading logic #3621

Merged
merged 3 commits into from
Sep 2, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 21 additions & 26 deletions blockchain/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package blockchain
import (
"crypto/ecdsa"
"os"
"sync"
"time"

"github.com/iotexproject/go-pkgs/crypto"
Expand All @@ -25,6 +26,7 @@ import (
type (
// Config is the config struct for blockchain package
Config struct {
producerPrivKeyLoader sync.Once
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defined but not used?
also, this can be outside of the Config struct?

ChainDBPath string `yaml:"chainDBPath"`
TrieDBPatchFile string `yaml:"trieDBPatchFile"`
TrieDBPath string `yaml:"trieDBPath"`
Expand All @@ -36,7 +38,7 @@ type (
EVMNetworkID uint32 `yaml:"evmNetworkID"`
Address string `yaml:"address"`
ProducerPrivKey string `yaml:"producerPrivKey"`
PrivKeyConfigFile string `yaml:"privKeyConfigFile"`
ProducerPrivKeySchema string `yaml:"producerPrivKeySchema"`
SignatureScheme []string `yaml:"signatureScheme"`
EmptyGenesis bool `yaml:"emptyGenesis"`
GravityChainDB db.Config `yaml:"gravityChainDB"`
Expand Down Expand Up @@ -137,39 +139,32 @@ func (cfg *Config) ProducerPrivateKey() crypto.PrivateKey {

// SetProducerPrivKey set producer privKey by PrivKeyConfigFile info
func (cfg *Config) SetProducerPrivKey() error {
if cfg.PrivKeyConfigFile == "" {
return nil
}

yaml, err := config.NewYAML(config.Expand(os.LookupEnv), config.File(cfg.PrivKeyConfigFile))
if err != nil {
return errors.Wrap(err, "failed to init private key config")
}
pc := &privKeyConfig{}
if err := yaml.Get(config.Root).Populate(pc); err != nil {
return errors.Wrap(err, "failed to unmarshal YAML config to privKeyConfig struct")
}

var loader privKeyLoader
switch pc.Method {
switch cfg.ProducerPrivKeySchema {
case "hex", "":
// do nothing
case "hashiCorpVault":
cli, err := newVaultClient(&pc.VaultConfig)
yaml, err := config.NewYAML(config.Expand(os.LookupEnv), config.File(cfg.ProducerPrivKey))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: cfg.ProducerPrivKey can be a private key text (hex-string) or a filename (like "/var/data/vault.config", which could be a little confusing

if err != nil {
return errors.Wrap(err, "failed to init private key config")
}
hcv := &hashiCorpVault{}
if err := yaml.Get(config.Root).Populate(hcv); err != nil {
return errors.Wrap(err, "failed to unmarshal YAML config to privKeyConfig struct")
}

loader, err := newVaultPrivKeyLoader(hcv)
if err != nil {
return errors.Wrap(err, "failed to new vault client")
}
loader = &vaultPrivKeyLoader{
cfg: &pc.VaultConfig,
vaultClient: cli,
key, err := loader.load()
if err != nil {
return errors.Wrap(err, "failed to load producer private key")
}
cfg.ProducerPrivKey = key
default:
return errors.Wrap(ErrConfig, "invalid private key method")
return errors.Wrap(ErrConfig, "invalid private key schema")
}

key, err := loader.load()
if err != nil {
return errors.Wrap(err, "failed to load producer private key")
}
cfg.ProducerPrivKey = key
return nil
}

Expand Down
16 changes: 4 additions & 12 deletions blockchain/config_privatekey.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,6 @@ type (
Key string `yaml:"key"`
}

privKeyConfig struct {
Method string `yaml:"method"`
VaultConfig hashiCorpVault `yaml:"hashiCorpVault"`
}

privKeyLoader interface {
load() (string, error)
}

vaultPrivKeyLoader struct {
cfg *hashiCorpVault
*vaultClient
Expand Down Expand Up @@ -73,7 +64,7 @@ func (l *vaultPrivKeyLoader) load() (string, error) {
return v, nil
}

func newVaultClient(cfg *hashiCorpVault) (*vaultClient, error) {
func newVaultPrivKeyLoader(cfg *hashiCorpVault) (*vaultPrivKeyLoader, error) {
conf := api.DefaultConfig()
conf.Address = cfg.Address
conf.Timeout = defaultHTTPTimeout
Expand All @@ -83,7 +74,8 @@ func newVaultClient(cfg *hashiCorpVault) (*vaultClient, error) {
}
cli.SetToken(cfg.Token)

return &vaultClient{
cli: cli.Logical(),
return &vaultPrivKeyLoader{
vaultClient: &vaultClient{cli: cli.Logical()},
cfg: cfg,
}, nil
}
24 changes: 12 additions & 12 deletions blockchain/config_privatekey_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@ import (

const (
hashiCorpVaultTestCfg = `
method: hashiCorpVault
hashiCorpVault:
address: http://127.0.0.1:8200
token: secret/data/test
path: secret/data/test
key: my key
address: http://127.0.0.1:8200
token: secret/data/test
path: secret/data/test
key: my key
`

vaultTestKey = "my key"
Expand All @@ -47,8 +45,8 @@ func TestVault(t *testing.T) {
vaultClient: &vaultClient{reader},
}

t.Run("NewVaultClientSuccess", func(t *testing.T) {
_, err := newVaultClient(cfg)
t.Run("NewVaultPrivKeyLoaderSuccess", func(t *testing.T) {
_, err := newVaultPrivKeyLoader(cfg)
r.NoError(err)
})
t.Run("VaultSuccess", func(t *testing.T) {
Expand Down Expand Up @@ -111,14 +109,15 @@ func TestSetProducerPrivKey(t *testing.T) {
r.NoError(err)
r.Equal(key, cfg.ProducerPrivKey)
})
t.Run("PrivateConfigFileIsEmpty", func(t *testing.T) {
t.Run("PrivateConfigUnknownSchema", func(t *testing.T) {
cfg := DefaultConfig
tmp, err := os.CreateTemp("", testfile)
r.NoError(err)
defer os.Remove(tmp.Name())
cfg.PrivKeyConfigFile = tmp.Name()
cfg.ProducerPrivKey = tmp.Name()
cfg.ProducerPrivKeySchema = "unknown"
err = cfg.SetProducerPrivKey()
r.Contains(err.Error(), "invalid private key method")
r.Contains(err.Error(), "invalid private key schema")
})
t.Run("PrivateConfigFileHasHashiCorpVault", func(t *testing.T) {
cfg := DefaultConfig
Expand All @@ -130,7 +129,8 @@ func TestSetProducerPrivKey(t *testing.T) {
r.NoError(err)
err = tmp.Close()
r.NoError(err)
cfg.PrivKeyConfigFile = tmp.Name()
cfg.ProducerPrivKey = tmp.Name()
cfg.ProducerPrivKeySchema = "hashiCorpVault"
err = cfg.SetProducerPrivKey()
r.Contains(err.Error(), "dial tcp 127.0.0.1:8200: connect: connection refused")
})
Expand Down