diff --git a/cmd/harmony/blsloader/helper.go b/cmd/harmony/blsloader/helper.go index e63ed24de..96e9eb83c 100644 --- a/cmd/harmony/blsloader/helper.go +++ b/cmd/harmony/blsloader/helper.go @@ -67,7 +67,7 @@ func newBlsDirLoader(keyDir string, decrypters []keyDecrypter) (*blsDirLoader, e dm[decrypter.extension()] = decrypter } if err := checkIsDir(keyDir); err != nil { - return nil, fmt.Errorf("bls dir %v: %v", keyDir, err) + return nil, err } return &blsDirLoader{ keyDir: keyDir, diff --git a/cmd/harmony/blsloader/kms.go b/cmd/harmony/blsloader/kms.go index c413b8dc7..7d5647723 100644 --- a/cmd/harmony/blsloader/kms.go +++ b/cmd/harmony/blsloader/kms.go @@ -7,13 +7,12 @@ import ( "sync" "time" - "github.com/harmony-one/harmony/internal/blsgen" - "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/credentials" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/kms" bls_core "github.com/harmony-one/bls/ffi/go/bls" + "github.com/harmony-one/harmony/internal/blsgen" "github.com/pkg/errors" ) @@ -91,7 +90,7 @@ func (kd *kmsDecrypter) validateConfig() error { return errors.New("config field AwsConfig file must set for AwsCfgSrcFile") } if err := checkIsFile(*config.awsConfigFile); err != nil { - return fmt.Errorf("aws config file %v: %v", *config.awsConfigFile, err) + return err } } return nil diff --git a/cmd/harmony/blsloader/loader.go b/cmd/harmony/blsloader/loader.go index 7fd5ea5b0..46dac4d23 100644 --- a/cmd/harmony/blsloader/loader.go +++ b/cmd/harmony/blsloader/loader.go @@ -84,7 +84,7 @@ type Config struct { // 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 + // prompt the user for passphrase. Persisted pass file is a file with .pass extension // under the same directory as the key file. PersistPassphrase bool diff --git a/cmd/harmony/blsloader/loader_test.go b/cmd/harmony/blsloader/loader_test.go index ac121dd3f..55a363410 100644 --- a/cmd/harmony/blsloader/loader_test.go +++ b/cmd/harmony/blsloader/loader_test.go @@ -1,98 +1,5 @@ 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) { // tests := []struct { // cfg Config @@ -105,7 +12,7 @@ var wrongPassTestKeys = []testKey{ // { // // load the default pass file with file // cfg: Config{ -// BlsKeyFile: &validTestKeys[0].path, +// BlsKeyFile: &validTestKeys[0].keyFile, // PassSrcType: PassSrcFile, // }, // inputs: []string{}, @@ -116,7 +23,7 @@ var wrongPassTestKeys = []testKey{ // { // // load the default pass file with file // cfg: Config{ -// BlsKeyFile: &validTestKeys[1].path, +// BlsKeyFile: &validTestKeys[1].keyFile, // PassSrcType: PassSrcFile, // }, // inputs: []string{}, @@ -127,20 +34,20 @@ var wrongPassTestKeys = []testKey{ // { // // load key file with prompt // cfg: Config{ -// BlsKeyFile: &validTestKeys[1].path, +// BlsKeyFile: &validTestKeys[1].keyFile, // PassSrcType: PassSrcPrompt, // }, // inputs: []string{validTestKeys[1].passphrase}, // // 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}, // }, // { // // Automatically use pass file // cfg: Config{ -// BlsKeyFile: &validTestKeys[1].path, +// BlsKeyFile: &validTestKeys[1].keyFile, // PassSrcType: PassSrcAuto, // }, // inputs: []string{}, @@ -151,14 +58,14 @@ var wrongPassTestKeys = []testKey{ // { // // Automatically use prompt // cfg: Config{ -// BlsKeyFile: &emptyPassTestKeys[1].path, +// BlsKeyFile: &emptyPassTestKeys[1].keyFile, // PassSrcType: PassSrcAuto, // }, // inputs: []string{emptyPassTestKeys[1].passphrase}, // // expOutSubs: []string{ // "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}, // }, diff --git a/cmd/harmony/blsloader/params.go b/cmd/harmony/blsloader/params.go index 783dff08f..ed691417b 100644 --- a/cmd/harmony/blsloader/params.go +++ b/cmd/harmony/blsloader/params.go @@ -16,6 +16,6 @@ const ( ) const ( - defWritePassDirMode = 0600 + defWritePassDirMode = 0700 defWritePassFileMode = 0600 ) diff --git a/cmd/harmony/blsloader/passphrase.go b/cmd/harmony/blsloader/passphrase.go index 2043fe064..0df300d81 100644 --- a/cmd/harmony/blsloader/passphrase.go +++ b/cmd/harmony/blsloader/passphrase.go @@ -63,6 +63,18 @@ func (pd *passDecrypter) extension() string { 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 { config := pd.config if !config.passSrcType.isValid() { @@ -70,7 +82,7 @@ func (pd *passDecrypter) validateConfig() error { } if stringIsSet(config.passFile) { if err := checkIsPassFile(*config.passFile); err != nil { - return fmt.Errorf("%v not a passphrase file: %v", *config.passFile, err) + return err } } 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. // Implemented by // 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 +// dynamicPassProvider - provide the passphrase based on the given key file keyFile // dirPassProvider - provide passphrase from .pass files in a directory type passProvider interface { getPassphrase(keyFile string) (string, error) } -// promptPassProvider provides the bls password through console prompt. +// promptPassProvider provides the bls passphrase through console prompt. type promptPassProvider struct { // if enablePersist is true, after user enter the passphrase, the // 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 return err } + 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 { 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 -// 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 type dynamicPassProvider struct{} diff --git a/cmd/harmony/blsloader/passphrase_test.go b/cmd/harmony/blsloader/passphrase_test.go new file mode 100644 index 000000000..4745e0c8d --- /dev/null +++ b/cmd/harmony/blsloader/passphrase_test.go @@ -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) + } + } + } +} diff --git a/cmd/harmony/blsloader/testdata/blskey_emptypass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key b/cmd/harmony/blsloader/testdata/blskey_emptypass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key deleted file mode 100644 index 967e39613..000000000 --- a/cmd/harmony/blsloader/testdata/blskey_emptypass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key +++ /dev/null @@ -1 +0,0 @@ -1d97f32175d8875f251e15805fd08f0cda794d827cb02d2de7b10d10f36f951d68347bef1e7a3018bd865c6966219cd9c4d20b055c50f8e09a6a3a1666b7c112450f643cc3c175f541fae75da8a843d47993fe89ec85788fd6ea2e98 \ No newline at end of file diff --git a/cmd/harmony/blsloader/testdata/blskey_emptypass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key b/cmd/harmony/blsloader/testdata/blskey_emptypass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key deleted file mode 100644 index c70626a06..000000000 --- a/cmd/harmony/blsloader/testdata/blskey_emptypass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key +++ /dev/null @@ -1 +0,0 @@ -194a2d68c37f037f36b28a560402d64ab007f949313b63d9a08f5adb55a061681c70d9119df2d2cdcae5da6e484550c03bad63aae7c1332a3647ce633999ac4ddbb4a40e213c7e88e604784fef40da9d2f28b392c9fb2462f5e51e9c \ No newline at end of file diff --git a/cmd/harmony/blsloader/testdata/blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key b/cmd/harmony/blsloader/testdata/blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key deleted file mode 100644 index 967e39613..000000000 --- a/cmd/harmony/blsloader/testdata/blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key +++ /dev/null @@ -1 +0,0 @@ -1d97f32175d8875f251e15805fd08f0cda794d827cb02d2de7b10d10f36f951d68347bef1e7a3018bd865c6966219cd9c4d20b055c50f8e09a6a3a1666b7c112450f643cc3c175f541fae75da8a843d47993fe89ec85788fd6ea2e98 \ No newline at end of file diff --git a/cmd/harmony/blsloader/testdata/blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass b/cmd/harmony/blsloader/testdata/blskey_passphrase/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass deleted file mode 100644 index e69de29bb..000000000 diff --git a/cmd/harmony/blsloader/testdata/blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key b/cmd/harmony/blsloader/testdata/blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key deleted file mode 100644 index c70626a06..000000000 --- a/cmd/harmony/blsloader/testdata/blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key +++ /dev/null @@ -1 +0,0 @@ -194a2d68c37f037f36b28a560402d64ab007f949313b63d9a08f5adb55a061681c70d9119df2d2cdcae5da6e484550c03bad63aae7c1332a3647ce633999ac4ddbb4a40e213c7e88e604784fef40da9d2f28b392c9fb2462f5e51e9c \ No newline at end of file diff --git a/cmd/harmony/blsloader/testdata/blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass b/cmd/harmony/blsloader/testdata/blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass deleted file mode 100644 index 895202b7b..000000000 --- a/cmd/harmony/blsloader/testdata/blskey_passphrase/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass +++ /dev/null @@ -1 +0,0 @@ -harmony \ No newline at end of file diff --git a/cmd/harmony/blsloader/testdata/blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key b/cmd/harmony/blsloader/testdata/blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key deleted file mode 100644 index 967e39613..000000000 --- a/cmd/harmony/blsloader/testdata/blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.key +++ /dev/null @@ -1 +0,0 @@ -1d97f32175d8875f251e15805fd08f0cda794d827cb02d2de7b10d10f36f951d68347bef1e7a3018bd865c6966219cd9c4d20b055c50f8e09a6a3a1666b7c112450f643cc3c175f541fae75da8a843d47993fe89ec85788fd6ea2e98 \ No newline at end of file diff --git a/cmd/harmony/blsloader/testdata/blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass b/cmd/harmony/blsloader/testdata/blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass deleted file mode 100644 index 31add64a2..000000000 --- a/cmd/harmony/blsloader/testdata/blskey_wrongpass/0e969f8b302cf7648bc39652ca7a279a8562b72933a3f7cddac2252583280c7c3495c9ae854f00f6dd19c32fc5a17500.pass +++ /dev/null @@ -1 +0,0 @@ -evil harmony diff --git a/cmd/harmony/blsloader/testdata/blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key b/cmd/harmony/blsloader/testdata/blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key deleted file mode 100644 index c70626a06..000000000 --- a/cmd/harmony/blsloader/testdata/blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.key +++ /dev/null @@ -1 +0,0 @@ -194a2d68c37f037f36b28a560402d64ab007f949313b63d9a08f5adb55a061681c70d9119df2d2cdcae5da6e484550c03bad63aae7c1332a3647ce633999ac4ddbb4a40e213c7e88e604784fef40da9d2f28b392c9fb2462f5e51e9c \ No newline at end of file diff --git a/cmd/harmony/blsloader/testdata/blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass b/cmd/harmony/blsloader/testdata/blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass deleted file mode 100644 index 5d8cc4e5f..000000000 --- a/cmd/harmony/blsloader/testdata/blskey_wrongpass/152beed46d7a0002ef0f960946008887eedd4775bdf2ed238809aa74e20d31fdca267443615cc6f4ede49d58911ee083.pass +++ /dev/null @@ -1 +0,0 @@ -dark harmony \ No newline at end of file diff --git a/cmd/harmony/blsloader/utils.go b/cmd/harmony/blsloader/utils.go index 41a85f302..dc010bdd7 100644 --- a/cmd/harmony/blsloader/utils.go +++ b/cmd/harmony/blsloader/utils.go @@ -1,13 +1,13 @@ package blsloader import ( + "fmt" "os" "path/filepath" "strings" bls_core "github.com/harmony-one/bls/ffi/go/bls" "github.com/harmony-one/harmony/internal/blsgen" - "github.com/pkg/errors" ) func loadBasicKeyWithProvider(blsKeyFile string, pp passProvider) (*bls_core.SecretKey, error) { @@ -28,7 +28,7 @@ func checkIsFile(path string) error { return err } if info.IsDir() { - return errors.New("is directory") + return fmt.Errorf("%v is directory", path) } return nil } @@ -39,18 +39,17 @@ func checkIsDir(path string) error { return err } if info.IsDir() { - return errors.New("is a file") + return fmt.Errorf("%v is a file", path) } return nil } func checkIsPassFile(path string) error { - err := checkIsFile(path) - if err != nil { + if err := checkIsFile(path); err != nil { return err } 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 } diff --git a/cmd/harmony/blsloader/utils_test.go b/cmd/harmony/blsloader/utils_test.go index 148f15ba6..38e58e2f7 100644 --- a/cmd/harmony/blsloader/utils_test.go +++ b/cmd/harmony/blsloader/utils_test.go @@ -2,12 +2,54 @@ package blsloader import ( "fmt" + "io/ioutil" + "os" + "path/filepath" "strings" "testing" ) 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) { tests := []struct { inputs []string @@ -74,7 +116,7 @@ func TestPromptYesNo(t *testing.T) { if 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 { 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 for { select {