[node.sh] changed public signature to config based. Do a lot of refactoring

pull/3219/head
Jacky Wang 4 years ago
parent 6d2fa888fc
commit cc600f9879
No known key found for this signature in database
GPG Key ID: 1085CE5F4FF5842C
  1. 235
      cmd/harmony/blsloader/helper.go
  2. 55
      cmd/harmony/blsloader/kmsProvider.go
  3. 329
      cmd/harmony/blsloader/loader.go
  4. 59
      cmd/harmony/blsloader/params.go
  5. 15
      cmd/harmony/blsloader/passProvider.go
  6. 47
      cmd/harmony/blsloader/utils.go

@ -0,0 +1,235 @@
package blsloader
import (
"errors"
"fmt"
"os"
"path/filepath"
bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/multibls"
)
// loadHelper defines the interface to help load bls keys
type loadHelper interface {
loadKeys() (multibls.PrivateKeys, error)
}
// basicSingleBlsLoader loads a single bls key file with passphrase
type basicSingleBlsLoader struct {
blsKeyFile string
passProviderConfig
}
// loadKeys load bls keys from a single bls file
func (loader *basicSingleBlsLoader) loadKeys() (multibls.PrivateKeys, error) {
providers, err := loader.getPassProviders()
if err != nil {
return multibls.PrivateKeys{}, err
}
secretKey, err := loadBasicKey(loader.blsKeyFile, providers)
if err != nil {
return multibls.PrivateKeys{}, err
}
return multibls.GetPrivateKeys(secretKey), nil
}
func (loader *basicSingleBlsLoader) getPassProviders() ([]passProvider, error) {
switch loader.passSrcType {
case PassSrcFile:
return []passProvider{loader.getFilePassProvider()}, nil
case PassSrcPrompt:
return []passProvider{loader.getPromptPassProvider()}, nil
case PassSrcAuto:
return []passProvider{
loader.getFilePassProvider(),
loader.getPromptPassProvider(),
}, nil
default:
return nil, errors.New("unknown passphrase source type")
}
}
func (loader *basicSingleBlsLoader) getFilePassProvider() passProvider {
if stringIsSet(loader.passFile) {
return newFilePassProvider(*loader.passFile)
}
passFile := keyFileToPassFileFull(loader.blsKeyFile)
return newFilePassProvider(passFile)
}
func (loader *basicSingleBlsLoader) getPromptPassProvider() passProvider {
provider := newPromptPassProvider()
if loader.persistPassphrase {
provider.setPersist(filepath.Dir(loader.blsKeyFile))
}
return provider
}
type kmsSingleBlsLoader struct {
blsKeyFile string
kmsProviderConfig
}
// loadKeys load a single kms key file
func (loader *kmsSingleBlsLoader) loadKeys() (multibls.PrivateKeys, error) {
provider, err := loader.getKmsClientProvider()
if err != nil {
return multibls.PrivateKeys{}, err
}
secretKey, err := loadKmsKeyFromFile(loader.blsKeyFile, provider)
if err != nil {
return multibls.PrivateKeys{}, err
}
return multibls.GetPrivateKeys(secretKey), nil
}
func (loader *kmsSingleBlsLoader) getKmsClientProvider() (kmsClientProvider, error) {
switch loader.awsCfgSrcType {
case AwsCfgSrcFile:
if stringIsSet(loader.awsConfigFile) {
return newFileKmsProvider(*loader.awsConfigFile), nil
}
return newSharedKmsProvider(), nil
case AwsCfgSrcPrompt:
return newPromptKmsProvider(defKmsPromptTimeout), nil
case AwsCfgSrcShared:
return newSharedKmsProvider(), nil
default:
return nil, errors.New("unknown aws config source type")
}
}
// blsDirLoader is the helper structure for loading bls keys in a directory
type blsDirLoader struct {
// input fields
dirPath string
passProviderConfig
kmsProviderConfig
// providers in process
pps []passProvider
kcp kmsClientProvider
// result field
secretKeys []*bls_core.SecretKey
}
// loadKeys load all keys from the directory
func (loader *blsDirLoader) loadKeys() (multibls.PrivateKeys, error) {
var err error
if loader.pps, err = loader.getPassProviders(); err != nil {
return multibls.PrivateKeys{}, err
}
if loader.kcp, err = loader.getKmsClientProvider(); err != nil {
return multibls.PrivateKeys{}, err
}
return loader.loadKeyFiles()
}
func (loader *blsDirLoader) getPassProviders() ([]passProvider, error) {
switch loader.passSrcType {
case PassSrcFile:
return []passProvider{loader.getFilePassProvider()}, nil
case PassSrcPrompt:
return []passProvider{loader.getPromptPassProvider()}, nil
case PassSrcAuto:
return []passProvider{
loader.getFilePassProvider(),
loader.getPromptPassProvider(),
}, nil
default:
return nil, errors.New("unknown pass source type")
}
}
func (loader *blsDirLoader) getFilePassProvider() passProvider {
if stringIsSet(loader.passFile) {
return newFilePassProvider(*loader.passFile)
}
return newDirPassProvider(loader.dirPath)
}
func (loader *blsDirLoader) getPromptPassProvider() passProvider {
provider := newPromptPassProvider()
if loader.persistPassphrase {
provider.setPersist(loader.dirPath)
}
return provider
}
func (loader *blsDirLoader) getKmsClientProvider() (kmsClientProvider, error) {
switch loader.awsCfgSrcType {
case AwsCfgSrcFile:
if stringIsSet(loader.awsConfigFile) {
return newFileKmsProvider(*loader.awsConfigFile), nil
}
return newSharedKmsProvider(), nil
case AwsCfgSrcPrompt:
return newPromptKmsProvider(defKmsPromptTimeout), nil
case AwsCfgSrcShared:
return newSharedKmsProvider(), nil
default:
return nil, errors.New("unknown aws config source type")
}
}
func (loader *blsDirLoader) loadKeyFiles() (multibls.PrivateKeys, error) {
err := filepath.Walk(loader.dirPath, loader.processFileWalk)
if err != nil {
return multibls.PrivateKeys{}, err
}
return multibls.GetPrivateKeys(loader.secretKeys...), nil
}
func (loader *blsDirLoader) processFileWalk(path string, info os.FileInfo, err error) error {
key, err := loader.loadKeyFromFile(path, info)
if err != nil {
if !errIsErrors(err, loader.skippingErrors()) {
// unexpected error, return the error and break the file walk loop
return err
}
// expected error. Skipping these files
skipStr := fmt.Sprintf("Skipping [%s]: %v\n", path, err)
console.println(skipStr)
return nil
}
loader.secretKeys = append(loader.secretKeys, key)
return nil
}
// errors to be neglected for directory bls loading
func (loader *blsDirLoader) skippingErrors() []error {
return []error{
errUnknownExtension,
errNilPassProvider,
errNilKMSClientProvider,
}
}
func (loader *blsDirLoader) loadKeyFromFile(path string, info os.FileInfo) (*bls_core.SecretKey, error) {
var (
key *bls_core.SecretKey
err error
)
switch {
case isBasicKeyFile(path):
key, err = loadBasicKey(path, loader.pps)
case isKMSKeyFile(path):
key, err = loadKmsKeyFromFile(path, loader.kcp)
default:
err = errUnknownExtension
}
return key, err
}
// errIsErrors return whether the err is one of the errs
func errIsErrors(err error, errs []error) bool {
for _, targetErr := range errs {
if errors.Is(err, targetErr) {
return true
}
}
return false
}

