The core protocol of WoopChain
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
woop/cmd/harmony/bls.go

270 lines
8.3 KiB

package main
import (
"errors"
"flag"
"fmt"
"strings"
"sync"
"github.com/spf13/cobra"
"github.com/harmony-one/harmony/internal/blsgen"
"github.com/harmony-one/harmony/internal/cli"
"github.com/harmony-one/harmony/multibls"
)
var (
blsKeyFile = flag.String("blskey_file", "", "The encrypted file of bls serialized private key by passphrase.")
blsFolder = flag.String("blsfolder", ".hmy/blskeys", "The folder that stores the bls keys and corresponding passphrases; e.g. <blskey>.key and <blskey>.pass; all bls keys mapped to same shard")
maxBLSKeysPerNode = flag.Int("max_bls_keys_per_node", 10, "Maximum number of bls keys allowed per node (default 4)")
blsPass = flag.String("blspass", "default", "The source for bls passphrases. (default, no-prompt, prompt, file:$PASS_FILE, none)")
persistPass = flag.Bool("save-passphrase", false, "Whether the prompt passphrase is saved after prompt.")
awsConfigSource = flag.String("aws-config-source", "default", "The source for aws config. (default, prompt, file:$CONFIG_FILE, none)")
)
var (
multiBLSPriKey multibls.PrivateKeys
onceLoadBLSKey sync.Once
)
var blsFlags = []cli.Flag{
blsDirFlag,
blsKeyFilesFlag,
maxBLSKeyFilesFlag,
passEnabledFlag,
passSrcTypeFlag,
passSrcFileFlag,
passSaveFlag,
kmsEnabledFlag,
kmsConfigSrcTypeFlag,
kmsConfigFileFlag,
}
var legacyBLSFlags = []cli.Flag{
legacyBLSKeyFileFlag,
legacyBLSFolderFlag,
legacyBLSKeysPerNodeFlag,
legacyBLSPassFlag,
legacyBLSPersistPassFlag,
legacyKMSConfigSourceFlag,
}
var (
blsDirFlag = cli.StringFlag{
Name: "bls.dir",
Usage: "directory for BLS keys",
DefValue: defaultConfig.BLSKeys.KeyDir,
}
blsKeyFilesFlag = cli.StringSliceFlag{
Name: "bls.keys",
Usage: "a list of BLS key files (separated by ,)",
DefValue: defaultConfig.BLSKeys.KeyFiles,
}
// TODO: shall we move this to a hard coded parameter?
maxBLSKeyFilesFlag = cli.IntFlag{
Name: "bls.maxkeys",
Usage: "maximum number of BLS keys for a node",
DefValue: defaultConfig.BLSKeys.MaxKeys,
}
passEnabledFlag = cli.BoolFlag{
Name: "bls.pass",
Usage: "whether BLS key decryption with passphrase is enabled",
DefValue: defaultConfig.BLSKeys.PassEnabled,
}
passSrcTypeFlag = cli.StringFlag{
Name: "bls.pass.src",
Usage: "source for BLS passphrase (auto, file, prompt)",
DefValue: defaultConfig.BLSKeys.PassSrcType,
}
passSrcFileFlag = cli.StringFlag{
Name: "bls.pass.file",
Usage: "the pass file used for BLS decryption. If specified, this pass file will be used for all BLS keys",
DefValue: defaultConfig.BLSKeys.PassFile,
}
passSaveFlag = cli.BoolFlag{
Name: "bls.pass.save",
Usage: "after input the BLS passphrase from console, whether to persist the input passphrases in .pass file",
DefValue: defaultConfig.BLSKeys.SavePassphrase,
}
kmsEnabledFlag = cli.BoolFlag{
Name: "bls.kms",
Usage: "whether BLS key decryption with AWS KMS service is enabled",
DefValue: defaultConfig.BLSKeys.KMSEnabled,
}
kmsConfigSrcTypeFlag = cli.StringFlag{
Name: "bls.kms.src",
Usage: "the AWS config source (region and credentials) for KMS service (shared, prompt, file)",
DefValue: defaultConfig.BLSKeys.KMSConfigSrcType,
}
kmsConfigFileFlag = cli.StringFlag{
Name: "bls.kms.config",
Usage: "json config file for KMS service (region and credentials)",
DefValue: defaultConfig.BLSKeys.KMSConfigFile,
}
legacyBLSKeyFileFlag = cli.StringSliceFlag{
Name: "blskey_file",
Usage: "The encrypted file of bls serialized private key by passphrase.",
DefValue: defaultConfig.BLSKeys.KeyFiles,
Deprecated: "use --bls.keys",
}
legacyBLSFolderFlag = cli.StringFlag{
Name: "blsfolder",
Usage: "The folder that stores the bls keys and corresponding passphrases; e.g. <blskey>.key and <blskey>.pass; all bls keys mapped to same shard",
DefValue: defaultConfig.BLSKeys.KeyDir,
Deprecated: "use --bls.dir",
}
legacyBLSKeysPerNodeFlag = cli.IntFlag{
Name: "max_bls_keys_per_node",
Usage: "Maximum number of bls keys allowed per node",
DefValue: defaultConfig.BLSKeys.MaxKeys,
Deprecated: "use --bls.maxkeys",
}
legacyBLSPassFlag = cli.StringFlag{
Name: "blspass",
Usage: "The source for bls passphrases. (default, stdin, no-prompt, prompt, file:$PASS_FILE, none)",
DefValue: "default",
Deprecated: "use --bls.pass, --bls.pass.src, --bls.pass.file",
}
legacyBLSPersistPassFlag = cli.BoolFlag{
Name: "save-passphrase",
Usage: "Whether the prompt passphrase is saved after prompt.",
DefValue: defaultConfig.BLSKeys.SavePassphrase,
Deprecated: "use --bls.pass.save",
}
legacyKMSConfigSourceFlag = cli.StringFlag{
Name: "aws-config-source",
Usage: "The source for aws config. (default, prompt, file:$CONFIG_FILE, none)",
DefValue: "default",
Deprecated: "use --bls.kms, --bls.kms.src, --bls.kms.config",
}
)
func applyBLSFlags(cmd *cobra.Command, config *hmyConfig) {
if cli.HasFlagChanged(cmd, blsDirFlag) {
config.BLSKeys.KeyDir = cli.GetStringFlagValue(cmd, blsDirFlag)
} else if cli.HasFlagChanged(cmd, legacyBLSFolderFlag) {
config.BLSKeys.KeyDir = cli.GetStringFlagValue(cmd, legacyBLSFolderFlag)
}
if cli.HasFlagChanged(cmd, blsKeyFilesFlag) {
config.BLSKeys.KeyFiles = cli.GetStringSliceFlagValue(cmd, blsKeyFilesFlag)
} else if cli.HasFlagChanged(cmd, legacyBLSKeyFileFlag) {
config.BLSKeys.KeyFiles = cli.GetStringSliceFlagValue(cmd, legacyBLSKeyFileFlag)
}
if cli.HasFlagChanged(cmd, maxBLSKeyFilesFlag) {
config.BLSKeys.MaxKeys = cli.GetIntFlagValue(cmd, maxBLSKeyFilesFlag)
} else if cli.HasFlagChanged(cmd, legacyBLSKeysPerNodeFlag) {
config.BLSKeys.MaxKeys = cli.GetIntFlagValue(cmd, legacyBLSKeysPerNodeFlag)
}
if cli.HasFlagsChanged(cmd, blsFlags) {
applyBLSPassFlags(cmd, config)
applyKMSFlags(cmd, config)
} else if cli.HasFlagsChanged(cmd, legacyBLSFlags) {
applyLegacyBLSPassFlags(cmd, config)
applyLegacyKMSFlags(cmd, config)
}
}
func applyBLSPassFlags(cmd *cobra.Command, config *hmyConfig) {
}
func applyKMSFlags(cmd *cobra.Command, config *hmyConfig) {
}
func applyLegacyBLSPassFlags(cmd *cobra.Command, config *hmyConfig) {
}
func applyLegacyKMSFlags(cmd *cobra.Command, config *hmyConfig) {
}
func loadBLSKeys() (multibls.PrivateKeys, error) {
config, err := parseBLSLoadingConfig()
if err != nil {
return nil, err
}
keys, err := blsgen.LoadKeys(config)
if err != nil {
return nil, err
}
if len(keys) == 0 {
return nil, fmt.Errorf("0 bls keys loaded")
}
if len(keys) > *maxBLSKeysPerNode {
return nil, fmt.Errorf("bls keys exceed maximum count %v", *maxBLSKeysPerNode)
}
return keys, err
}
func parseBLSLoadingConfig() (blsgen.Config, error) {
var (
config blsgen.Config
err error
)
if len(*blsKeyFile) != 0 {
config.MultiBlsKeys = strings.Split(*blsKeyFile, ",")
}
config.BlsDir = blsFolder
config, err = parseBLSPass(config, *blsPass)
if err != nil {
return blsgen.Config{}, err
}
config, err = parseAwsConfigSrc(config, *awsConfigSource)
if err != nil {
return blsgen.Config{}, err
}
return config, nil
}
func parseBLSPass(config blsgen.Config, src string) (blsgen.Config, error) {
methodArgs := strings.SplitN(src, ":", 2)
method := methodArgs[0]
switch method {
case "default", "stdin":
config.PassSrcType = blsgen.PassSrcAuto
case "file":
config.PassSrcType = blsgen.PassSrcFile
if len(methodArgs) < 2 {
return blsgen.Config{}, errors.New("must specify passphrase file")
}
config.PassFile = &methodArgs[1]
case "no-prompt":
config.PassSrcType = blsgen.PassSrcFile
case "prompt":
config.PassSrcType = blsgen.PassSrcPrompt
config.PersistPassphrase = *persistPass
case "none":
config.PassSrcType = blsgen.PassSrcNil
}
config.PersistPassphrase = *persistPass
return config, nil
}
func parseAwsConfigSrc(config blsgen.Config, src string) (blsgen.Config, error) {
methodArgs := strings.SplitN(src, ":", 2)
method := methodArgs[0]
switch method {
case "default":
config.AwsCfgSrcType = blsgen.AwsCfgSrcShared
case "file":
config.AwsCfgSrcType = blsgen.AwsCfgSrcFile
if len(methodArgs) < 2 {
return blsgen.Config{}, errors.New("must specify aws config file")
}
config.AwsConfigFile = &methodArgs[1]
case "prompt":
config.AwsCfgSrcType = blsgen.AwsCfgSrcPrompt
case "none":
config.AwsCfgSrcType = blsgen.AwsCfgSrcNil
}
return config, nil
}