parent
8057507813
commit
7842d0ea34
@ -0,0 +1,118 @@ |
||||
package blsloader |
||||
|
||||
import ( |
||||
"fmt" |
||||
"os" |
||||
"path/filepath" |
||||
"strings" |
||||
|
||||
ffi_bls "github.com/harmony-one/bls/ffi/go/bls" |
||||
"github.com/harmony-one/harmony/internal/blsgen" |
||||
"github.com/harmony-one/harmony/multibls" |
||||
) |
||||
|
||||
// basicBLSLoader is the structure to load bls private keys through a key file
|
||||
// and passphrase combination.
|
||||
type basicBLSLoader struct { |
||||
// input fields
|
||||
BLSKeyFile *string // If both BLSKeyFile and blsFolder exists, use BLSKeyFile only
|
||||
BLSPassFile *string // If both BLSPassFile and BLSDir exists, use BLSPassFile only
|
||||
BLSDir *string |
||||
|
||||
// variables in process
|
||||
loadKeyFiles []string |
||||
passProvider passProvider |
||||
|
||||
// results
|
||||
privateKeys multibls.PrivateKey |
||||
} |
||||
|
||||
func (loader *basicBLSLoader) loadKeys() (multibls.PrivateKey, error) { |
||||
if err := loader.validateInput(); err != nil { |
||||
return multibls.PrivateKey{}, err |
||||
} |
||||
|
||||
loader.loadPassProvider() |
||||
keyFiles, err := loader.getTargetKeyFiles() |
||||
if err != nil { |
||||
return multibls.PrivateKey{}, err |
||||
} |
||||
|
||||
res := multibls.PrivateKey{PrivateKey: make([]*ffi_bls.SecretKey, 0, len(keyFiles))} |
||||
for |
||||
} |
||||
|
||||
func loadSingleBasicKeyFile(keyFile string, passFile string) { |
||||
if passFile == "" |
||||
} |
||||
|
||||
func (loader *basicBLSLoader) validateInput() error { |
||||
emptyKeyFile := !stringIsSet(loader.BLSKeyFile) |
||||
emptyDir := !stringIsSet(loader.BLSDir) |
||||
|
||||
if emptyKeyFile && emptyDir { |
||||
return fmt.Errorf("BLS key file or key directory has to be provided") |
||||
} |
||||
return nil |
||||
} |
||||
|
||||
func (loader *basicBLSLoader) loadPassProvider() { |
||||
var provider passProvider |
||||
|
||||
if stringIsSet(loader.BLSPassFile) { |
||||
provider = &filePassProvider{*loader.BLSPassFile} |
||||
} else if stringIsSet(loader.BLSKeyFile) { |
||||
provider = &promptPassProvider{} |
||||
} else { |
||||
provider = multiPassProvider{ |
||||
&dirPassProvider{*loader.BLSKeyFile}, |
||||
&promptPassProvider{}, |
||||
} |
||||
} |
||||
|
||||
loader.passProvider = provider |
||||
} |
||||
|
||||
func (loader *basicBLSLoader) getTargetKeyFiles() ([]string, error) { |
||||
if loader.BLSKeyFile != nil && *loader.BLSKeyFile != "" { |
||||
return []string{*loader.BLSKeyFile}, nil |
||||
} |
||||
return loader.getKeyFilesFromDir(*loader.BLSDir) |
||||
} |
||||
|
||||
func (loader *basicBLSLoader) getKeyFilesFromDir(dir string) ([]string, error) { |
||||
var keyFilePaths []string |
||||
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { |
||||
if isBasicKeyFile(info) { |
||||
keyFilePaths = append(keyFilePaths, path) |
||||
} |
||||
return nil |
||||
}) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
return keyFilePaths, nil |
||||
} |
||||
|
||||
func stringIsSet(val *string) bool { |
||||
return val != nil && *val != "" |
||||
} |
||||
|
||||
// isBasicKeyFile return whether the given file is a bls file
|
||||
func isBasicKeyFile(info os.FileInfo) bool { |
||||
if info.IsDir() { |
||||
return false |
||||
} |
||||
if !strings.HasSuffix(info.Name(), basicKeyExt) { |
||||
return false |
||||
} |
||||
return true |
||||
} |
||||
|
||||
func loadBasicKey(keyStr string, keyFile string, provider passProvider) (*ffi_bls.SecretKey, error) { |
||||
pass, err := provider.getPassphrase(keyStr) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
return blsgen.LoadBLSKeyWithPassPhrase(keyFile, pass) |
||||
} |
@ -0,0 +1,12 @@ |
||||
package blsloader |
||||
|
||||
import ( |
||||
"sync" |
||||
|
||||
"github.com/aws/aws-sdk-go/service/kms" |
||||
) |
||||
|
||||
var ( |
||||
kmsClient *kms.KMS |
||||
kmsInitOnce sync.Once |
||||
) |
@ -0,0 +1,7 @@ |
||||
package blsloader |
||||
|
||||
const ( |
||||
passExt = ".pass" |
||||
basicKeyExt = ".key" |
||||
kmsKeyExt = ".bls" |
||||
) |
@ -0,0 +1,84 @@ |
||||
package blsloader |
||||
|
||||
import ( |
||||
"fmt" |
||||
"io/ioutil" |
||||
"os" |
||||
"path/filepath" |
||||
"syscall" |
||||
|
||||
"golang.org/x/crypto/ssh/terminal" |
||||
) |
||||
|
||||
// passProvider is the interface to provide the passphrase of a bls keys.
|
||||
// Implemented by
|
||||
// emptyPassProvider - provide empty passphrase
|
||||
// promptPassProvider - provide passphrase through user-interactive prompt
|
||||
// filePassProvider - provide passphrase from a .pass file
|
||||
// dirPassProvider - provide passphrase from .pass files in a directory
|
||||
// multiPassProvider - multiple passProviders that will provide the passphrase.
|
||||
type passProvider interface { |
||||
getPassphrase(blsPubStr string) (string, error) |
||||
} |
||||
|
||||
// promptPassProvider provides the bls password through console prompt.
|
||||
type promptPassProvider struct{} |
||||
|
||||
const pwdPromptStr = "Enter passphrase for the BLS key file %s:" |
||||
|
||||
func (provider *promptPassProvider) getPassphrase(blsPubStr string) (string, error) { |
||||
fmt.Printf(pwdPromptStr, blsPubStr) |
||||
hexBytes, err := terminal.ReadPassword(syscall.Stdin) |
||||
if err != nil { |
||||
return "", err |
||||
} |
||||
return string(hexBytes), nil |
||||
} |
||||
|
||||
// filePassProvider provide the bls password from the single bls pass file
|
||||
type filePassProvider struct { |
||||
file string |
||||
} |
||||
|
||||
func (provider *filePassProvider) getPassphrase(blsPubStr string) (string, error) { |
||||
return readPassFromFile(provider.file) |
||||
} |
||||
|
||||
func readPassFromFile(file string) (string, error) { |
||||
f, err := os.Open(file) |
||||
if err != nil { |
||||
return "", fmt.Errorf("cannot open passphrase file: [%s]", file) |
||||
} |
||||
defer f.Close() |
||||
|
||||
b, err := ioutil.ReadAll(f) |
||||
if err != nil { |
||||
return "", err |
||||
} |
||||
return string(b), nil |
||||
} |
||||
|
||||
// dirPassProvider provide the all bls password available in the directory.
|
||||
type dirPassProvider struct { |
||||
dirPath string |
||||
} |
||||
|
||||
func (provider *dirPassProvider) getPassphrase(blsPubStr string) (string, error) { |
||||
file := filepath.Join(provider.dirPath, blsPubStr+passExt) |
||||
return readPassFromFile(file) |
||||
} |
||||
|
||||
// multiPassProvider is a slice of passProviders to provide the passphrase
|
||||
// of the given bls key. If a passProvider fails, will continue to the next provider.
|
||||
type multiPassProvider []passProvider |
||||
|
||||
func (provider multiPassProvider) getPassphrase(blsPubStr string) (string, error) { |
||||
for _, pp := range provider { |
||||
pass, err := pp.getPassphrase(blsPubStr) |
||||
if err != nil { |
||||
continue |
||||
} |
||||
return pass, err |
||||
} |
||||
return "", fmt.Errorf("cannot get passphrase for %s", blsPubStr) |
||||
} |
Loading…
Reference in new issue