parent
6d2fa888fc
commit
cc600f9879
@ -0,0 +1,235 @@ |
||||
package blsloader |
||||
|
||||
import ( |
||||
"errors" |
||||
"fmt" |
||||
"os" |
||||
"path/filepath" |
||||
|
||||
bls_core "github.com/harmony-one/bls/ffi/go/bls" |
||||
"github.com/harmony-one/harmony/multibls" |
||||
) |
||||
|
||||
// loadHelper defines the interface to help load bls keys
|
||||
type loadHelper interface { |
||||
loadKeys() (multibls.PrivateKeys, error) |
||||
} |
||||
|
||||
// basicSingleBlsLoader loads a single bls key file with passphrase
|
||||
type basicSingleBlsLoader struct { |
||||
blsKeyFile string |
||||
|
||||
passProviderConfig |
||||
} |
||||
|
||||
// loadKeys load bls keys from a single bls file
|
||||
func (loader *basicSingleBlsLoader) loadKeys() (multibls.PrivateKeys, error) { |
||||
providers, err := loader.getPassProviders() |
||||
if err != nil { |
||||
return multibls.PrivateKeys{}, err |
||||
} |
||||
secretKey, err := loadBasicKey(loader.blsKeyFile, providers) |
||||
if err != nil { |
||||
return multibls.PrivateKeys{}, err |
||||
} |
||||
return multibls.GetPrivateKeys(secretKey), nil |
||||
} |
||||
|
||||
func (loader *basicSingleBlsLoader) getPassProviders() ([]passProvider, error) { |
||||
switch loader.passSrcType { |
||||
case PassSrcFile: |
||||
return []passProvider{loader.getFilePassProvider()}, nil |
||||
case PassSrcPrompt: |
||||
return []passProvider{loader.getPromptPassProvider()}, nil |
||||
case PassSrcAuto: |
||||
return []passProvider{ |
||||
loader.getFilePassProvider(), |
||||
loader.getPromptPassProvider(), |
||||
}, nil |
||||
default: |
||||
return nil, errors.New("unknown passphrase source type") |
||||
} |
||||
} |
||||
|
||||
func (loader *basicSingleBlsLoader) getFilePassProvider() passProvider { |
||||
if stringIsSet(loader.passFile) { |
||||
return newFilePassProvider(*loader.passFile) |
||||
} |
||||
passFile := keyFileToPassFileFull(loader.blsKeyFile) |
||||
return newFilePassProvider(passFile) |
||||
} |
||||
|
||||
func (loader *basicSingleBlsLoader) getPromptPassProvider() passProvider { |
||||
provider := newPromptPassProvider() |
||||
if loader.persistPassphrase { |
||||
provider.setPersist(filepath.Dir(loader.blsKeyFile)) |
||||
} |
||||
return provider |
||||
} |
||||
|
||||
type kmsSingleBlsLoader struct { |
||||
blsKeyFile string |
||||
|
||||
kmsProviderConfig |
||||
} |
||||
|
||||
// loadKeys load a single kms key file
|
||||
func (loader *kmsSingleBlsLoader) loadKeys() (multibls.PrivateKeys, error) { |
||||
provider, err := loader.getKmsClientProvider() |
||||
if err != nil { |
||||
return multibls.PrivateKeys{}, err |
||||
} |
||||
secretKey, err := loadKmsKeyFromFile(loader.blsKeyFile, provider) |
||||
if err != nil { |
||||
return multibls.PrivateKeys{}, err |
||||
} |
||||
return multibls.GetPrivateKeys(secretKey), nil |
||||
} |
||||
|
||||
func (loader *kmsSingleBlsLoader) getKmsClientProvider() (kmsClientProvider, error) { |
||||
switch loader.awsCfgSrcType { |
||||
case AwsCfgSrcFile: |
||||
if stringIsSet(loader.awsConfigFile) { |
||||
return newFileKmsProvider(*loader.awsConfigFile), nil |
||||
} |
||||
return newSharedKmsProvider(), nil |
||||
case AwsCfgSrcPrompt: |
||||
return newPromptKmsProvider(defKmsPromptTimeout), nil |
||||
case AwsCfgSrcShared: |
||||
return newSharedKmsProvider(), nil |
||||
default: |
||||
return nil, errors.New("unknown aws config source type") |
||||
} |
||||
} |
||||
|
||||
// blsDirLoader is the helper structure for loading bls keys in a directory
|
||||
type blsDirLoader struct { |
||||
// input fields
|
||||
dirPath string |
||||
passProviderConfig |
||||
kmsProviderConfig |
||||
|
||||
// providers in process
|
||||
pps []passProvider |
||||
kcp kmsClientProvider |
||||
// result field
|
||||
secretKeys []*bls_core.SecretKey |
||||
} |
||||
|
||||
// loadKeys load all keys from the directory
|
||||
func (loader *blsDirLoader) loadKeys() (multibls.PrivateKeys, error) { |
||||
var err error |
||||
if loader.pps, err = loader.getPassProviders(); err != nil { |
||||
return multibls.PrivateKeys{}, err |
||||
} |
||||
if loader.kcp, err = loader.getKmsClientProvider(); err != nil { |
||||
return multibls.PrivateKeys{}, err |
||||
} |
||||
return loader.loadKeyFiles() |
||||
} |
||||
|
||||
func (loader *blsDirLoader) getPassProviders() ([]passProvider, error) { |
||||
switch loader.passSrcType { |
||||
case PassSrcFile: |
||||
return []passProvider{loader.getFilePassProvider()}, nil |
||||
case PassSrcPrompt: |
||||
return []passProvider{loader.getPromptPassProvider()}, nil |
||||
case PassSrcAuto: |
||||
return []passProvider{ |
||||
loader.getFilePassProvider(), |
||||
loader.getPromptPassProvider(), |
||||
}, nil |
||||
default: |
||||
return nil, errors.New("unknown pass source type") |
||||
} |
||||
} |
||||
|
||||
func (loader *blsDirLoader) getFilePassProvider() passProvider { |
||||
if stringIsSet(loader.passFile) { |
||||
return newFilePassProvider(*loader.passFile) |
||||
} |
||||
return newDirPassProvider(loader.dirPath) |
||||
} |
||||
|
||||
func (loader *blsDirLoader) getPromptPassProvider() passProvider { |
||||
provider := newPromptPassProvider() |
||||
if loader.persistPassphrase { |
||||
provider.setPersist(loader.dirPath) |
||||
} |
||||
return provider |
||||
} |
||||
|
||||
func (loader *blsDirLoader) getKmsClientProvider() (kmsClientProvider, error) { |
||||
switch loader.awsCfgSrcType { |
||||
case AwsCfgSrcFile: |
||||
if stringIsSet(loader.awsConfigFile) { |
||||
return newFileKmsProvider(*loader.awsConfigFile), nil |
||||
} |
||||
return newSharedKmsProvider(), nil |
||||
case AwsCfgSrcPrompt: |
||||
return newPromptKmsProvider(defKmsPromptTimeout), nil |
||||
case AwsCfgSrcShared: |
||||
return newSharedKmsProvider(), nil |
||||
default: |
||||
return nil, errors.New("unknown aws config source type") |
||||
} |
||||
} |
||||
|
||||
func (loader *blsDirLoader) loadKeyFiles() (multibls.PrivateKeys, error) { |
||||
err := filepath.Walk(loader.dirPath, loader.processFileWalk) |
||||
if err != nil { |
||||
return multibls.PrivateKeys{}, err |
||||
} |
||||
return multibls.GetPrivateKeys(loader.secretKeys...), nil |
||||
} |
||||
|
||||
func (loader *blsDirLoader) processFileWalk(path string, info os.FileInfo, err error) error { |
||||
key, err := loader.loadKeyFromFile(path, info) |
||||
if err != nil { |
||||
if !errIsErrors(err, loader.skippingErrors()) { |
||||
// unexpected error, return the error and break the file walk loop
|
||||
return err |
||||
} |
||||
// expected error. Skipping these files
|
||||
skipStr := fmt.Sprintf("Skipping [%s]: %v\n", path, err) |
||||
console.println(skipStr) |
||||
return nil |
||||
} |
||||
loader.secretKeys = append(loader.secretKeys, key) |
||||
return nil |
||||
} |
||||
|
||||
// errors to be neglected for directory bls loading
|
||||
func (loader *blsDirLoader) skippingErrors() []error { |
||||
return []error{ |
||||
errUnknownExtension, |
||||
errNilPassProvider, |
||||
errNilKMSClientProvider, |
||||
} |
||||
} |
||||
|
||||
func (loader *blsDirLoader) loadKeyFromFile(path string, info os.FileInfo) (*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 { |
||||
for _, targetErr := range errs { |
||||
if errors.Is(err, targetErr) { |
||||
return true |
||||
} |
||||
} |
||||
return false |
||||
} |
Loading…
Reference in new issue