[node.sh] added test case for pass prompt

pull/3219/head
Jacky Wang 4 years ago
parent ef238ad287
commit 60ae574001
No known key found for this signature in database
GPG Key ID: 1085CE5F4FF5842C
  1. 2
      cmd/harmony/blsloader/helper.go
  2. 5
      cmd/harmony/blsloader/kms.go
  3. 2
      cmd/harmony/blsloader/loader.go
  4. 107
      cmd/harmony/blsloader/loader_test.go
  5. 2
      cmd/harmony/blsloader/params.go
  6. 35
      cmd/harmony/blsloader/passphrase.go
  7. 247
      cmd/harmony/blsloader/passphrase_test.go
  8. 1
      cmd/harmony/blsloader/testdata/blskey_emptypass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key
  9. 1
      cmd/harmony/blsloader/testdata/blskey_emptypass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key
  10. 1
      cmd/harmony/blsloader/testdata/blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key
  11. 0
      cmd/harmony/blsloader/testdata/blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass
  12. 1
      cmd/harmony/blsloader/testdata/blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key
  13. 1
      cmd/harmony/blsloader/testdata/blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass
  14. 1
      cmd/harmony/blsloader/testdata/blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key
  15. 1
      cmd/harmony/blsloader/testdata/blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass
  16. 1
      cmd/harmony/blsloader/testdata/blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key
  17. 1
      cmd/harmony/blsloader/testdata/blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass
  18. 11
      cmd/harmony/blsloader/utils.go
  19. 46
      cmd/harmony/blsloader/utils_test.go

@ -67,7 +67,7 @@ func newBlsDirLoader(keyDir string, decrypters []keyDecrypter) (*blsDirLoader, e
dm[decrypter.extension()] = decrypter dm[decrypter.extension()] = decrypter
} }
if err := checkIsDir(keyDir); err != nil { if err := checkIsDir(keyDir); err != nil {
return nil, fmt.Errorf("bls dir %v: %v", keyDir, err) return nil, err
} }
return &blsDirLoader{ return &blsDirLoader{
keyDir: keyDir, keyDir: keyDir,

@ -7,13 +7,12 @@ import (
"sync" "sync"
"time" "time"
"github.com/harmony-one/harmony/internal/blsgen"
"github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/kms" "github.com/aws/aws-sdk-go/service/kms"
bls_core "github.com/harmony-one/bls/ffi/go/bls" bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/internal/blsgen"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -91,7 +90,7 @@ func (kd *kmsDecrypter) validateConfig() error {
return errors.New("config field AwsConfig file must set for AwsCfgSrcFile") return errors.New("config field AwsConfig file must set for AwsCfgSrcFile")
} }
if err := checkIsFile(*config.awsConfigFile); err != nil { if err := checkIsFile(*config.awsConfigFile); err != nil {
return fmt.Errorf("aws config file %v: %v", *config.awsConfigFile, err) return err
} }
} }
return nil return nil

