[node.sh] a lot of refactoring and added getPubKeyFromFilePath

pull/3219/head
Jacky Wang 4 years ago
parent 80836edcdd
commit 40721eafd0
No known key found for this signature in database
GPG Key ID: 1085CE5F4FF5842C
  1. 8
      cmd/harmony/blsloader/decrypter.go
  2. 12
      cmd/harmony/blsloader/helper.go
  3. 16
      cmd/harmony/blsloader/loader.go
  4. 82
      cmd/harmony/blsloader/loader_test.go
  5. 23
      cmd/harmony/blsloader/params.go
  6. 195
      cmd/harmony/blsloader/passProvider.go
  7. 33
      cmd/harmony/blsloader/utils.go

@ -0,0 +1,8 @@
package blsloader
import bls_core "github.com/harmony-one/bls/ffi/go/bls"
type decrypter interface {
validate() error
decrypt(keyFile string) (*bls_core.SecretKey, error)
}

@ -6,8 +6,6 @@ import (
"os"
"path/filepath"
"github.com/harmony-one/harmony/crypto/bls"
bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/multibls"
)
@ -21,25 +19,19 @@ type loadHelper interface {
type basicSingleBlsLoader struct {
blsKeyFile string
passProviderConfig
passDecrypterConfig
}
// loadKeys load bls keys from a single bls file
func (loader *basicSingleBlsLoader) loadKeys() (multibls.PrivateKeys, error) {
fmt.Println("load keys")
providers, err := loader.getPassProviders()
if err != nil {
fmt.Println("not loaded 1")
return multibls.PrivateKeys{}, err
}
fmt.Println("provider got")
secretKey, err := loadBasicKey(loader.blsKeyFile, providers)
if err != nil {
fmt.Println("not loaded 2")
return multibls.PrivateKeys{}, err
}
fmt.Println("loaded secret key")
console.printf("loaded bls key %x\n", bls.WrapperFromPrivateKey(secretKey).Pub.Bytes)
return multibls.GetPrivateKeys(secretKey), nil
}
@ -102,7 +94,7 @@ func (loader *kmsSingleBlsLoader) getKmsClientProvider() (kmsProvider, error) {
type blsDirLoader struct {
// input fields
dirPath string
passProviderConfig
passDecrypterConfig
kmsProviderConfig
// providers in process

@ -9,10 +9,8 @@ import (
)
func LoadKeys(cfg Config) (multibls.PrivateKeys, error) {
fmt.Println("start")
cfg.applyDefault()
if err := cfg.validate(); err != nil {
fmt.Println("validate")
return multibls.PrivateKeys{}, err
}
helper, err := getHelper(cfg)
@ -94,8 +92,8 @@ func (cfg *Config) validate() error {
return cfg.getKmsProviderConfig().validate()
}
func (cfg *Config) getPassProviderConfig() passProviderConfig {
return passProviderConfig{
func (cfg *Config) getPassProviderConfig() passDecrypterConfig {
return passDecrypterConfig{
passSrcType: cfg.PassSrcType,
passFile: cfg.PassFile,
persistPassphrase: cfg.PersistPassphrase,
@ -117,8 +115,8 @@ func getHelper(cfg Config) (loadHelper, error) {
case basicKeyExt:
fmt.Println("basic")
return &basicSingleBlsLoader{
blsKeyFile: *cfg.BlsKeyFile,
passProviderConfig: cfg.getPassProviderConfig(),
blsKeyFile: *cfg.BlsKeyFile,
passDecrypterConfig: cfg.getPassProviderConfig(),
}, nil
case kmsKeyExt:
fmt.Println("kms")
@ -131,9 +129,9 @@ func getHelper(cfg Config) (loadHelper, error) {
}
case stringIsSet(cfg.BlsDir):
return &blsDirLoader{
dirPath: *cfg.BlsDir,
passProviderConfig: cfg.getPassProviderConfig(),
kmsProviderConfig: cfg.getKmsProviderConfig(),
dirPath: *cfg.BlsDir,
passDecrypterConfig: cfg.getPassProviderConfig(),
kmsProviderConfig: cfg.getKmsProviderConfig(),
}, nil
default:
return nil, errors.New("either BlsKeyFile or BlsDir must be set")

@ -3,6 +3,8 @@ package blsloader
import (
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"testing"
@ -11,8 +13,28 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/harmony-one/harmony/multibls"
dircopy "github.com/otiai10/copy"
)
func init() {
// Move the test data to temp directory
os.RemoveAll(testDir)
if err := os.MkdirAll(testDir, 0777); err != nil {
fmt.Println("makedir error", err)
}
info, exist := os.Stat(testDir)
fmt.Println("testDir", info, exist)
testDataFolder := "testdata"
fmt.Println(testDir)
if err := dircopy.Copy(testDataFolder, testDir); err != nil {
panic(fmt.Sprintf("failed to copy dir: %v", err))
}
fmt.Println(testDir)
}
var testDir = filepath.Join(os.TempDir(), "harmony/BlsLoader")
type testKey struct {
publicKey string
privateKey string
@ -28,16 +50,16 @@ var validTestKeys = []testKey{
publicKey: "0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500",
privateKey: "78c88c331195591b396e3205830071901a7a79e14fd0ede7f06bfb4c5e9f3473",
passphrase: "",
passFile: "testData/blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass",
path: "testData/blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key",
passFile: "blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass",
path: "blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key",
},
{
// key with non empty passphrase
publicKey: "152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083",
privateKey: "c20fa8de733d08e27e3101436d41f6a3207b8bedad7525c6e91a77ae2a49cf56",
passphrase: "harmony",
passFile: "testData/blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass",
path: "testData/blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key",
passFile: "blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass",
path: "blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key",
},
}
@ -48,14 +70,14 @@ var emptyPassTestKeys = []testKey{
publicKey: "0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500",
privateKey: "78c88c331195591b396e3205830071901a7a79e14fd0ede7f06bfb4c5e9f3473",
passphrase: "",
path: "testData/blskey_emptypass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key",
path: "blskey_emptypass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key",
},
{
// key with non empty passphrase
publicKey: "152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083",
privateKey: "c20fa8de733d08e27e3101436d41f6a3207b8bedad7525c6e91a77ae2a49cf56",
passphrase: "harmony",
path: "testData/blskey_emptypass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key",
path: "blskey_emptypass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key",
},
}
@ -66,16 +88,16 @@ var wrongPassTestKeys = []testKey{
publicKey: "0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500",
privateKey: "78c88c331195591b396e3205830071901a7a79e14fd0ede7f06bfb4c5e9f3473",
passphrase: "evil harmony",
passFile: "testData/blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass",
path: "testData/blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key",
passFile: "blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass",
path: "blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key",
},
{
// key with non empty passphrase
publicKey: "152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083",
privateKey: "c20fa8de733d08e27e3101436d41f6a3207b8bedad7525c6e91a77ae2a49cf56",
passphrase: "harmony",
passFile: "testData/blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass",
path: "testData/blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key",
passFile: "blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass",
path: "blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key",
},
}
@ -84,7 +106,7 @@ func TestLoadKeys_SingleBls_File(t *testing.T) {
cfg Config
inputs []string
expOutputs []string
expOutSubs []string
expPubKeys []string
expErr error
}{
@ -96,9 +118,7 @@ func TestLoadKeys_SingleBls_File(t *testing.T) {
},
inputs: []string{},
expOutputs: []string{
fmt.Sprintf("loaded bls key %s\n", validTestKeys[0].publicKey),
},
expOutSubs: []string{},
expPubKeys: []string{validTestKeys[0].publicKey},
},
{
@ -109,9 +129,7 @@ func TestLoadKeys_SingleBls_File(t *testing.T) {
},
inputs: []string{},
expOutputs: []string{
fmt.Sprintf("loaded bls key %s\n", validTestKeys[1].publicKey),
},
expOutSubs: []string{},
expPubKeys: []string{validTestKeys[1].publicKey},
},
{
@ -122,9 +140,8 @@ func TestLoadKeys_SingleBls_File(t *testing.T) {
},
inputs: []string{validTestKeys[1].passphrase},
expOutputs: []string{
expOutSubs: []string{
fmt.Sprintf("Enter passphrase for the BLS key file %s:", validTestKeys[1].path),
fmt.Sprintf("loaded bls key %s\n", validTestKeys[1].publicKey),
},
expPubKeys: []string{validTestKeys[1].publicKey},
},
@ -136,9 +153,7 @@ func TestLoadKeys_SingleBls_File(t *testing.T) {
},
inputs: []string{},
expOutputs: []string{
fmt.Sprintf("loaded bls key %s\n", validTestKeys[1].publicKey),
},
expOutSubs: []string{},
expPubKeys: []string{validTestKeys[1].publicKey},
},
{
@ -149,10 +164,9 @@ func TestLoadKeys_SingleBls_File(t *testing.T) {
},
inputs: []string{emptyPassTestKeys[1].passphrase},
expOutputs: []string{
"unable to get passphrase from passphrase file testData/blskey_emptypass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass: cannot open passphrase file\n",
expOutSubs: []string{
"unable to get passphrase",
fmt.Sprintf("Enter passphrase for the BLS key file %s:", emptyPassTestKeys[1].path),
fmt.Sprintf("loaded bls key %s\n", emptyPassTestKeys[1].publicKey),
},
expPubKeys: []string{emptyPassTestKeys[1].publicKey},
},
@ -161,7 +175,7 @@ func TestLoadKeys_SingleBls_File(t *testing.T) {
ts := &testSuite{
cfg: test.cfg,
inputs: test.inputs,
expOutputs: test.expOutputs,
expOutSub: test.expOutSubs,
expErr: test.expErr,
expPubKeys: test.expPubKeys,
}
@ -191,7 +205,7 @@ type testSuite struct {
cfg Config
inputs []string
expOutputs []string
expOutSub []string
expPubKeys []string
expErr error
@ -206,7 +220,7 @@ type testSuite struct {
}
func (ts *testSuite) init() {
ts.gotOutputs = make([]string, 0, len(ts.expOutputs))
ts.gotOutputs = make([]string, 0, len(ts.expOutSub))
ts.console = newTestConsole()
setTestConsole(ts.console)
ts.timeout = 1 * time.Second
@ -232,7 +246,7 @@ func (ts *testSuite) checkResult() error {
default:
}
fmt.Println("got outputs:", ts.gotOutputs)
fmt.Println("expect outputs:", ts.expOutputs)
fmt.Println("expect outputs:", ts.expOutSub)
if isClean, msg := ts.console.checkClean(); !isClean {
return fmt.Errorf("console not clean: %v", msg)
}
@ -249,12 +263,12 @@ func (ts *testSuite) checkResult() error {
}
func (ts *testSuite) checkOutputs() error {
if len(ts.gotOutputs) != len(ts.expOutputs) {
return fmt.Errorf("output size not expected: %v / %v", len(ts.gotOutputs), len(ts.expOutputs))
if len(ts.gotOutputs) != len(ts.expOutSub) {
return fmt.Errorf("output size not expected: %v / %v", len(ts.gotOutputs), len(ts.expOutSub))
}
for i, gotOutput := range ts.gotOutputs {
expOutput := ts.expOutputs[i]
if gotOutput != expOutput {
expOutput := ts.expOutSub[i]
if !strings.Contains(gotOutput, expOutput) {
return fmt.Errorf("%vth output unexpected: [%v] / [%v]", i, gotOutput, expOutput)
}
}
@ -313,7 +327,7 @@ func (ts *testSuite) threadedLoadOutputs() {
var (
i = 0
)
for i < len(ts.expOutputs) {
for i < len(ts.expOutSub) {
select {
case got := <-ts.console.Out:
ts.gotOutputs = append(ts.gotOutputs, got)

@ -20,29 +20,6 @@ const (
defWritePassFileMode = 0600
)
// PassSrcType is the type of passphrase provider source.
// Three options available:
// PassSrcFile - Read the passphrase from file
// PassSrcPrompt - Read the passphrase from prompt
// PassSrcPrompt - First try to unlock with passphrase from file, then read passphrase from prompt
type PassSrcType uint8
const (
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
)
func (srcType PassSrcType) isValid() bool {
switch srcType {
case PassSrcAuto, PassSrcFile, PassSrcPrompt:
return true
default:
return false
}
}
// AwsConfigSrcType is the type of src to load aws config. Two options available
// AwsCfgSrcFile - Provide the aws config through a file (json).
// AwsCfgSrcPrompt - Provide the aws config though prompt.

@ -5,76 +5,153 @@ import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strings"
"sync"
"github.com/harmony-one/harmony/crypto/bls"
bls_core "github.com/harmony-one/bls/ffi/go/bls"
)
// passProviderConfig is the data structure of passProviders config
type passProviderConfig struct {
// PassSrcType is the type of passphrase provider source.
// Three options available:
// PassSrcFile - Read the passphrase from files
// PassSrcPrompt - Read the passphrase from prompt
// PassSrcAuto - First try to unlock with passphrase from file, then read passphrase from prompt
type PassSrcType uint8
const (
PassSrcNil PassSrcType = iota // place holder for nil src
PassSrcFile // provide the passphrase through pass files
PassSrcPrompt // provide the passphrase through prompt
PassSrcAuto // first try to unlock with pass from file, then look for prompt
)
func (srcType PassSrcType) isValid() bool {
switch srcType {
case PassSrcAuto, PassSrcFile, PassSrcPrompt:
return true
default:
return false
}
}
type passDecrypter struct {
pps []passProvider
}
func newPassDecrypter(cfg passDecrypterConfig) *passDecrypter {
pps := cfg.makePassProviders()
return &passDecrypter{pps}
}
func (pd *passDecrypter) decrypt(keyFile string) (*bls_core.SecretKey, error) {
for _, pp := range pd.pps {
}
}
func (pd *passDecrypter) checkDecryptResult(keyFile string, got *bls_core.SecretKey) error {
expPubKey, err := getPubKeyFromFilePath(keyFile, passExt)
if err != nil {
if err == errUnableGetPubkey {
// file name not bls pub key + .pass
return nil
}
return err
}
gotPubKey := *bls.FromLibBLSPublicKeyUnsafe(got.GetPublicKey())
if expPubKey != gotPubKey {
return errors.New("public key unexpected")
}
return nil
}
// passDecrypterConfig is the data structure of passProviders config
type passDecrypterConfig struct {
passSrcType PassSrcType
passFile *string
passDir *string
persistPassphrase bool
}
func (config passProviderConfig) validate() error {
func (config passDecrypterConfig) validate() error {
if !config.passSrcType.isValid() {
return errors.New("unknown PassSrcType")
}
return nil
}
func (config passDecrypterConfig) makePassProviders() []passProvider {
switch config.passSrcType {
case PassSrcFile:
return []passProvider{config.getFilePassProvider()}
case PassSrcPrompt:
return []passProvider{config.getPromptPassProvider()}
case PassSrcAuto:
return []passProvider{
config.getFilePassProvider(),
config.getPromptPassProvider(),
}
}
}
func (config passDecrypterConfig) getFilePassProvider() passProvider {
switch {
case stringIsSet(config.passFile):
return newStaticPassProvider(*config.passFile)
case stringIsSet(config.passDir):
return newDirPassProvider(*config.passDir)
default:
return newDynamicPassProvider()
}
}
func (config passDecrypterConfig) getPromptPassProvider() passProvider {
return newPromptPassProvider(config.persistPassphrase)
}
// passProvider is the interface to provide the passphrase of a bls keys.
// Implemented by
// promptPassProvider - provide passphrase through user-interactive prompt
// filePassProvider - provide passphrase from a .pass file
// dirPassProvider - provide passphrase from .pass files in a directory
// promptPassProvider - provide passphrase through user-interactive prompt
// staticPassProvider - provide passphrase from a static .pass file
// dynamicPassProvider - provide the passphrase based on the given key file path
// dirPassProvider - provide passphrase from .pass files in a directory
type passProvider interface {
toStr() string
getPassphrase(keyFile string) (string, error)
}
// promptPassProvider provides the bls password through console prompt.
type promptPassProvider struct {
// if enablePersist is true, after user enter the passphrase, the
// passphrase is also persisted into the persistDir
// passphrase is also persisted into .pass file under the same directory
// of the key file
enablePersist bool
persistDir string
}
const pwdPromptStr = "Enter passphrase for the BLS key file %s:"
func newPromptPassProvider() *promptPassProvider {
return &promptPassProvider{}
}
func (provider *promptPassProvider) toStr() string {
return "prompt"
}
func (provider *promptPassProvider) setPersist(dirPath string) *promptPassProvider {
provider.enablePersist = true
os.MkdirAll(dirPath, defWritePassDirMode)
provider.persistDir = dirPath
return provider
func newPromptPassProvider(enablePersist bool) *promptPassProvider {
return &promptPassProvider{enablePersist: enablePersist}
}
func (provider *promptPassProvider) getPassphrase(keyFile string) (string, error) {
prompt := fmt.Sprintf(pwdPromptStr, keyFile)
pass, err := promptGetPassword(prompt)
if err != nil {
return "", err
return "", fmt.Errorf("unable to read from prompt: %v", err)
}
// If user set to persist the pass file, persist to .pass file
if provider.enablePersist {
if err := provider.persistPassphrase(keyFile, pass); err != nil {
return "", err
return "", fmt.Errorf("unable to save passphrase: %v", err)
}
}
return pass, nil
}
func (provider *promptPassProvider) persistPassphrase(keyFile string, passPhrase string) error {
passFile := filepath.Join(provider.persistDir, filepath.Base(keyFile))
passFile := keyFileToPassFileFull(keyFile)
if _, err := os.Stat(passFile); err == nil {
// File exist. Prompt user to overwrite pass file
overwrite, err := promptYesNo(fmt.Sprintf("pass file [%v] already exist. Overwrite? ", passFile))
@ -91,37 +168,42 @@ func (provider *promptPassProvider) persistPassphrase(keyFile string, passPhrase
return ioutil.WriteFile(passFile, []byte(passPhrase), defWritePassFileMode)
}
// filePassProvider provide the bls password from the single bls pass file
type filePassProvider struct {
// staticPassProvider provide the bls password from a static .pass file
type staticPassProvider struct {
fileName string
// cached field
pass string
err error
once sync.Once
}
func newFilePassProvider(fileName string) *filePassProvider {
return &filePassProvider{fileName: fileName}
func newStaticPassProvider(fileName string) *staticPassProvider {
return &staticPassProvider{fileName: fileName}
}
func (provider *filePassProvider) toStr() string {
return "passphrase file " + provider.fileName
func (provider *staticPassProvider) getPassphrase(keyFile string) (string, error) {
provider.once.Do(func() {
provider.pass, provider.err = readPassFromFile(provider.fileName)
})
return provider.pass, provider.err
}
func (provider *filePassProvider) getPassphrase(keyFile string) (string, error) {
return readPassFromFile(provider.fileName)
}
// dynamicPassProvider provide the passphrase based on .pass file with the given
// key file path. For example, looking for key file xxx.key will provide the
// passphrase from xxx.pass
type dynamicPassProvider struct{}
func readPassFromFile(file string) (string, error) {
f, err := os.Open(file)
if err != nil {
return "", fmt.Errorf("cannot open passphrase file")
}
defer f.Close()
func newDynamicPassProvider() passProvider {
return &dynamicPassProvider{}
}
b, err := ioutil.ReadAll(f)
if err != nil {
return "", err
func (provider *dynamicPassProvider) getPassphrase(keyFile string) (string, error) {
passFile := keyFileToPassFileFull(keyFile)
if !isPassFile(passFile) {
return "", fmt.Errorf("pass file %v not exist", passFile)
}
return strings.TrimSpace(string(b)), nil
return readPassFromFile(passFile)
}
// dirPassProvider provide the all bls password available in the directory.
@ -138,8 +220,23 @@ func newDirPassProvider(dirPath string) *dirPassProvider {
}
func (provider *dirPassProvider) getPassphrase(keyFile string) (string, error) {
baseName := filepath.Base(keyFile)
passKeyBase := keyFileToPassFileBase(baseName)
passFile := filepath.Join(provider.dirPath, passKeyBase)
passFile := keyFileToPassFileFull(keyFile)
if !isPassFile(passFile) {
return "", fmt.Errorf("pass file %v not exist", passFile)
}
return readPassFromFile(passFile)
}
func readPassFromFile(file string) (string, error) {
f, err := os.Open(file)
if err != nil {
return "", fmt.Errorf("cannot open passphrase file: %v", err)
}
defer f.Close()
b, err := ioutil.ReadAll(f)
if err != nil {
return "", err
}
return strings.TrimSpace(string(b)), nil
}

@ -4,8 +4,13 @@ import (
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"github.com/ethereum/go-ethereum/common"
"github.com/harmony-one/harmony/crypto/bls"
"github.com/pkg/errors"
bls_core "github.com/harmony-one/bls/ffi/go/bls"
@ -14,6 +19,7 @@ import (
var (
errUnknownExtension = errors.New("unknown extension")
errUnableGetPubkey = errors.New("unable to get public key")
errNilPassProvider = errors.New("no source for password")
errNilKMSClientProvider = errors.New("no source for KMS provider")
)
@ -88,6 +94,14 @@ func isBasicKeyFile(path string) bool {
return filepath.Ext(path) == basicKeyExt
}
func isPassFile(path string) bool {
exist := isFile(path)
if !exist {
return false
}
return filepath.Ext(path) == passExt
}
func isKMSKeyFile(path string) bool {
exist := isFile(path)
if !exist {
@ -96,6 +110,25 @@ func isKMSKeyFile(path string) bool {
return filepath.Ext(path) == kmsKeyExt
}
var regexFmt = `^[\da-f]{96}%s$`
func getPubKeyFromFilePath(path string, ext string) (bls.SerializedPublicKey, error) {
baseName := filepath.Base(path)
re, err := regexp.Compile(fmt.Sprintf(regexFmt, ext))
if err != nil {
return bls.SerializedPublicKey{}, err
}
res := re.FindAllStringSubmatch(baseName, 1)
if len(res) == 0 {
return bls.SerializedPublicKey{}, errUnableGetPubkey
}
b := common.Hex2Bytes(res[0][1])
var pubKey bls.SerializedPublicKey
copy(pubKey[:], b)
return pubKey, nil
}
func keyFileToPassFileBase(keyFileBase string) string {
return strings.Trim(keyFileBase, basicKeyExt) + passExt
}

Loading…
Cancel
Save