Skip to content

Commit

Permalink
added bls support for harmony
Browse files Browse the repository at this point in the history
  • Loading branch information
coolcottontail committed Apr 1, 2020
1 parent 00b3abe commit d84b2d2
Show file tree
Hide file tree
Showing 3 changed files with 127 additions and 6 deletions.
34 changes: 30 additions & 4 deletions cmd/harmony/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ var (
// shardID indicates the shard ID of this node
shardID = flag.Int("shard_id", -1, "the shard ID of this node")
enableMemProfiling = flag.Bool("enableMemProfiling", false, "Enable memsize logging.")
cmkEncryptedBLSKey = flag.String("aws_blskey", "", "The aws CMK encrypted bls private key file.")
enableGC = flag.Bool("enableGC", true, "Enable calling garbage collector manually .")
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; same blspass is used to decrypt all bls keys; all bls keys mapped to same shard")
Expand Down Expand Up @@ -157,12 +158,16 @@ var (
revertTo = flag.Int("revert_to", -1, "The revert will rollback all blocks until and including block number revert_to")
// Blacklist of addresses
blacklistPath = flag.String("blacklist", "./.hmy/blacklist.txt", "Path to newline delimited file of blacklisted wallet addresses")

// aws credentials
awsSettingString = ""
)

func initSetup() {

// maybe request passphrase for bls key.
passphraseForBls()
if *cmkEncryptedBLSKey == "" {
passphraseForBls()
}

// Configure log parameters
utils.SetLogContext(*port, *ip)
Expand Down Expand Up @@ -267,11 +272,20 @@ func readMultiBlsKeys(consensusMultiBlsPriKey *nodeconfig.MultiBlsPrivateKey, co
}

for _, blsKeyFile := range blsKeyFiles {
if filepath.Ext(blsKeyFile.Name()) != ".key" {
if filepath.Ext(blsKeyFile.Name()) != ".key" || filepath.Ext(blsKeyFile.Name()) != ".bls" {
continue
}

var consensusPriKey *bls.SecretKey
var err error
blsKeyFilePath := path.Join(*multiBlsKeyDir, blsKeyFile.Name())
consensusPriKey, err := blsgen.LoadBlsKeyWithPassPhrase(blsKeyFilePath, blsPassphrase) // uses the same bls passphrase for multiple bls keys
if filepath.Ext(blsKeyFile.Name()) == ".key" {
// uses the same bls passphrase for multiple bls keys
consensusPriKey, err = blsgen.LoadBlsKeyWithPassPhrase(blsKeyFilePath, blsPassphrase)
} else {
consensusPriKey, err = blsgen.LoadAwsCMKEncryptedBLSKey(blsKeyFilePath, awsSettingString)
}

if err != nil {
return err
}
Expand All @@ -292,6 +306,15 @@ func setupConsensusKey(nodeConfig *nodeconfig.ConfigType) nodeconfig.MultiBlsPub
_, _ = fmt.Fprintf(os.Stderr, "ERROR when loading bls key, err :%v\n", err)
os.Exit(100)
}
nodeconfig.AppendPriKey(&consensusMultiPriKey, consensusPriKey)
nodeconfig.AppendPubKey(&consensusMultiPubKey, consensusPriKey.GetPublicKey())
} else if *cmkEncryptedBLSKey != "" {
consensusPriKey, err := blsgen.LoadAwsCMKEncryptedBLSKey(*cmkEncryptedBLSKey, awsSettingString)
if err != nil {
fmt.Fprintf(os.Stderr, "ERROR when loading aws CMK encrypted bls key, err :%v\n", err)
os.Exit(100)
}

nodeconfig.AppendPriKey(&consensusMultiPriKey, consensusPriKey)
nodeconfig.AppendPubKey(&consensusMultiPubKey, consensusPriKey.GetPublicKey())
} else {
Expand Down Expand Up @@ -517,6 +540,9 @@ func main() {
// build time.
os.Setenv("GODEBUG", "netdns=go")

// Get aws credentials from prompt timeout 1 second if there's no input
awsSettingString, _ = blsgen.Readln(1 * time.Second)

flag.Var(&utils.BootNodes, "bootnodes", "a list of bootnode multiaddress (delimited by ,)")
flag.Parse()

Expand Down
5 changes: 3 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require (
github.com/Workiva/go-datastructures v1.0.50
github.com/allegro/bigcache v1.2.1 // indirect
github.com/aristanetworks/goarista v0.0.0-20190607111240-52c2a7864a08 // indirect
github.com/aws/aws-sdk-go v1.30.2
github.com/beorn7/perks v1.0.1 // indirect
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d
github.com/cespare/cp v1.1.1
Expand Down Expand Up @@ -45,7 +46,7 @@ require (
github.com/multiformats/go-multiaddr-net v0.1.2
github.com/natefinch/lumberjack v2.0.0+incompatible
github.com/pborman/uuid v1.2.0
github.com/pkg/errors v0.8.1
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v0.9.3
github.com/prometheus/common v0.4.1 // indirect
github.com/prometheus/procfs v0.0.3 // indirect
Expand All @@ -54,7 +55,7 @@ require (
github.com/rs/zerolog v1.14.3
github.com/shirou/gopsutil v2.18.12+incompatible
github.com/spf13/cobra v0.0.5
github.com/stretchr/testify v1.4.0
github.com/stretchr/testify v1.5.1
github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965
github.com/uber/jaeger-client-go v2.20.1+incompatible // indirect
github.com/uber/jaeger-lib v2.2.0+incompatible // indirect
Expand Down
94 changes: 94 additions & 0 deletions internal/blsgen/lib.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
package blsgen

import (
"bufio"
"crypto/aes"
"crypto/cipher"
"crypto/md5"
"crypto/rand"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"os"
"time"

"github.com/pkg/errors"

"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"
ffi_bls "github.com/harmony-one/bls/ffi/go/bls"

"github.com/harmony-one/harmony/crypto/bls"
)

type awsConfiguration struct {
AccessKey string `json:"aws-access-key-id"`
SecretKey string `json:"aws-secret-access-key"`
Region string `json:"aws-region"`
}

func toISO8601(t time.Time) string {
var tz string
name, offset := t.Zone()
Expand Down Expand Up @@ -94,6 +108,86 @@ func LoadBlsKeyWithPassPhrase(fileName, passphrase string) (*ffi_bls.SecretKey,
return priKey, nil
}

// Readln reads aws configuratoin from prompt with a timeout
func Readln(timeout time.Duration) (string, error) {
s := make(chan string)
e := make(chan error)

go func() {
reader := bufio.NewReader(os.Stdin)
line, err := reader.ReadString('\n')
if err != nil {
e <- err
} else {
s <- line
}
close(s)
close(e)
}()

select {
case line := <-s:
return line, nil
case err := <-e:
return "", err
case <-time.After(timeout):
return "", errors.New("Timeout")
}
}

// LoadAwsCMKEncryptedBLSKey loads aws encrypted bls key.
func LoadAwsCMKEncryptedBLSKey(fileName, awsSettingString string) (*ffi_bls.SecretKey, error) {
if awsSettingString == "" {
return nil, errors.New("aws credential is not set")
}

var awsConfig awsConfiguration
if err := json.Unmarshal([]byte(awsSettingString), &awsConfig); err != nil {
return nil, errors.New(awsSettingString + " is not a valid JSON string for setting aws configuration.")
}

// Initialize a session that the aws SDK uses to load
sess, err := session.NewSessionWithOptions(session.Options{
SharedConfigState: session.SharedConfigEnable,
})

if err != nil {
return nil, errors.Wrapf(err, "failed to create aws session")
}

// Create KMS service client
svc := kms.New(sess, &aws.Config{
//Region: aws.String("us-east-1"),
Region: aws.String(awsConfig.Region),
Credentials: credentials.NewStaticCredentials(awsConfig.AccessKey, awsConfig.SecretKey, ""),
})

encryptedPrivateKeyBytes, err := ioutil.ReadFile(fileName)
if err != nil {
return nil, errors.Wrapf(err, "fail read at: %s", fileName)
}

unhexed := make([]byte, hex.DecodedLen(len(encryptedPrivateKeyBytes)))
if _, err = hex.Decode(unhexed, encryptedPrivateKeyBytes); err != nil {
return nil, err
}

clearKey, err := svc.Decrypt(&kms.DecryptInput{
CiphertextBlob: unhexed,
})

if err != nil {
return nil, err
}

priKey := &ffi_bls.SecretKey{}
if err = priKey.DeserializeHexStr(hex.EncodeToString(clearKey.Plaintext)); err != nil {
return nil, errors.Wrapf(err, "failed to deserialize the decrypted bls private key")
}

return priKey, nil
}

func createHash(key string) string {
hasher := md5.New()
hasher.Write([]byte(key))
Expand Down

0 comments on commit d84b2d2

Please sign in to comment.