@ -84,7 +84,7 @@ type Config struct {
// If not set, default to the .pass file in the same directory as the key file. // If not set, default to the .pass file in the same directory as the key file.
PassFile *string PassFile *string
// PersistPassphrase set whether to persist the passphrase to a .pass file when // 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 // prompt the user for passphrase. Persisted pass file is a file with .pass extension
// under the same directory as the key file. // under the same directory as the key file.
PersistPassphrase bool PersistPassphrase bool

@ -1,98 +1,5 @@
package blsloader package blsloader
import (
"fmt"
"os"
"path/filepath"
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
passphrase string
passFile string
path string
}
// validTestKeys are keys with valid password and valid .pass file
var validTestKeys = []testKey{
{
// key with empty passphrase
publicKey: "0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500",
privateKey: "78c88c331195591b396e3205830071901a7a79e14fd0ede7f06bfb4c5e9f3473",
passphrase: "",
passFile: "blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass",
path: "blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key",
},
{
// key with non empty passphrase
publicKey: "152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083",
privateKey: "c20fa8de733d08e27e3101436d41f6a3207b8bedad7525c6e91a77ae2a49cf56",
passphrase: "harmony",
passFile: "blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass",
path: "blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key",
},
}
// emptyPassTestKeys are keys with valid password but empty .pass file
var emptyPassTestKeys = []testKey{
{
// key with empty passphrase
publicKey: "0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500",
privateKey: "78c88c331195591b396e3205830071901a7a79e14fd0ede7f06bfb4c5e9f3473",
passphrase: "",
path: "blskey_emptypass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key",
},
{
// key with non empty passphrase
publicKey: "152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083",
privateKey: "c20fa8de733d08e27e3101436d41f6a3207b8bedad7525c6e91a77ae2a49cf56",
passphrase: "harmony",
path: "blskey_emptypass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key",
},
}
// wrongPassTestKeys are keys with wrong pass file and wrong passphrase
var wrongPassTestKeys = []testKey{
{
// key with empty passphrase
publicKey: "0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500",
privateKey: "78c88c331195591b396e3205830071901a7a79e14fd0ede7f06bfb4c5e9f3473",
passphrase: "evil harmony",
passFile: "blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass",
path: "blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key",
},
{
// key with non empty passphrase
publicKey: "152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083",
privateKey: "c20fa8de733d08e27e3101436d41f6a3207b8bedad7525c6e91a77ae2a49cf56",
passphrase: "harmony",
passFile: "blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass",
path: "blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key",
},
}
//func TestLoadKeys_SingleBls_File(t *testing.T) { //func TestLoadKeys_SingleBls_File(t *testing.T) {
// tests := []struct { // tests := []struct {
// cfg Config // cfg Config
@ -105,7 +12,7 @@ var wrongPassTestKeys = []testKey{
// { // {
// // load the default pass file with file // // load the default pass file with file
// cfg: Config{ // cfg: Config{
// BlsKeyFile: &validTestKeys[0].path, // BlsKeyFile: &validTestKeys[0].keyFile,
// PassSrcType: PassSrcFile, // PassSrcType: PassSrcFile,
// }, // },
// inputs: []string{}, // inputs: []string{},
@ -116,7 +23,7 @@ var wrongPassTestKeys = []testKey{
// { // {
// // load the default pass file with file // // load the default pass file with file
// cfg: Config{ // cfg: Config{
// BlsKeyFile: &validTestKeys[1].path, // BlsKeyFile: &validTestKeys[1].keyFile,
// PassSrcType: PassSrcFile, // PassSrcType: PassSrcFile,
// }, // },
// inputs: []string{}, // inputs: []string{},
@ -127,20 +34,20 @@ var wrongPassTestKeys = []testKey{
// { // {
// // load key file with prompt // // load key file with prompt
// cfg: Config{ // cfg: Config{
// BlsKeyFile: &validTestKeys[1].path, // BlsKeyFile: &validTestKeys[1].keyFile,
// PassSrcType: PassSrcPrompt, // PassSrcType: PassSrcPrompt,
// }, // },
// inputs: []string{validTestKeys[1].passphrase}, // inputs: []string{validTestKeys[1].passphrase},
// //
// expOutSubs: []string{ // expOutSubs: []string{
// fmt.Sprintf("Enter passphrase for the BLS key file %s:", validTestKeys[1].path), // fmt.Sprintf("Enter passphrase for the BLS key file %s:", validTestKeys[1].keyFile),
// }, // },
// expPubKeys: []string{validTestKeys[1].publicKey}, // expPubKeys: []string{validTestKeys[1].publicKey},
// }, // },
// { // {
// // Automatically use pass file // // Automatically use pass file
// cfg: Config{ // cfg: Config{
// BlsKeyFile: &validTestKeys[1].path, // BlsKeyFile: &validTestKeys[1].keyFile,
// PassSrcType: PassSrcAuto, // PassSrcType: PassSrcAuto,
// }, // },
// inputs: []string{}, // inputs: []string{},
@ -151,14 +58,14 @@ var wrongPassTestKeys = []testKey{
// { // {
// // Automatically use prompt // // Automatically use prompt
// cfg: Config{ // cfg: Config{
// BlsKeyFile: &emptyPassTestKeys[1].path, // BlsKeyFile: &emptyPassTestKeys[1].keyFile,
// PassSrcType: PassSrcAuto, // PassSrcType: PassSrcAuto,
// }, // },
// inputs: []string{emptyPassTestKeys[1].passphrase}, // inputs: []string{emptyPassTestKeys[1].passphrase},
// //
// expOutSubs: []string{ // expOutSubs: []string{
// "unable to get passphrase", // "unable to get passphrase",
// fmt.Sprintf("Enter passphrase for the BLS key file %s:", emptyPassTestKeys[1].path), // fmt.Sprintf("Enter passphrase for the BLS key file %s:", emptyPassTestKeys[1].keyFile),
// }, // },
// expPubKeys: []string{emptyPassTestKeys[1].publicKey}, // expPubKeys: []string{emptyPassTestKeys[1].publicKey},
// }, // },

@ -16,6 +16,6 @@ const (
) )
const ( const (
defWritePassDirMode = 0600 defWritePassDirMode = 0700
defWritePassFileMode = 0600 defWritePassFileMode = 0600
) )

@ -63,6 +63,18 @@ func (pd *passDecrypter) extension() string {
return basicKeyExt return basicKeyExt
} }
func (pd *passDecrypter) decryptFile(keyFile string) (*bls_core.SecretKey, error) {
for _, pp := range pd.pps {
secretKey, err := loadBasicKeyWithProvider(keyFile, pp)
if err != nil {
console.println(err)
continue
}
return secretKey, nil
}
return nil, fmt.Errorf("failed to load bls key %v", keyFile)
}
func (pd *passDecrypter) validateConfig() error { func (pd *passDecrypter) validateConfig() error {
config := pd.config config := pd.config
if !config.passSrcType.isValid() { if !config.passSrcType.isValid() {
@ -70,7 +82,7 @@ func (pd *passDecrypter) validateConfig() error {
} }
if stringIsSet(config.passFile) { if stringIsSet(config.passFile) {
if err := checkIsPassFile(*config.passFile); err != nil { if err := checkIsPassFile(*config.passFile); err != nil {
return fmt.Errorf("%v not a passphrase file: %v", *config.passFile, err) return err
} }
} }
return nil return nil
@ -103,29 +115,17 @@ func (pd *passDecrypter) getFilePassProvider() passProvider {
} }
} }
func (pd *passDecrypter) decryptFile(keyFile string) (*bls_core.SecretKey, error) {
for _, pp := range pd.pps {
secretKey, err := loadBasicKeyWithProvider(keyFile, pp)
if err != nil {
console.println(err)
continue
}
return secretKey, nil
}
return nil, fmt.Errorf("failed to load bls key %v", keyFile)
}
// passProvider is the interface to provide the passphrase of a bls keys. // passProvider is the interface to provide the passphrase of a bls keys.
// Implemented by // Implemented by
// promptPassProvider - provide passphrase through user-interactive prompt // promptPassProvider - provide passphrase through user-interactive prompt
// staticPassProvider - provide passphrase from a static .pass file // staticPassProvider - provide passphrase from a static .pass file
// dynamicPassProvider - provide the passphrase based on the given key file path // dynamicPassProvider - provide the passphrase based on the given key file keyFile
// dirPassProvider - provide passphrase from .pass files in a directory // dirPassProvider - provide passphrase from .pass files in a directory
type passProvider interface { type passProvider interface {
getPassphrase(keyFile string) (string, error) getPassphrase(keyFile string) (string, error)
} }
// promptPassProvider provides the bls password through console prompt. // promptPassProvider provides the bls passphrase through console prompt.
type promptPassProvider struct { type promptPassProvider struct {
// if enablePersist is true, after user enter the passphrase, the // if enablePersist is true, after user enter the passphrase, the
// passphrase is also persisted into .pass file under the same directory // passphrase is also persisted into .pass file under the same directory
@ -169,10 +169,11 @@ func (provider *promptPassProvider) persistPassphrase(keyFile string, passPhrase
// Unknown error. Directly return // Unknown error. Directly return
return err return err
} }
return ioutil.WriteFile(passFile, []byte(passPhrase), defWritePassFileMode) return ioutil.WriteFile(passFile, []byte(passPhrase), defWritePassFileMode)
} }
// staticPassProvider provide the bls password from a static .pass file // staticPassProvider provide the bls passphrase from a static .pass file
type staticPassProvider struct { type staticPassProvider struct {
fileName string fileName string
@ -194,7 +195,7 @@ func (provider *staticPassProvider) getPassphrase(keyFile string) (string, error
} }
// dynamicPassProvider provide the passphrase based on .pass file with the given // 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 // key file keyFile. For example, looking for key file xxx.key will provide the
// passphrase from xxx.pass // passphrase from xxx.pass
type dynamicPassProvider struct{} type dynamicPassProvider struct{}

@ -0,0 +1,247 @@
package blsloader
import (
"errors"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"reflect"
"testing"
)
func TestNewPassDecrypter(t *testing.T) {
// setup
var (
testDir = filepath.Join(baseTestDir, t.Name())
existPassFile = filepath.Join(testDir, testKeys[0].publicKey+passExt)
emptyPassFile = filepath.Join(testDir, testKeys[1].publicKey+passExt)
invalidExtPassFile = filepath.Join(testDir, testKeys[1].publicKey+".invalid")
)
if err := writeFile(existPassFile, testKeys[0].passphrase); err != nil {
t.Fatal(err)
}
if err := writeFile(invalidExtPassFile, testKeys[1].passphrase); err != nil {
t.Fatal(err)
}
tests := []struct {
config passDecrypterConfig
expErr error
providerTypes []passProvider
}{
{
config: passDecrypterConfig{passSrcType: PassSrcNil},
expErr: errors.New("unknown PassSrcType"),
},
{
config: passDecrypterConfig{
passSrcType: PassSrcFile,
passFile: &emptyPassFile,
},
expErr: errors.New("no such file or directory"),
},
{
config: passDecrypterConfig{
passSrcType: PassSrcFile,
passFile: &existPassFile,
},
expErr: nil,
providerTypes: []passProvider{
&staticPassProvider{},
},
},
{
config: passDecrypterConfig{
passSrcType: PassSrcFile,
passFile: &invalidExtPassFile,
},
expErr: errors.New("should have extension .pass"),
},
{
config: passDecrypterConfig{passSrcType: PassSrcPrompt},
expErr: nil,
providerTypes: []passProvider{
&promptPassProvider{},
},
},
{
config: passDecrypterConfig{
passSrcType: PassSrcPrompt,
persistPassphrase: true,
},
expErr: nil,
providerTypes: []passProvider{
&promptPassProvider{},
},
},
{
config: passDecrypterConfig{
passSrcType: PassSrcAuto,
},
expErr: nil,
providerTypes: []passProvider{
&dynamicPassProvider{},
&promptPassProvider{},
},
},
{
config: passDecrypterConfig{
passSrcType: PassSrcAuto,
passFile: &existPassFile,
},
expErr: nil,
providerTypes: []passProvider{
&staticPassProvider{},
&promptPassProvider{},
},
},
}
for i, test := range tests {
decrypter, err := newPassDecrypter(test.config)
if assErr := assertError(err, test.expErr); assErr != nil {
t.Errorf("Test %v: %v", i, assErr)
continue
}
if err != nil {
continue
}
if len(decrypter.pps) != len(test.providerTypes) {
t.Errorf("Test %v: unexpected provider number %v / %v",
i, len(decrypter.pps), len(test.providerTypes))
continue
}
for ppIndex, gotPP := range decrypter.pps {
gotType := reflect.TypeOf(gotPP).Elem()
expType := reflect.TypeOf(test.providerTypes[ppIndex]).Elem()
if gotType != expType {
t.Errorf("Test %v: %v passProvider unexpected type: %v / %v",
i, ppIndex, gotType, expType)
}
}
}
}
func TestPromptPassProvider_getPassphrase(t *testing.T) {
unitTestDir := filepath.Join(baseTestDir, t.Name())
tests := []struct {
setupFunc func(rootDir string) error
keyFile string
passphrase string
enablePersist bool
extraInput []string
expOutputLen int
expErr error
newPassFileContent bool
passFileExist bool
}{
{
setupFunc: nil,
keyFile: testKeys[1].publicKey + basicKeyExt,
passphrase: "new key",
enablePersist: false,
extraInput: []string{},
expOutputLen: 1, // prompt for passphrase
passFileExist: false,
newPassFileContent: false,
},
{
// new pass file
setupFunc: nil,
keyFile: testKeys[1].publicKey + basicKeyExt,
passphrase: "new key",
enablePersist: true,
extraInput: []string{},
expOutputLen: 1, // prompt for passphrase
passFileExist: true,
newPassFileContent: true,
},
{
// exist pass file, not overwrite
setupFunc: func(rootDir string) error {
passFile := filepath.Join(rootDir, testKeys[1].publicKey+passExt)
return writeFile(passFile, "old key")
},
keyFile: testKeys[1].publicKey + basicKeyExt,
passphrase: "new key",
enablePersist: true,
extraInput: []string{"n"},
expOutputLen: 2, // prompt for passphrase and ask for overwrite
passFileExist: true,
newPassFileContent: false,
},
{
// exist pass file, do overwrite
setupFunc: func(rootDir string) error {
passFile := filepath.Join(rootDir, testKeys[1].publicKey+passExt)
return writeFile(passFile, "old key")
},
keyFile: testKeys[1].publicKey + basicKeyExt,
passphrase: "new key",
enablePersist: true,
extraInput: []string{"y"},
expOutputLen: 2, // prompt for passphrase and ask for overwrite
passFileExist: true,
newPassFileContent: true,
},
}
for i, test := range tests {
tc := newTestConsole()
setTestConsole(tc)
tcDir := filepath.Join(unitTestDir, fmt.Sprintf("%v", i))
os.RemoveAll(tcDir)
os.MkdirAll(tcDir, 0700)
if test.setupFunc != nil {
if err := test.setupFunc(tcDir); err != nil {
t.Fatal(err)
}
}
tc.In <- test.passphrase
for _, in := range test.extraInput {
tc.In <- in
}
ppd := &promptPassProvider{enablePersist: test.enablePersist}
keyFile := filepath.Join(tcDir, test.keyFile)
passphrase, err := ppd.getPassphrase(keyFile)
if assErr := assertError(err, test.expErr); assErr != nil {
t.Errorf("Test %v: %v", i, assErr)
continue
}
if passphrase != test.passphrase {
t.Errorf("Test %v: got unexpected passphrase: %v / %v", i, passphrase, test.passphrase)
continue
}
for index := 0; index != test.expOutputLen; index++ {
<-tc.Out
}
if isClean, msg := tc.checkClean(); !isClean {
t.Errorf("Test %v: console not clean: %v", i, msg)
continue
}
passFile := keyFileToPassFileFull(keyFile)
if !test.passFileExist {
if _, err := os.Stat(passFile); !os.IsNotExist(err) {
t.Errorf("Test %v: pass file exist %v", i, passFile)
}
} else {
b, err := ioutil.ReadFile(passFile)
if err != nil {
t.Error(err)
continue
}
if test.newPassFileContent && string(b) != test.passphrase {
t.Errorf("Test %v: unexpected passphrase from persist file: %v/ %v",
i, string(b), test.passphrase)
}
if !test.newPassFileContent && string(b) == test.passphrase {
t.Errorf("Test %v: passphrase content has changed", i)
}
}
}
}

@ -1 +0,0 @@
1d97f32175d8875f251e15805fd08f0cda794d827cb02d2de7b10d10f36f951d68347bef1e7a3018bd865c6966219cd9c4d20b055c50f8e09a6a3a1666b7c112450f643cc3c175f541fae75da8a843d47993fe89ec85788fd6ea2e98

@ -1 +0,0 @@
194a2d68c37f037f36b28a560402d64ab007f949313b63d9a08f5adb55a061681c70d9119df2d2cdcae5da6e484550c03bad63aae7c1332a3647ce633999ac4ddbb4a40e213c7e88e604784fef40da9d2f28b392c9fb2462f5e51e9c

@ -1 +0,0 @@
1d97f32175d8875f251e15805fd08f0cda794d827cb02d2de7b10d10f36f951d68347bef1e7a3018bd865c6966219cd9c4d20b055c50f8e09a6a3a1666b7c112450f643cc3c175f541fae75da8a843d47993fe89ec85788fd6ea2e98

@ -1 +0,0 @@
194a2d68c37f037f36b28a560402d64ab007f949313b63d9a08f5adb55a061681c70d9119df2d2cdcae5da6e484550c03bad63aae7c1332a3647ce633999ac4ddbb4a40e213c7e88e604784fef40da9d2f28b392c9fb2462f5e51e9c

@ -1 +0,0 @@
1d97f32175d8875f251e15805fd08f0cda794d827cb02d2de7b10d10f36f951d68347bef1e7a3018bd865c6966219cd9c4d20b055c50f8e09a6a3a1666b7c112450f643cc3c175f541fae75da8a843d47993fe89ec85788fd6ea2e98

@ -1 +0,0 @@
194a2d68c37f037f36b28a560402d64ab007f949313b63d9a08f5adb55a061681c70d9119df2d2cdcae5da6e484550c03bad63aae7c1332a3647ce633999ac4ddbb4a40e213c7e88e604784fef40da9d2f28b392c9fb2462f5e51e9c

@ -1,13 +1,13 @@
package blsloader package blsloader
import ( import (
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"strings" "strings"
bls_core "github.com/harmony-one/bls/ffi/go/bls" bls_core "github.com/harmony-one/bls/ffi/go/bls"
"github.com/harmony-one/harmony/internal/blsgen" "github.com/harmony-one/harmony/internal/blsgen"
"github.com/pkg/errors"
) )
func loadBasicKeyWithProvider(blsKeyFile string, pp passProvider) (*bls_core.SecretKey, error) { func loadBasicKeyWithProvider(blsKeyFile string, pp passProvider) (*bls_core.SecretKey, error) {
@ -28,7 +28,7 @@ func checkIsFile(path string) error {
return err return err
} }
if info.IsDir() { if info.IsDir() {
return errors.New("is directory") return fmt.Errorf("%v is directory", path)
} }
return nil return nil
} }
@ -39,18 +39,17 @@ func checkIsDir(path string) error {
return err return err
} }
if info.IsDir() { if info.IsDir() {
return errors.New("is a file") return fmt.Errorf("%v is a file", path)
} }
return nil return nil
} }
func checkIsPassFile(path string) error { func checkIsPassFile(path string) error {
err := checkIsFile(path) if err := checkIsFile(path); err != nil {
if err != nil {
return err return err
} }
if filepath.Ext(path) != passExt { if filepath.Ext(path) != passExt {
return errors.New("should have extension .pass") return fmt.Errorf("pass file %v should have extension .pass", path)
} }
return nil return nil
} }

