diff --git a/cmd/harmony/blsloader/decrypter.go b/cmd/harmony/blsloader/decrypter.go index 724c3b907..70b37c977 100644 --- a/cmd/harmony/blsloader/decrypter.go +++ b/cmd/harmony/blsloader/decrypter.go @@ -3,6 +3,6 @@ package blsloader import bls_core "github.com/harmony-one/bls/ffi/go/bls" type decrypter interface { - validate() error + extension() string decrypt(keyFile string) (*bls_core.SecretKey, error) } diff --git a/cmd/harmony/blsloader/helper.go b/cmd/harmony/blsloader/helper.go index 8f89012ea..35e553325 100644 --- a/cmd/harmony/blsloader/helper.go +++ b/cmd/harmony/blsloader/helper.go @@ -183,21 +183,21 @@ func (loader *blsDirLoader) skippingErrors() []error { } } -func (loader *blsDirLoader) loadKeyFromFile(path string) (*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 -} +//func (loader *blsDirLoader) loadKeyFromFile(path string) (*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 { diff --git a/cmd/harmony/blsloader/passProvider.go b/cmd/harmony/blsloader/passProvider.go index 62a735114..05669162d 100644 --- a/cmd/harmony/blsloader/passProvider.go +++ b/cmd/harmony/blsloader/passProvider.go @@ -8,8 +8,6 @@ import ( "strings" "sync" - "github.com/harmony-one/harmony/crypto/bls" - bls_core "github.com/harmony-one/bls/ffi/go/bls" ) @@ -36,79 +34,84 @@ func (srcType PassSrcType) isValid() bool { } } -type passDecrypter struct { - pps []passProvider -} - -func newPassDecrypter(cfg passDecrypterConfig) *passDecrypter { - pps := cfg.makePassProviders() - return &passDecrypter{pps} +// passDecrypterConfig is the data structure of passProviders config +type passDecrypterConfig struct { + passSrcType PassSrcType + passFile *string + persistPassphrase bool } -func (pd *passDecrypter) decrypt(keyFile string) (*bls_core.SecretKey, error) { - for _, pp := range pd.pps { +// passDecrypter decrypt the .key bls files with passphrase from a series +// of passProvider as passphrase source +type passDecrypter struct { + config passDecrypterConfig - } + pps []passProvider } -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") +func newPassDecrypter(cfg passDecrypterConfig) (*passDecrypter, error) { + pd := &passDecrypter{config: cfg} + if err := pd.validate(); err != nil { + return nil, err } - return nil + pd.makePassProviders() + return pd, nil } -// passDecrypterConfig is the data structure of passProviders config -type passDecrypterConfig struct { - passSrcType PassSrcType - passFile *string - passDir *string - persistPassphrase bool +func (pd *passDecrypter) extension() string { + return basicKeyExt } -func (config passDecrypterConfig) validate() error { +func (pd *passDecrypter) validate() error { + config := pd.config if !config.passSrcType.isValid() { return errors.New("unknown PassSrcType") } + if stringIsSet(config.passFile) { + if err := isPassFile(*config.passFile); err != nil { + return fmt.Errorf("%v not a passphrase file: %v", *config.passFile, err) + } + } return nil } -func (config passDecrypterConfig) makePassProviders() []passProvider { - switch config.passSrcType { +func (pd *passDecrypter) makePassProviders() { + switch pd.config.passSrcType { case PassSrcFile: - return []passProvider{config.getFilePassProvider()} + pd.pps = []passProvider{pd.getFilePassProvider()} case PassSrcPrompt: - return []passProvider{config.getPromptPassProvider()} + pd.pps = []passProvider{pd.getPromptPassProvider()} case PassSrcAuto: - return []passProvider{ - config.getFilePassProvider(), - config.getPromptPassProvider(), + pd.pps = []passProvider{ + pd.getFilePassProvider(), + pd.getPromptPassProvider(), } } } -func (config passDecrypterConfig) getFilePassProvider() passProvider { +func (pd *passDecrypter) getPromptPassProvider() passProvider { + return newPromptPassProvider(pd.config.persistPassphrase) +} + +func (pd *passDecrypter) getFilePassProvider() passProvider { switch { - case stringIsSet(config.passFile): - return newStaticPassProvider(*config.passFile) - case stringIsSet(config.passDir): - return newDirPassProvider(*config.passDir) + case stringIsSet(pd.config.passFile): + return newStaticPassProvider(*pd.config.passFile) default: return newDynamicPassProvider() } } -func (config passDecrypterConfig) getPromptPassProvider() passProvider { - return newPromptPassProvider(config.persistPassphrase) +func (pd *passDecrypter) decrypt(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. @@ -200,30 +203,6 @@ func newDynamicPassProvider() passProvider { func (provider *dynamicPassProvider) getPassphrase(keyFile string) (string, error) { passFile := keyFileToPassFileFull(keyFile) - if !isPassFile(passFile) { - return "", fmt.Errorf("pass file %v not exist", passFile) - } - return readPassFromFile(passFile) -} - -// dirPassProvider provide the all bls password available in the directory. -type dirPassProvider struct { - dirPath string -} - -func (provider *dirPassProvider) toStr() string { - return "directory " + provider.dirPath -} - -func newDirPassProvider(dirPath string) *dirPassProvider { - return &dirPassProvider{dirPath: dirPath} -} - -func (provider *dirPassProvider) getPassphrase(keyFile string) (string, error) { - passFile := keyFileToPassFileFull(keyFile) - if !isPassFile(passFile) { - return "", fmt.Errorf("pass file %v not exist", passFile) - } return readPassFromFile(passFile) } diff --git a/cmd/harmony/blsloader/utils.go b/cmd/harmony/blsloader/utils.go index 85a786d28..603d73639 100644 --- a/cmd/harmony/blsloader/utils.go +++ b/cmd/harmony/blsloader/utils.go @@ -4,13 +4,8 @@ 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" @@ -70,67 +65,59 @@ func loadKmsKeyFromFile(blsKeyFile string, kcp kmsProvider) (*bls_core.SecretKey return secretKey, nil } -func isFile(path string) bool { +func isFile(path string) error { info, err := os.Stat(path) if err != nil { - return false + return err } - return !info.IsDir() + if info.IsDir() { + return errors.New("is directory") + } + return nil } -func isDir(path string) bool { +func isDir(path string) error { info, err := os.Stat(path) if err != nil { - return false + return err } - return info.IsDir() -} - -func isBasicKeyFile(path string) bool { - exist := isFile(path) - if !exist { - return false + if info.IsDir() { + return errors.New("is a file") } - return filepath.Ext(path) == basicKeyExt + return nil } -func isPassFile(path string) bool { - exist := isFile(path) - if !exist { - return false +func isBasicKeyFile(path string) error { + err := isFile(path) + if err != nil { + return err } - return filepath.Ext(path) == passExt -} - -func isKMSKeyFile(path string) bool { - exist := isFile(path) - if !exist { - return false + if filepath.Ext(path) != basicKeyExt { + return errors.New("should have extension .key") } - return filepath.Ext(path) == kmsKeyExt + return nil } -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)) +func isPassFile(path string) error { + err := isFile(path) if err != nil { - return bls.SerializedPublicKey{}, err + return err } - res := re.FindAllStringSubmatch(baseName, 1) - if len(res) == 0 { - return bls.SerializedPublicKey{}, errUnableGetPubkey + if filepath.Ext(path) != passExt { + return errors.New("should have extension .pass") } - - b := common.Hex2Bytes(res[0][1]) - var pubKey bls.SerializedPublicKey - copy(pubKey[:], b) - return pubKey, nil + return nil } -func keyFileToPassFileBase(keyFileBase string) string { - return strings.Trim(keyFileBase, basicKeyExt) + passExt +func isKMSKeyFile(path string) error { + err := isFile(path) + if err != nil { + return err + } + if filepath.Ext(path) != kmsKeyExt { + return errors.New("should have extension .bls") + } + return nil } func keyFileToPassFileFull(keyFile string) string {