@ -14,6 +14,8 @@ import (
"github.com/pkg/errors"
)
// AwsConfig is the config data structure for credentials and region. Used for AWS KMS
// decryption.
type AwsConfig struct {
AccessKey string `json:"aws-access-key-id"`
SecretKey string `json:"aws-secret-access-key"`
@ -21,7 +23,7 @@ type AwsConfig struct {
Token string `json:"aws-token,omitempty"`
}
func (cfg *AwsConfig) toAws() *aws.Config {
func (cfg AwsConfig) toAws() *aws.Config {
cred := credentials.NewStaticCredentials(cfg.AccessKey, cfg.SecretKey, cfg.Token)
return &aws.Config{
Region: aws.String(cfg.Region),
@ -29,6 +31,27 @@ func (cfg *AwsConfig) toAws() *aws.Config {
}
}
// kmsProviderConfig is the data structure of kmsClientProvider config
type kmsProviderConfig struct {
awsCfgSrcType AwsCfgSrcType
awsConfigFile *string
}
func (cfg kmsProviderConfig) validate() error {
if !cfg.awsCfgSrcType.isValid() {
return errors.New("unknown AwsCfgSrcType")
}
if cfg.awsCfgSrcType == AwsCfgSrcFile {
if !stringIsSet(cfg.awsConfigFile) {
return errors.New("config field AwsConfig file must set for AwsCfgSrcFile")
}
if !isFile(*cfg.awsConfigFile) {
return fmt.Errorf("aws config file not exist %v", *cfg.awsConfigFile)
}
}
return nil
}
// kmsClientProvider provides the kms client. Implemented by
// baseKMSProvider - abstract implementation
// sharedKMSProvider - provide the client with default .aws folder
@ -38,19 +61,20 @@ type kmsClientProvider interface {
// getKMSClient returns the KMSClient of the kmsClientProvider with lazy loading.
getKMSClient() (*kms.KMS, error)
// getAWSConfig returns the AwsConfig for different implementations
getAWSConfig() (*AwsConfig, error)
// toStr return the string presentation of kmsClientProvider
toStr() string
}
type getAwsCfgFunc func() (*AwsConfig, error)
// baseKMSProvider provide the kms client with singleton initialization through
// function getConfig for aws credential and regions loading.
type baseKMSProvider struct {
client *kms.KMS
err error
once sync.Once
getAWSConfig getAwsCfgFunc
}
func (provider *baseKMSProvider) getKMSClient() (*kms.KMS, error) {
@ -68,10 +92,6 @@ func (provider *baseKMSProvider) getKMSClient() (*kms.KMS, error) {
return provider.client, nil
}
func (provider *baseKMSProvider) getAWSConfig() (*AwsConfig, error) {
return nil, errors.New("not implemented")
}
func (provider *baseKMSProvider) toStr() string {
return "not implemented"
}
@ -83,11 +103,12 @@ type sharedKMSProvider struct {
}
func newSharedKmsProvider() *sharedKMSProvider {
return &sharedKMSProvider{
baseKMSProvider{},
}
provider := &sharedKMSProvider{baseKMSProvider{}}
provider.baseKMSProvider.getAWSConfig = provider.getAWSConfig
return provider
}
// TODO(Jacky): set getAwsConfig into a function, not bind with structure
func (provider *sharedKMSProvider) getAWSConfig() (*AwsConfig, error) {
return nil, nil
}
@ -105,10 +126,12 @@ type fileKMSProvider struct {
}
func newFileKmsProvider(file string) *fileKMSProvider {
return &fileKMSProvider{
provider := &fileKMSProvider{
baseKMSProvider: baseKMSProvider{},
file: file,
}
provider.baseKMSProvider.getAWSConfig = provider.getAWSConfig
return provider
}
func (provider *fileKMSProvider) getAWSConfig() (*AwsConfig, error) {
@ -138,10 +161,12 @@ type promptKMSProvider struct {
}
func newPromptKmsProvider(timeout time.Duration) *promptKMSProvider {
return &promptKMSProvider{
provider := &promptKMSProvider{
baseKMSProvider: baseKMSProvider{},
timeout: timeout,
}
provider.baseKMSProvider.getAWSConfig = provider.getAWSConfig
return provider
}
func (provider *promptKMSProvider) getAWSConfig() (*AwsConfig, error) {
@ -204,7 +229,7 @@ func kmsClientWithConfig(config *AwsConfig) (*kms.KMS, error) {
if config == nil {
return getSharedKMSClient()
}
return getKMSClientFromConfig(config)
return getKMSClientFromConfig(*config)
}
func getSharedKMSClient() (*kms.KMS, error) {
@ -217,7 +242,7 @@ func getSharedKMSClient() (*kms.KMS, error) {
return kms.New(sess), err
}
func getKMSClientFromConfig(config *AwsConfig) (*kms.KMS, error) {
func getKMSClientFromConfig(config AwsConfig) (*kms.KMS, error) {
sess, err := session.NewSession(config.toAws())
if err != nil {
return nil, err

@ -3,289 +3,134 @@ package blsloader
import (
"errors"
"fmt"
"os"
"path/filepath"
"github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/multibls"
)
type Loader struct {
BlsKeyFile *string
AwsBlsKey *string
BlsDir *string
PassSrcType PassSrcType
PassFile *string
PersistPassphrase bool
AwsCfgSrcType AwsCfgSrcType
AwsConfigFile *string
}
// LoadKeys load all keys from the input fields provided
func (loader *Loader) LoadKeys() (multibls.PrivateKeys, error) {
helper, err := loader.getHelper()
if err != nil {
func LoadKeys(cfg Config) (multibls.PrivateKeys, error) {
cfg.applyDefault()
if err := cfg.validate(); err != nil {
return multibls.PrivateKeys{}, err
}
helper, err := getHelper(cfg)
if err != nil {
return nil, err
}
return helper.loadKeys()
}
// getHelper parse the Loader structure to helper for further computation
func (loader *Loader) getHelper() (loadHelper, error) {
func getHelper(cfg Config) (loadHelper, error) {
switch {
case stringIsSet(loader.BlsKeyFile):
case stringIsSet(cfg.BlsKeyFile):
switch filepath.Ext(*cfg.BlsKeyFile) {
case basicKeyExt:
return &basicSingleBlsLoader{
blsKeyFile: *loader.BlsKeyFile,
passFile: loader.PassFile,
passSrcType: loader.PassSrcType,
persistPassphrase: loader.PersistPassphrase,
blsKeyFile: *cfg.BlsKeyFile,
passProviderConfig: cfg.getPassProviderConfig(),
}, nil
case stringIsSet(loader.AwsBlsKey):
case kmsKeyExt:
return &kmsSingleBlsLoader{
awsBlsKey: *loader.AwsBlsKey,
awsCfgSrcType: loader.AwsCfgSrcType,
awsConfigFile: loader.AwsConfigFile,
}, nil
case stringIsSet(loader.BlsDir):
return &blsDirLoader{
dirPath: *loader.BlsDir,
pst: loader.PassSrcType,
passFile: loader.PassFile,
persistPassphrase: loader.PersistPassphrase,
act: loader.AwsCfgSrcType,
awsConfigFile: loader.AwsConfigFile,
blsKeyFile: *cfg.BlsKeyFile,
kmsProviderConfig: cfg.getKmsProviderConfig(),
}, nil
default:
return nil, errors.New("empty bls key data source")
return nil, errors.New("unknown extension")
}
}
// loadHelper defines the interface to help load bls keys
type loadHelper interface {
loadKeys() (multibls.PrivateKeys, error)
}
// basicSingleBlsLoader loads a single bls key file with passphrase
type basicSingleBlsLoader struct {
blsKeyFile string
passSrcType PassSrcType
passFile *string
persistPassphrase bool
}
func (loader *basicSingleBlsLoader) loadKeys() (multibls.PrivateKeys, error) {
providers, err := loader.getPassProviders()
if err != nil {
return multibls.PrivateKeys{}, err
}
secretKey, err := loadBasicKey(loader.blsKeyFile, providers)
if err != nil {
return multibls.PrivateKeys{}, err
}
return secretKeyToMultiPrivateKey(secretKey), nil
}
func (loader *basicSingleBlsLoader) getPassProviders() ([]passProvider, error) {
switch loader.passSrcType {
case PassSrcFile:
return []passProvider{loader.getFilePassProvider()}, nil
case PassSrcPrompt:
return []passProvider{loader.getPromptPassProvider()}, nil
case PassSrcAuto:
return []passProvider{
loader.getFilePassProvider(),
loader.getPromptPassProvider(),
case stringIsSet(cfg.BlsDir):
return &blsDirLoader{
dirPath: *cfg.BlsDir,
passProviderConfig: cfg.getPassProviderConfig(),
kmsProviderConfig: cfg.getKmsProviderConfig(),
}, nil
default:
return nil, errors.New("unknown passphrase source type")
return nil, errors.New("either BlsKeyFile or BlsDir must be set")
}
}
func (loader *basicSingleBlsLoader) getFilePassProvider() passProvider {
if stringIsSet(loader.passFile) {
return newFilePassProvider(*loader.passFile)
}
passFile := keyFileToPassFileFull(loader.blsKeyFile)
return newFilePassProvider(passFile)
}
func (loader *basicSingleBlsLoader) getPromptPassProvider() passProvider {
provider := newPromptPassProvider()
if loader.persistPassphrase {
provider.setPersist(filepath.Dir(loader.blsKeyFile))
}
return provider
}
type kmsSingleBlsLoader struct {
awsBlsKey string
// Loader is the structure to load bls keys.
type Config struct {
// source for bls key loading. At least one of the BlsKeyFile and BlsDir
// need to be provided.
//
// BlsKeyFile defines a single key file to load from. Based on the file
// extension, decryption with passphrase or aws kms will be used.
BlsKeyFile *string
// BlsDir defines a file directory to load keys from.
BlsDir *string
awsCfgSrcType AwsCfgSrcType
awsConfigFile *string
}
// Passphrase related settings. Used for passphrase encrypted key files.
//
// PassSrcType defines the source to get passphrase. Three source types are available
// PassSrcFile - get passphrase from a .pass file
// PassSrcPrompt - get passphrase from prompt
// PassSrcAuto - try to unlock with .pass file. If not success, ask user with prompt
// Value is default to PassSrcAuto.
PassSrcType PassSrcType
// PassFile specifies the .pass file to be used when loading passphrase from file.
// If not set, default to the .pass file in the same directory as the key file.
PassFile *string
// PersistPassphrase set whether to persist the passphrase to a .pass file when
// prompt the user for password. Persisted pass file is a file with .pass extension
// under the same directory as the key file.
PersistPassphrase bool
func (loader *kmsSingleBlsLoader) loadKeys() (multibls.PrivateKeys, error) {
provider, err := loader.getKmsClientProvider()
if err != nil {
return multibls.PrivateKeys{}, err
}
secretKey, err := loadKmsKeyFromFile(loader.awsBlsKey, provider)
if err != nil {
return multibls.PrivateKeys{}, err
}
return secretKeyToMultiPrivateKey(secretKey), nil
// Aws configuration related settings, including AWS credentials and region info.
// Used for KMS encrypted passphrase files.
//
// AwsCfgSrcType defines the source to get aws config. Three types available:
// AwsCfgSrcFile - get AWS config through a json file. See AwsConfig for content fields.
// AwsCfgSrcPrompt - get AWS config through prompt.
// AwsCfgSrcShared - Use the default AWS config settings (from env and $HOME/.aws/config)
// Default to AwsCfgSrcShared.
AwsCfgSrcType AwsCfgSrcType
// AwsConfigFile set the json file to load aws config.
AwsConfigFile *string
}
func (loader *kmsSingleBlsLoader) getKmsClientProvider() (kmsClientProvider, error) {
switch loader.awsCfgSrcType {
case AwsCfgSrcFile:
if stringIsSet(loader.awsConfigFile) {
return newFileKmsProvider(*loader.awsConfigFile), nil
func (cfg *Config) applyDefault() {
if cfg.PassSrcType == PassSrcNil {
cfg.PassSrcType = PassSrcAuto
}
return newSharedKmsProvider(), nil
case AwsCfgSrcPrompt:
return newPromptKmsProvider(defKmsPromptTimeout), nil
case AwsCfgSrcShared:
return newSharedKmsProvider(), nil
default:
return nil, errors.New("unknown aws config source type")
if cfg.AwsCfgSrcType == AwsCfgSrcNil {
cfg.AwsCfgSrcType = AwsCfgSrcShared
}
}
// blsDirLoader is the helper structure for loading bls keys in a directory
type blsDirLoader struct {
// input fields
dirPath string
// pass provider fields
pst PassSrcType
passFile *string
persistPassphrase bool
// kms provider fields
act AwsCfgSrcType
awsConfigFile *string
// providers in process
pps []passProvider
kcp kmsClientProvider
// result field
secretKeys []*bls.SecretKey
}
func (loader *blsDirLoader) loadKeys() (multibls.PrivateKeys, error) {
var err error
if loader.pps, err = loader.getPassProviders(); err != nil {
return multibls.PrivateKeys{}, err
func (cfg *Config) validate() error {
if stringIsSet(cfg.BlsKeyFile) {
if !isFile(*cfg.BlsKeyFile) {
return fmt.Errorf("key file not exist %v", *cfg.BlsKeyFile)
}
if loader.kcp, err = loader.getKmsClientProvider(); err != nil {
return multibls.PrivateKeys{}, err
}
return loader.loadKeyFiles()
}
func (loader *blsDirLoader) getPassProviders() ([]passProvider, error) {
switch loader.pst {
case PassSrcFile:
return []passProvider{loader.getFilePassProvider()}, nil
case PassSrcPrompt:
return []passProvider{loader.getPromptPassProvider()}, nil
case PassSrcAuto:
return []passProvider{
loader.getFilePassProvider(),
loader.getPromptPassProvider(),
}, nil
switch ext := filepath.Ext(*cfg.BlsKeyFile); ext {
case basicKeyExt, kmsKeyExt:
default:
return nil, errors.New("unknown pass source type")
}
}
func (loader *blsDirLoader) getFilePassProvider() passProvider {
if stringIsSet(loader.passFile) {
return newFilePassProvider(*loader.passFile)
return fmt.Errorf("unknown key file extension %v", ext)
}
return newDirPassProvider(loader.dirPath)
}
func (loader *blsDirLoader) getPromptPassProvider() passProvider {
provider := newPromptPassProvider()
if loader.persistPassphrase {
provider.setPersist(loader.dirPath)
}
return provider
}
func (loader *blsDirLoader) getKmsClientProvider() (kmsClientProvider, error) {
switch loader.act {
case AwsCfgSrcFile:
if stringIsSet(loader.awsConfigFile) {
return newFileKmsProvider(*loader.awsConfigFile), nil
} else if stringIsSet(cfg.BlsDir) {
if !isDir(*cfg.BlsDir) {
return fmt.Errorf("dir not exist %v", *cfg.BlsDir)
}
return newSharedKmsProvider(), nil
case AwsCfgSrcPrompt:
return newPromptKmsProvider(defKmsPromptTimeout), nil
case AwsCfgSrcShared:
return newSharedKmsProvider(), nil
default:
return nil, errors.New("unknown aws config source type")
}
}
func (loader *blsDirLoader) loadKeyFiles() (multibls.PrivateKeys, error) {
err := filepath.Walk(loader.dirPath, loader.processFileWalk)
if err != nil {
return multibls.PrivateKeys{}, err
} else {
return errors.New("either BlsKeyFile or BlsDir must be set")
}
return secretKeyToMultiPrivateKey(loader.secretKeys...), nil
}
func (loader *blsDirLoader) processFileWalk(path string, info os.FileInfo, err error) error {
key, err := loader.loadKeyFromFile(path, info)
if err != nil {
if !errIsErrors(err, loader.skippingErrors()) {
// unexpected error, return the error and break the file walk loop
if err := cfg.getPassProviderConfig().validate(); err != nil {
return err
}
// expected error. Skipping these files
skipStr := fmt.Sprintf("Skipping [%s]: %v\n", path, err)
console.println(skipStr)
return nil
}
loader.secretKeys = append(loader.secretKeys, key)
return nil
}
// errors to be neglected for directory bls loading
func (loader *blsDirLoader) skippingErrors() []error {
return []error{
errUnknownExtension,
errNilPassProvider,
errNilKMSClientProvider,
}
return cfg.getKmsProviderConfig().validate()
}
func (loader *blsDirLoader) loadKeyFromFile(path string, info os.FileInfo) (*bls.SecretKey, error) {
var (
key *bls.SecretKey
err error
)
switch {
case isBasicKeyFile(info):
key, err = loadBasicKey(path, loader.pps)
case isKMSKeyFile(info):
key, err = loadKmsKeyFromFile(path, loader.kcp)
default:
err = errUnknownExtension
func (cfg *Config) getPassProviderConfig() passProviderConfig {
return passProviderConfig{
passSrcType: cfg.PassSrcType,
passFile: cfg.PassFile,
persistPassphrase: cfg.PersistPassphrase,
}
return key, err
}
// errIsErrors return whether the err is one of the errs
func errIsErrors(err error, errs []error) bool {
for _, targetErr := range errs {
if errors.Is(err, targetErr) {
return true
}
func (cfg *Config) getKmsProviderConfig() kmsProviderConfig {
return kmsProviderConfig{
awsCfgSrcType: cfg.AwsCfgSrcType,
awsConfigFile: cfg.AwsConfigFile,
}
return false
}

@ -3,12 +3,15 @@ package blsloader
import "time"
const (
// Extensions for files.
passExt = ".pass"
basicKeyExt = ".key"
kmsKeyExt = ".bls"
)
const (
// The default timeout for kms config prompt. The timeout is introduced
// for security concern.
defKmsPromptTimeout = 1 * time.Second
)
@ -25,37 +28,18 @@ const (
type PassSrcType uint8
const (
PassSrcNil PassSrcType = iota // nil place holder
PassSrcNil PassSrcType = iota // place holder for nil src
PassSrcAuto // first try to unlock with pass from file, then look for prompt
PassSrcFile // provide the passphrase through a pass file
PassSrcPrompt // provide the passphrase through prompt
PassSrcAuto // first try to unlock with pass from file, then look for prompt
)
// String return the string presentation of PassSrcType
func (srcType PassSrcType) String() string {
func (srcType PassSrcType) isValid() bool {
switch srcType {
case PassSrcFile:
return "file"
case PassSrcPrompt:
return "prompt"
case PassSrcAuto:
return "auto"
default:
return "unknown"
}
}
// PassSrcTypeFromString parse PassSrcType from string specifier
func PassSrcTypeFromString(str string) PassSrcType {
switch str {
case "file":
return PassSrcFile
case "prompt":
return PassSrcPrompt
case "auto":
return PassSrcAuto
case PassSrcAuto, PassSrcFile, PassSrcPrompt:
return true
default:
return PassSrcNil
return false
}
}
@ -72,28 +56,11 @@ const (
AwsCfgSrcShared // through shared aws config
)
func (srcType AwsCfgSrcType) String() string {
func (srcType AwsCfgSrcType) isValid() bool {
switch srcType {
case AwsCfgSrcFile:
return "file"
case AwsCfgSrcPrompt:
return "prompt"
case AwsCfgSrcShared:
return "shared"
default:
return "unknown"
}
}
func AwsCfgSrcTypeFromString(str string) AwsCfgSrcType {
switch str {
case "file":
return AwsCfgSrcFile
case "prompt":
return AwsCfgSrcPrompt
case "shared":
return AwsCfgSrcShared
case AwsCfgSrcFile, AwsCfgSrcPrompt, AwsCfgSrcShared:
return true
default:
return AwsCfgSrcNil
return false
}
}

@ -1,12 +1,27 @@
package blsloader
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
)
// passProviderConfig is the data structure of passProviders config
type passProviderConfig struct {
passSrcType PassSrcType
passFile *string
persistPassphrase bool
}
func (config passProviderConfig) validate() error {
if !config.passSrcType.isValid() {
return errors.New("unknown PassSrcType")
}
return nil
}
// passProvider is the interface to provide the passphrase of a bls keys.
// Implemented by
// promptPassProvider - provide passphrase through user-interactive prompt

@ -3,13 +3,13 @@ package blsloader
import (
"fmt"
"os"
"path/filepath"
"strings"
"github.com/pkg/errors"
bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/internal/blsgen"
"github.com/harmony-one/harmony/multibls"
"github.com/pkg/errors"
)
var (
@ -62,34 +62,42 @@ func loadKmsKeyFromFile(blsKeyFile string, kcp kmsClientProvider) (*bls_core.Sec
return secretKey, nil
}
// isBasicKeyFile return whether the given file is a bls file
func isBasicKeyFile(info os.FileInfo) bool {
if info.IsDir() {
func isFile(path string) bool {
info, err := os.Stat(path)
if err != nil {
return false
}
if !strings.HasSuffix(info.Name(), basicKeyExt) {
return !info.IsDir()
}
func isDir(path string) bool {
info, err := os.Stat(path)
if err != nil {
return false
}
return true
return info.IsDir()
}
// isKMSKeyFile returns whether the given file is a kms key file
func isKMSKeyFile(info os.FileInfo) bool {
if info.IsDir() {
func isBasicKeyFile(path string) bool {
exist := isFile(path)
if !exist {
return false
}
if !strings.HasSuffix(info.Name(), kmsKeyExt) {
return filepath.Ext(path) == basicKeyExt
}
func isKMSKeyFile(path string) bool {
exist := isFile(path)
if !exist {
return false
}
return true
return filepath.Ext(path) == kmsKeyExt
}
// keyFileToPassFileBase convert a key file base name to passphrase file base name
func keyFileToPassFileBase(keyFileBase string) string {
return strings.Trim(keyFileBase, basicKeyExt) + passExt
}
// keyFileToPassFileFull convert a key file full path to passphrase file full path
func keyFileToPassFileFull(keyFile string) string {
return strings.Trim(keyFile, basicKeyExt) + passExt
}
@ -124,15 +132,6 @@ func promptYesNo(prompt string) (bool, error) {
}
}
func secretKeyToMultiPrivateKey(secretKeys ...*bls_core.SecretKey) multibls.PrivateKeys {
keys := make(multibls.PrivateKeys, 0, len(secretKeys))
for _, secretKey := range secretKeys {
key := bls.WrapperFromPrivateKey(secretKey)
keys = append(keys, key)
}
return keys
}
func stringIsSet(val *string) bool {
return val != nil && *val != ""
}

Loading…
Cancel
Save