@ -2,12 +2,54 @@ package blsloader
import ( import (
"fmt" "fmt"
"io/ioutil"
"os"
"path/filepath"
"strings" "strings"
"testing" "testing"
) )
const testPrompt = yesNoPrompt const testPrompt = yesNoPrompt
func init() {
// Move the test data to temp directory
os.RemoveAll(baseTestDir)
os.MkdirAll(baseTestDir, 0777)
}
var baseTestDir = filepath.Join(os.TempDir(), "harmony/BlsLoader")
type testKey struct {
publicKey string
privateKey string
passphrase string
keyFileData string
}
// testKeys are keys with valid passphrase and valid .pass file
var testKeys = []testKey{
{
// key with empty passphrase
publicKey: "0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500",
privateKey: "78c88c331195591b396e3205830071901a7a79e14fd0ede7f06bfb4c5e9f3473",
passphrase: "",
keyFileData: "1d97f32175d8875f251e15805fd08f0cda794d827cb02d2de7b10d10f36f951d68347bef1e7a3018bd865c6966219cd9c4d20b055c50f8e09a6a3a1666b7c112450f643cc3c175f541fae75da8a843d47993fe89ec85788fd6ea2e98",
},
{
// key with non empty passphrase
publicKey: "152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083",
privateKey: "c20fa8de733d08e27e3101436d41f6a3207b8bedad7525c6e91a77ae2a49cf56",
passphrase: "harmony",
keyFileData: "194a2d68c37f037f36b28a560402d64ab007f949313b63d9a08f5adb55a061681c70d9119df2d2cdcae5da6e484550c03bad63aae7c1332a3647ce633999ac4ddbb4a40e213c7e88e604784fef40da9d2f28b392c9fb2462f5e51e9c",
},
}
func writeFile(file string, data string) error {
dir := filepath.Dir(file)
os.MkdirAll(dir, 0700)
return ioutil.WriteFile(file, []byte(data), 0600)
}
func TestPromptYesNo(t *testing.T) { func TestPromptYesNo(t *testing.T) {
tests := []struct { tests := []struct {
inputs []string inputs []string
@ -74,7 +116,7 @@ func TestPromptYesNo(t *testing.T) {
if got != test.expRes { if got != test.expRes {
t.Errorf("Test %v: result unexpected %v / %v", i, got, test.expRes) t.Errorf("Test %v: result unexpected %v / %v", i, got, test.expRes)
} }
gotOutputs := drainOutCh(tc.Out) gotOutputs := drainCh(tc.Out)
if len(gotOutputs) != test.lenOutputs { if len(gotOutputs) != test.lenOutputs {
t.Errorf("unexpected output size: %v / %v", len(gotOutputs), test.lenOutputs) t.Errorf("unexpected output size: %v / %v", len(gotOutputs), test.lenOutputs)
} }
@ -84,7 +126,7 @@ func TestPromptYesNo(t *testing.T) {
} }
} }
func drainOutCh(c chan string) []string { func drainCh(c chan string) []string {
var res []string var res []string
for { for {
select { select {

Loading…
Cancel
Save