diff --git a/Makefile b/Makefile index 913a5d25da21868ca810efa834d8a77ea8cf7252..649eb0996a05b3c240751e5e99f8da386b1a8a18 100644 --- a/Makefile +++ b/Makefile @@ -156,8 +156,12 @@ docker_build: check commit_hash test: check @go test ${PACKAGES_NOVENDOR} +.PHONY: test_keys +test_keys: build_db + burrow_bin="${REPO}/bin/burrow" keys/test.sh + .PHONY: test_integration -test_integration: +test_integration: test_keys @go test -tags integration ./rpc/v0/integration @go test -tags integration ./rpc/tm/integration diff --git a/client/methods/call.go b/client/methods/call.go index c613ff489f089c14d0a8286127ad47c2abecea3b..38271439ae27955983272440f640df28c6eeebde 100644 --- a/client/methods/call.go +++ b/client/methods/call.go @@ -29,7 +29,10 @@ func Call(do *client.Do) error { if err != nil { return fmt.Errorf("Could not generate logging config from Do: %s", err) } - burrowKeyClient := keys.NewKeyClient(do.SignAddrFlag, logger) + burrowKeyClient, err := keys.NewRemoteKeyClient(do.SignAddrFlag, logger) + if err != nil { + return fmt.Errorf("Could not create remote key client: %s", err) + } burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger) // form the call transaction callTransaction, err := rpc.Call(burrowNodeClient, burrowKeyClient, diff --git a/client/methods/send.go b/client/methods/send.go index b9736d5065816f1ec43a69c9479288c99a0cffcf..e04771e185b358a22c0e8fcb53b99adb47504bc9 100644 --- a/client/methods/send.go +++ b/client/methods/send.go @@ -29,7 +29,10 @@ func Send(do *client.Do) error { if err != nil { return fmt.Errorf("Could not generate logging config from Do: %s", err) } - burrowKeyClient := keys.NewKeyClient(do.SignAddrFlag, logger) + burrowKeyClient, err := keys.NewRemoteKeyClient(do.SignAddrFlag, logger) + if err != nil { + return fmt.Errorf("Could not create remote key client: %s", err) + } burrowNodeClient := client.NewBurrowNodeClient(do.NodeAddrFlag, logger) // form the send transaction sendTransaction, err := rpc.Send(burrowNodeClient, burrowKeyClient, diff --git a/cmd/burrow/commands/configure.go b/cmd/burrow/commands/configure.go index 97c64432f120452f7db6e5c8004081e235687f7c..a964e2f9eb86b330eb34327ccfb8d31bbdc43c1b 100644 --- a/cmd/burrow/commands/configure.go +++ b/cmd/burrow/commands/configure.go @@ -12,7 +12,6 @@ import ( "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/genesis/spec" "github.com/hyperledger/burrow/keys" - "github.com/hyperledger/burrow/keys/mock" "github.com/hyperledger/burrow/logging" logging_config "github.com/hyperledger/burrow/logging/config" "github.com/hyperledger/burrow/logging/config/presets" @@ -27,8 +26,8 @@ func Configure(output Output) func(cmd *cli.Cmd) { jsonOutOpt := cmd.BoolOpt("j json", false, "Emit config in JSON rather than TOML "+ "suitable for further processing") - keysUrlOpt := cmd.StringOpt("k keys-url", "", fmt.Sprintf("Provide keys URL, default: %s", - keys.DefaultKeysConfig().URL)) + keysUrlOpt := cmd.StringOpt("k keys-url", "", fmt.Sprintf("Provide keys GRPC address, default: %s", + keys.DefaultKeysConfig().RemoteAddress)) configOpt := cmd.StringOpt("c base-config", "", "Use the a specified burrow config file as a base") @@ -85,7 +84,7 @@ func Configure(output Output) func(cmd *cli.Cmd) { } if *keysUrlOpt != "" { - conf.Keys.URL = *keysUrlOpt + conf.Keys.RemoteAddress = *keysUrlOpt } // Genesis Spec @@ -95,14 +94,22 @@ func Configure(output Output) func(cmd *cli.Cmd) { if err != nil { output.Fatalf("Could not read GenesisSpec: %v", err) } + keyStore := keys.NewKeyStore(conf.Keys.KeysDirectory) if *generateKeysOpt != "" { - keyClient := mock.NewKeyClient() + keyClient := keys.NewLocalKeyClient(keyStore, logging.NewNoopLogger()) conf.GenesisDoc, err = genesisSpec.GenesisDoc(keyClient) if err != nil { output.Fatalf("Could not generate GenesisDoc from GenesisSpec using MockKeyClient: %v", err) } - pkg := deployment.Package{Keys: keyClient.Keys()} + allKeys, err := keyStore.AllKeys() + if err != nil { + output.Fatalf("could get all keys: %v", err) + } + pkg := deployment.Package{Keys: allKeys} + if err != nil { + output.Fatalf("Could not dump keys: %v", err) + } secretKeysString, err := pkg.Dump(*keysTemplateOpt) if err != nil { output.Fatalf("Could not dump keys: %v", err) @@ -112,8 +119,18 @@ func Configure(output Output) func(cmd *cli.Cmd) { output.Fatalf("Could not write secret keys: %v", err) } } else { - conf.GenesisDoc, err = genesisSpec.GenesisDoc(keys.NewKeyClient(conf.Keys.URL, logging.NewNoopLogger())) + var keyClient keys.KeyClient + if conf.Keys.RemoteAddress != "" { + keyClient, err = keys.NewRemoteKeyClient(conf.Keys.RemoteAddress, logging.NewNoopLogger()) + if err != nil { + output.Fatalf("Could not create remote key client: %v", err) + } + } else { + keyClient = keys.NewLocalKeyClient(keyStore, logging.NewNoopLogger()) + } + conf.GenesisDoc, err = genesisSpec.GenesisDoc(keyClient) } + if err != nil { output.Fatalf("could not realise GenesisSpec: %v", err) } diff --git a/cmd/burrow/commands/keys.go b/cmd/burrow/commands/keys.go index 4b9408c6f60f0915fc62c054b703cbe3019b7eb8..10b3c4fe240425a8b1fb8d48252af480befe306e 100644 --- a/cmd/burrow/commands/keys.go +++ b/cmd/burrow/commands/keys.go @@ -4,11 +4,12 @@ import ( "context" "encoding/hex" "fmt" - "io/ioutil" "os" "time" + "io/ioutil" + "github.com/howeyc/gopass" "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/keys" @@ -17,34 +18,37 @@ import ( "google.golang.org/grpc" ) -func grpcKeysClient(output Output) pbkeys.KeysClient { - var opts []grpc.DialOption - opts = append(opts, grpc.WithInsecure()) - conn, err := grpc.Dial(keys.KeyHost+":"+keys.KeyPort, opts...) - if err != nil { - output.Fatalf("Failed to connect to grpc server: %v", err) - } - return pbkeys.NewKeysClient(conn) -} - func Keys(output Output) func(cmd *cli.Cmd) { return func(cmd *cli.Cmd) { - if keysHost := os.Getenv("MONAX_KEYS_HOST"); keysHost != "" { - keys.DefaultHost = keysHost - } - if keysPort := os.Getenv("MONAX_KEYS_PORT"); keysPort != "" { - keys.DefaultPort = keysPort - } + keysHost := cmd.String(cli.StringOpt{ + Name: "host", + Desc: "set the host for talking to the key daemon", + Value: keys.DefaultHost, + EnvVar: "MONAX_KEYS_HOST", + }) - keys.KeyHost = *cmd.StringOpt("host", keys.DefaultHost, "set the host for talking to the key daemon") + keysPort := cmd.String(cli.StringOpt{ + Name: "host", + Desc: "set the port for key daemon", + Value: keys.DefaultPort, + EnvVar: "MONAX_KEYS_PORT", + }) - keys.KeyPort = *cmd.StringOpt("port", keys.DefaultPort, "set the port for key daemon") + grpcKeysClient := func(output Output) pbkeys.KeysClient { + var opts []grpc.DialOption + opts = append(opts, grpc.WithInsecure()) + conn, err := grpc.Dial(*keysHost+":"+*keysPort, opts...) + if err != nil { + output.Fatalf("Failed to connect to grpc server: %v", err) + } + return pbkeys.NewKeysClient(conn) + } cmd.Command("server", "run keys server", func(cmd *cli.Cmd) { - keys.KeysDir = *cmd.StringOpt("dir", keys.DefaultDir, "specify the location of the directory containing key files") + keysDir := cmd.StringOpt("dir", keys.DefaultKeysDir, "specify the location of the directory containing key files") cmd.Action = func() { - err := keys.StartStandAloneServer(keys.KeyHost, keys.KeyPort) + err := keys.StartStandAloneServer(*keysDir, *keysHost, *keysPort) if err != nil { output.Fatalf("Failed to start server: %v", err) } @@ -137,16 +141,24 @@ func Keys(output Output) func(cmd *cli.Cmd) { cmd.Command("import", "import <priv key> | /path/to/keyfile | <key json>", func(cmd *cli.Cmd) { curveType := cmd.StringOpt("t curvetype", "ed25519", "specify the curve type of key to create. Supports 'secp256k1' (ethereum), 'ed25519' (tendermint)") + noPassword := cmd.BoolOpt("n no-password", false, "don't use a password for this key") key := cmd.StringArg("KEY", "", "private key, filename, or raw json") cmd.Action = func() { - var privKeyBytes []byte - var err error - if _, err := os.Stat(*key); err == nil { - privKeyBytes, err = ioutil.ReadFile(*key) + var password string + if !*noPassword { + fmt.Printf("Enter Password:") + pwd, err := gopass.GetPasswdMasked() if err != nil { - output.Fatalf("Failed to read file %s: %v", *key, err) + os.Exit(1) } + password = string(pwd) + } + + var privKeyBytes []byte + fileContents, err := ioutil.ReadFile(*key) + if err == nil { + *key = string(fileContents) } c := grpcKeysClient(output) @@ -159,18 +171,18 @@ func Keys(output Output) func(cmd *cli.Cmd) { output.Fatalf("failed to import json key: %v", err) } - fmt.Printf("%X\n", resp.GetAddress()) + fmt.Printf("%s\n", resp.GetAddress()) } else { privKeyBytes, err = hex.DecodeString(*key) if err != nil { - output.Fatalf("failed to hex decode key") + output.Fatalf("failed to hex decode key: %s", *key) } - resp, err := c.Import(ctx, &pbkeys.ImportRequest{Keybytes: privKeyBytes, Curvetype: *curveType}) + resp, err := c.Import(ctx, &pbkeys.ImportRequest{Passphrase: password, Keybytes: privKeyBytes, Curvetype: *curveType}) if err != nil { output.Fatalf("failed to import json key: %v", err) } - fmt.Printf("%X\n", resp.GetAddress()) + fmt.Printf("%s\n", resp.GetAddress()) } } @@ -194,8 +206,9 @@ func Keys(output Output) func(cmd *cli.Cmd) { }) cmd.Command("sign", "sign <some data>", func(cmd *cli.Cmd) { + name := cmd.StringOpt("name", "", "name of key to use") addr := cmd.StringOpt("addr", "", "address of key to use") - msg := cmd.StringArg("HASH", "", "hash to sign") + msg := cmd.StringArg("MSG", "", "message to sign") passphrase := cmd.StringOpt("passphrase", "", "passphrase for encrypted key") cmd.Action = func() { @@ -207,7 +220,7 @@ func Keys(output Output) func(cmd *cli.Cmd) { c := grpcKeysClient(output) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - resp, err := c.Sign(ctx, &pbkeys.SignRequest{Passphrase: *passphrase, Address: *addr, Hash: message}) + resp, err := c.Sign(ctx, &pbkeys.SignRequest{Passphrase: *passphrase, Name: *name, Address: *addr, Message: message}) if err != nil { output.Fatalf("failed to get public key: %v", err) } @@ -241,22 +254,23 @@ func Keys(output Output) func(cmd *cli.Cmd) { c := grpcKeysClient(output) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - _, err = c.Verify(ctx, &pbkeys.VerifyRequest{Curvetype: *curveType, Pub: publickey, Signature: signature, Hash: message}) + _, err = c.Verify(ctx, &pbkeys.VerifyRequest{Curvetype: *curveType, Pub: publickey, Signature: signature, Message: message}) if err != nil { output.Fatalf("failed to verify: %v", err) } + output.Printf("true\n") } }) - cmd.Command("add", "add key by name or addr", func(cmd *cli.Cmd) { - name := cmd.StringArg("name", "", "name of key to use") - addr := cmd.StringArg("addr", "", "address of key to use") + cmd.Command("name", "add key name to addr", func(cmd *cli.Cmd) { + keyname := cmd.StringArg("NAME", "", "name of key to use") + addr := cmd.StringArg("ADDR", "", "address of key to use") cmd.Action = func() { c := grpcKeysClient(output) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - _, err := c.Add(ctx, &pbkeys.AddRequest{Keyname: *name, Address: *addr}) + _, err := c.AddName(ctx, &pbkeys.AddNameRequest{Keyname: *keyname, Address: *addr}) if err != nil { output.Fatalf("failed to add name to addr: %v", err) } @@ -274,20 +288,28 @@ func Keys(output Output) func(cmd *cli.Cmd) { if err != nil { output.Fatalf("failed to list key names: %v", err) } - for _, k := range resp.Key { - fmt.Printf("key: %v\n", k) + if *name != "" { + for _, k := range resp.Key { + if k.Keyname == *name { + output.Printf("%s\n", k.Address) + } + } + } else { + for _, k := range resp.Key { + fmt.Printf("%v\n", k) + } } } }) - cmd.Command("rm", "rm key by name", func(cmd *cli.Cmd) { + cmd.Command("rm", "rm key name", func(cmd *cli.Cmd) { name := cmd.StringArg("NAME", "", "key to remove") cmd.Action = func() { c := grpcKeysClient(output) ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - _, err := c.Remove(ctx, &pbkeys.Name{*name}) + _, err := c.RemoveName(ctx, &pbkeys.Name{*name}) if err != nil { output.Fatalf("failed to remove key: %v", err) } diff --git a/config/config.go b/config/config.go index 5a812bce625ecac9bfd8c3e3ce17d5b481984ca7..24896f06d7fc50cefa1b6c228d6b87a9023c4a03 100644 --- a/config/config.go +++ b/config/config.go @@ -55,7 +55,18 @@ func (conf *BurrowConfig) Kernel(ctx context.Context) (*core.Kernel, error) { if err != nil { return nil, fmt.Errorf("could not generate logger from logging config: %v", err) } - keyClient := keys.NewKeyClient(conf.Keys.URL, logger) + var keyClient keys.KeyClient + var keyStore *keys.KeyStore + if conf.Keys.RemoteAddress != "" { + keyClient, err = keys.NewRemoteKeyClient(conf.Keys.RemoteAddress, logger) + if err != nil { + return nil, err + } + } else { + *keyStore = keys.NewKeyStore(conf.Keys.KeysDirectory) + keyClient = keys.NewLocalKeyClient(*keyStore, logger) + } + val, err := keys.Addressable(keyClient, *conf.ValidatorAddress) if err != nil { return nil, fmt.Errorf("could not get validator addressable from keys client: %v", err) @@ -71,7 +82,7 @@ func (conf *BurrowConfig) Kernel(ctx context.Context) (*core.Kernel, error) { } return core.NewKernel(ctx, keyClient, privValidator, conf.GenesisDoc, conf.Tendermint.TendermintConfig(), conf.RPC, conf.Keys, - exeOptions, logger) + keyStore, exeOptions, logger) } func (conf *BurrowConfig) JSONString() string { diff --git a/core/integration/test_wrapper.go b/core/integration/test_wrapper.go index 7c2ab3f6782269300d32d218b3b5c624bcc10b82..8a0e5a46d47526e632c5903518cab7349b1fc75f 100644 --- a/core/integration/test_wrapper.go +++ b/core/integration/test_wrapper.go @@ -82,7 +82,7 @@ func TestWrapper(privateAccounts []acm.PrivateAccount, genesisDoc *genesis.Genes privValidator := validator.NewPrivValidatorMemory(validatorAccount, validatorAccount) keyClient := mock.NewKeyClient(privateAccounts...) kernel, err := core.NewKernel(context.Background(), keyClient, privValidator, genesisDoc, tmConf, rpc.DefaultRPCConfig(), keys.DefaultKeysConfig(), - nil, logger) + nil, nil, logger) if err != nil { panic(err) } diff --git a/core/kernel.go b/core/kernel.go index 598505abe0df6df976884b1c3adeb00e6a554e05..437c43fcb9f24a07307ac7f186fa1271d6188912 100644 --- a/core/kernel.go +++ b/core/kernel.go @@ -34,6 +34,7 @@ import ( "github.com/hyperledger/burrow/execution" "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/keys" + "github.com/hyperledger/burrow/keys/pbkeys" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/process" @@ -68,7 +69,7 @@ type Kernel struct { func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_types.PrivValidator, genesisDoc *genesis.GenesisDoc, tmConf *tm_config.Config, rpcConfig *rpc.RPCConfig, keyConfig *keys.KeysConfig, - exeOptions []execution.ExecutionOption, logger *logging.Logger) (*Kernel, error) { + keyStore *keys.KeyStore, exeOptions []execution.ExecutionOption, logger *logging.Logger) (*Kernel, error) { logger = logger.WithScope("NewKernel()").With(structure.TimeKey, kitlog.DefaultTimestampUTC) tmLogger := logger.With(structure.CallerKey, kitlog.Caller(LoggingCallerDepth+1)) @@ -211,14 +212,25 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t } grpcServer := grpc.NewServer() - err = keys.StartGRPCServer(grpcServer, keyConfig) - if err != nil { - return nil, err + var ks keys.KeyStore + if keyStore != nil { + ks = *keyStore + } + + if keyConfig.GRPCServiceEnabled { + if keyStore == nil { + ks = keys.NewKeyStore(keyConfig.KeysDirectory) + } + pbkeys.RegisterKeysServer(grpcServer, &ks) } go grpcServer.Serve(listen) - return process.FromListeners(listen), nil + return process.ShutdownFunc(func(ctx context.Context) error { + grpcServer.Stop() + // listener is closed for us + return nil + }), nil }, }, } diff --git a/core/kernel_test.go b/core/kernel_test.go index 480578bce3fd9b509357688395a5c3b1d743f100..e02ef7cd60463e64b0590a102be606cd7693c0e3 100644 --- a/core/kernel_test.go +++ b/core/kernel_test.go @@ -13,7 +13,6 @@ import ( "github.com/hyperledger/burrow/consensus/tendermint/validator" "github.com/hyperledger/burrow/genesis" "github.com/hyperledger/burrow/keys" - "github.com/hyperledger/burrow/keys/mock" "github.com/hyperledger/burrow/logging" "github.com/hyperledger/burrow/rpc" "github.com/stretchr/testify/assert" @@ -66,8 +65,10 @@ func bootWaitBlocksShutdown(privValidator tm_types.PrivValidator, genesisDoc *ge tmConf *tm_config.Config, logger *logging.Logger, blockChecker func(block *tm_types.EventDataNewBlock) (cont bool)) error { - kern, err := NewKernel(context.Background(), mock.NewKeyClient(), privValidator, genesisDoc, tmConf, - rpc.DefaultRPCConfig(), keys.DefaultKeysConfig(), nil, logger) + keyStore := keys.NewKeyStore(keys.DefaultKeysDir) + keyClient := keys.NewLocalKeyClient(keyStore, logging.NewNoopLogger()) + kern, err := NewKernel(context.Background(), keyClient, privValidator, genesisDoc, tmConf, + rpc.DefaultRPCConfig(), keys.DefaultKeysConfig(), &keyStore, nil, logger) if err != nil { return err } diff --git a/crypto/crypto.go b/crypto/crypto.go index b3ebf03e29606c8355917ef7bde020589cd3017b..400345fce3a4abae70942dd40a8cf76501ca3e19 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -4,16 +4,15 @@ import ( "bytes" crand "crypto/rand" "crypto/sha256" - "encoding/hex" "encoding/json" "fmt" "io" - "golang.org/x/crypto/ripemd160" - "github.com/btcsuite/btcd/btcec" tm_crypto "github.com/tendermint/go-crypto" + "github.com/tmthrgd/go-hex" "golang.org/x/crypto/ed25519" + "golang.org/x/crypto/ripemd160" ) type CurveType int8 @@ -46,6 +45,17 @@ func CurveTypeFromString(s string) (CurveType, error) { } } +func (p PublicKey) AddressHashType() string { + switch p.CurveType { + case CurveTypeEd25519: + return "go-crypto-0.5.0" + case CurveTypeSecp256k1: + return "btc" + default: + return "" + } +} + type ErrInvalidCurve string func (err ErrInvalidCurve) Error() string { @@ -79,7 +89,7 @@ type PublicKeyJSON struct { func (p PublicKey) MarshalJSON() ([]byte, error) { jStruct := PublicKeyJSON{ Type: p.CurveType.String(), - Data: fmt.Sprintf("%X", p.PublicKey), + Data: hex.EncodeUpperToString(p.PublicKey), } txt, err := json.Marshal(jStruct) return txt, err @@ -167,7 +177,7 @@ func (p PublicKey) RawBytes() []byte { } func (p PublicKey) String() string { - return fmt.Sprintf("%X", p.PublicKey[:]) + return hex.EncodeUpperToString(p.PublicKey) } // Signable is an interface for all signable things. diff --git a/deployment/config.go b/deployment/config.go index 8f1047b638d8465ae527fc887368add3842e61bd..b5ead42643ef360ee97f81b0b55f3c7b7ec96756 100644 --- a/deployment/config.go +++ b/deployment/config.go @@ -8,13 +8,13 @@ import ( "text/template" "github.com/hyperledger/burrow/config" - "github.com/hyperledger/burrow/keys/mock" + "github.com/hyperledger/burrow/keys" "github.com/pkg/errors" "github.com/tmthrgd/go-hex" ) type Package struct { - Keys []*mock.Key + Keys []*keys.Key BurrowConfig *config.BurrowConfig } diff --git a/deployment/config_test.go b/deployment/config_test.go deleted file mode 100644 index 0020ce7dddcde55fe90d56e6d732da16bb76043f..0000000000000000000000000000000000000000 --- a/deployment/config_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package deployment - -import ( - "encoding/json" - "fmt" - "testing" - - "github.com/hyperledger/burrow/crypto" - "github.com/hyperledger/burrow/keys/mock" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestMockKeyClient_DumpKeys(t *testing.T) { - keyClient := mock.NewKeyClient() - _, err := keyClient.Generate("foo", crypto.CurveTypeEd25519) - require.NoError(t, err) - _, err = keyClient.Generate("foobar", crypto.CurveTypeEd25519) - require.NoError(t, err) - pkg := Package{Keys: keyClient.Keys()} - dump, err := pkg.Dump(DefaultDumpKeysFormat) - require.NoError(t, err) - - // Check JSON equal - var keys struct{ Keys []*mock.Key } - err = json.Unmarshal([]byte(dump), &keys) - require.NoError(t, err) - bs, err := json.MarshalIndent(keys, "", " ") - require.NoError(t, err) - assert.Equal(t, string(bs), dump) -} - -func TestMockKeyClient_DumpKeysKubernetes(t *testing.T) { - keyClient := mock.NewKeyClient() - _, err := keyClient.Generate("foo", crypto.CurveTypeEd25519) - require.NoError(t, err) - _, err = keyClient.Generate("foobar", crypto.CurveTypeEd25519) - require.NoError(t, err) - pkg := Package{Keys: keyClient.Keys()} - dump, err := pkg.Dump(KubernetesKeyDumpFormat) - require.NoError(t, err) - fmt.Println(dump) -} - -func TestMockKeyClient_DumpKeysHelm(t *testing.T) { - keyClient := mock.NewKeyClient() - _, err := keyClient.Generate("foo", crypto.CurveTypeEd25519) - require.NoError(t, err) - _, err = keyClient.Generate("foobar", crypto.CurveTypeEd25519) - require.NoError(t, err) - pkg := Package{Keys: keyClient.Keys()} - dump, err := pkg.Dump(HelmDumpKeysFormat) - require.NoError(t, err) - fmt.Println(dump) -} diff --git a/keys/common/paths.go b/keys/common/paths.go index 76d443a2fa9f12489bc1d5a50ed350a12950870b..075800636f3034306f135db7fff728811bace0c5 100644 --- a/keys/common/paths.go +++ b/keys/common/paths.go @@ -6,16 +6,6 @@ import ( "runtime" ) -var ( - // Convenience directories. - MonaxRoot = ResolveMonaxRoot() - MonaxContainerRoot = "/home/monax/.monax" - - // Major directories. - KeysPath = filepath.Join(MonaxRoot, "keys") - ScratchPath = filepath.Join(MonaxRoot, "scratch") -) - func HomeDir() string { if runtime.GOOS == "windows" { drive := os.Getenv("HOMEDRIVE") diff --git a/keys/config.go b/keys/config.go index 082911ec27de07b8ed13d433890ad5d0ac7a4efa..d50d61338f9934dbb9301c36ee6878142e1ac81c 100644 --- a/keys/config.go +++ b/keys/config.go @@ -1,14 +1,16 @@ package keys type KeysConfig struct { - ServerEnabled bool - URL string + GRPCServiceEnabled bool + RemoteAddress string + KeysDirectory string } func DefaultKeysConfig() *KeysConfig { return &KeysConfig{ // Default Monax keys port - ServerEnabled: true, - URL: "", + GRPCServiceEnabled: true, + RemoteAddress: "", + KeysDirectory: DefaultKeysDir, } } diff --git a/keys/core.go b/keys/core.go index 8fb37c7ef7cbe69bfaec60a467de2b0aaa7a9d14..8642a820b331dc99c5ea8c43f30d99210886d433 100644 --- a/keys/core.go +++ b/keys/core.go @@ -1,7 +1,6 @@ package keys import ( - "encoding/hex" "fmt" "io/ioutil" "os" @@ -9,27 +8,16 @@ import ( "path/filepath" "strings" - "github.com/hyperledger/burrow/keys/common" - tmint_crypto "github.com/hyperledger/burrow/crypto/helpers" wire "github.com/tendermint/go-wire" ) -var ( - DefaultKeyType = "ed25519" - DefaultDir = common.KeysPath +const ( + DefaultHost = "localhost" + DefaultPort = "10997" DefaultHashType = "sha256" - - DefaultHost = "localhost" - DefaultPort = "10997" - TestPort = "7674" - TestAddr = DefaultHost + ":" + TestPort - - KeysDir string = ".monax-keys" - KeyHost string - KeyPort string - - GlobalKeystore KeyStore + DefaultKeysDir = ".keys" + TestPort = "7674" ) func returnDataDir(dir string) (string, error) { @@ -52,12 +40,8 @@ func returnNamesDir(dir string) (string, error) { //----- -func newKeyStore() (KeyStore, error) { - dir, err := returnDataDir(KeysDir) - if err != nil { - return nil, err - } - return NewKeyStoreFile(dir), nil +func NewKeyStore(dir string) KeyStore { + return KeyStore{keysDirPath: dir} } //---------------------------------------------------------------- @@ -72,7 +56,7 @@ func writeKey(keyDir string, addr, keyJson []byte) ([]byte, error) { return addr, nil } -func coreExport(passphrase, addr string) ([]byte, error) { +func coreExport(key *Key) ([]byte, error) { type privValidator struct { Address []byte `json:"address"` PubKey []interface{} `json:"pub_key"` @@ -82,19 +66,8 @@ func coreExport(passphrase, addr string) ([]byte, error) { LastStep int `json:"last_step"` } - addrB, err := hex.DecodeString(addr) - if err != nil { - return nil, fmt.Errorf("addr is invalid hex: %s", err.Error()) - } - key, err := GlobalKeystore.GetKey(passphrase, addrB) - if err != nil { - return nil, err - } - pub := key.Pubkey() - if err != nil { - return nil, err - } + var pubKeyWithType []interface{} var pubKey tmint_crypto.PubKeyEd25519 copy(pubKey[:], pub) @@ -108,7 +81,7 @@ func coreExport(passphrase, addr string) ([]byte, error) { privKeyWithType = append(privKeyWithType, privKey) privVal := &privValidator{ - Address: addrB, + Address: key.Address[:], PubKey: pubKeyWithType, PrivKey: privKeyWithType, } @@ -119,23 +92,23 @@ func coreExport(passphrase, addr string) ([]byte, error) { //---------------------------------------------------------------- // manage names for keys -func coreNameAdd(name, addr string) error { - namesDir, err := returnNamesDir(KeysDir) +func coreNameAdd(keysDir, name, addr string) error { + namesDir, err := returnNamesDir(keysDir) if err != nil { return err } - keysDir, err := returnDataDir(KeysDir) + dataDir, err := returnDataDir(keysDir) if err != nil { return err } - if _, err := os.Stat(path.Join(keysDir, addr)); err != nil { + if _, err := os.Stat(path.Join(dataDir, addr+".json")); err != nil { return fmt.Errorf("Unknown key %s", addr) } return ioutil.WriteFile(path.Join(namesDir, name), []byte(addr), 0600) } -func coreNameList() (map[string]string, error) { - dir, err := returnNamesDir(KeysDir) +func coreNameList(keysDir string) (map[string]string, error) { + dir, err := returnNamesDir(keysDir) if err != nil { return nil, err } @@ -154,8 +127,8 @@ func coreNameList() (map[string]string, error) { return names, nil } -func coreAddrList() (map[int]string, error) { - dir, err := returnDataDir(KeysDir) +func coreAddrList(keysDir string) (map[int]string, error) { + dir, err := returnDataDir(keysDir) if err != nil { return nil, err } @@ -170,16 +143,16 @@ func coreAddrList() (map[int]string, error) { return addrs, nil } -func coreNameRm(name string) error { - dir, err := returnNamesDir(KeysDir) +func coreNameRm(keysDir string, name string) error { + dir, err := returnNamesDir(keysDir) if err != nil { return err } return os.Remove(path.Join(dir, name)) } -func coreNameGet(name string) (string, error) { - dir, err := returnNamesDir(KeysDir) +func coreNameGet(keysDir, name string) (string, error) { + dir, err := returnNamesDir(keysDir) if err != nil { return "", err } @@ -201,7 +174,7 @@ func checkMakeDataDir(dir string) error { } // return addr from name or addr -func getNameAddr(name, addr string) (string, error) { +func getNameAddr(keysDir, name, addr string) (string, error) { if name == "" && addr == "" { return "", fmt.Errorf("at least one of name or addr must be provided") } @@ -209,7 +182,7 @@ func getNameAddr(name, addr string) (string, error) { // name takes precedent if both are given var err error if name != "" { - addr, err = coreNameGet(name) + addr, err = coreNameGet(keysDir, name) if err != nil { return "", err } diff --git a/keys/key_client.go b/keys/key_client.go index 6e669ec2d56a269d6398861334941f47a0dd6552..49983e41c987427e403b747b41a96cbe5234cb11 100644 --- a/keys/key_client.go +++ b/keys/key_client.go @@ -27,8 +27,8 @@ import ( ) type KeyClient interface { - // Sign returns the signature bytes for given hash signed with the key associated with signAddress - Sign(signAddress crypto.Address, hash []byte) (signature crypto.Signature, err error) + // Sign returns the signature bytes for given message signed with the key associated with signAddress + Sign(signAddress crypto.Address, message []byte) (signature crypto.Signature, err error) // PublicKey returns the public key associated with a given address PublicKey(address crypto.Address) (publicKey crypto.PublicKey, err error) @@ -44,6 +44,7 @@ var _ KeyClient = (*localKeyClient)(nil) var _ KeyClient = (*remoteKeyClient)(nil) type localKeyClient struct { + ks KeyStore logger *logging.Logger } @@ -53,8 +54,8 @@ type remoteKeyClient struct { logger *logging.Logger } -func (l localKeyClient) Sign(signAddress crypto.Address, hash []byte) (signature crypto.Signature, err error) { - resp, err := GlobalKeyServer.Sign(nil, &pbkeys.SignRequest{Address: signAddress.String(), Hash: hash}) +func (l localKeyClient) Sign(signAddress crypto.Address, message []byte) (signature crypto.Signature, err error) { + resp, err := l.ks.Sign(nil, &pbkeys.SignRequest{Address: signAddress.String(), Message: message}) if err != nil { return crypto.Signature{}, err } @@ -66,7 +67,7 @@ func (l localKeyClient) Sign(signAddress crypto.Address, hash []byte) (signature } func (l localKeyClient) PublicKey(address crypto.Address) (publicKey crypto.PublicKey, err error) { - resp, err := GlobalKeyServer.PublicKey(nil, &pbkeys.PubRequest{Address: address.String()}) + resp, err := l.ks.PublicKey(nil, &pbkeys.PubRequest{Address: address.String()}) if err != nil { return crypto.PublicKey{}, err } @@ -79,7 +80,7 @@ func (l localKeyClient) PublicKey(address crypto.Address) (publicKey crypto.Publ // Generate requests that a key be generate within the keys instance and returns the address func (l localKeyClient) Generate(keyName string, curveType crypto.CurveType) (keyAddress crypto.Address, err error) { - resp, err := GlobalKeyServer.GenerateKey(nil, &pbkeys.GenRequest{Keyname: keyName, Curvetype: curveType.String()}) + resp, err := l.ks.GenerateKey(nil, &pbkeys.GenRequest{Keyname: keyName, Curvetype: curveType.String()}) if err != nil { return crypto.Address{}, err } @@ -94,7 +95,7 @@ func (l localKeyClient) HealthCheck() error { func (l remoteKeyClient) Sign(signAddress crypto.Address, message []byte) (signature crypto.Signature, err error) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() - req := pbkeys.SignRequest{Address: signAddress.String(), Hash: message} + req := pbkeys.SignRequest{Address: signAddress.String(), Message: message} l.logger.TraceMsg("Sending Sign request to remote key server: ", fmt.Sprintf("%v", req)) resp, err := l.kc.Sign(ctx, &req) if err != nil { @@ -152,32 +153,22 @@ func (l remoteKeyClient) HealthCheck() error { // keyClient.New returns a new monax-keys client for provided rpc location // Monax-keys connects over http request-responses -func NewKeyClient(rpcAddress string, logger *logging.Logger) KeyClient { - logger = logger.WithScope("NewKeyClient") - var client KeyClient - if rpcAddress != "" { - var opts []grpc.DialOption - opts = append(opts, grpc.WithInsecure()) - conn, err := grpc.Dial(rpcAddress, opts...) - if err != nil { - // FIXME: we should return error, or handle this when the - // key client is used for the first time - panic("Failed to connect to grpc server") - } - kc := pbkeys.NewKeysClient(conn) - - client = remoteKeyClient{kc: kc, rpcAddress: rpcAddress, logger: logger} - } else { - ks, err := newKeyStore() - if err != nil { - panic("Failed to start keys store") - } - - GlobalKeystore = ks - - client = localKeyClient{logger: logger} +func NewRemoteKeyClient(rpcAddress string, logger *logging.Logger) (KeyClient, error) { + logger = logger.WithScope("RemoteKeyClient") + var opts []grpc.DialOption + opts = append(opts, grpc.WithInsecure()) + conn, err := grpc.Dial(rpcAddress, opts...) + if err != nil { + return nil, err } - return client + kc := pbkeys.NewKeysClient(conn) + + return remoteKeyClient{kc: kc, rpcAddress: rpcAddress, logger: logger}, nil +} + +func NewLocalKeyClient(ks KeyStore, logger *logging.Logger) KeyClient { + logger = logger.WithScope("LocalKeyClient") + return localKeyClient{ks: ks, logger: logger} } type signer struct { diff --git a/keys/key_store.go b/keys/key_store.go index 0dd857dae65628b3926ae0b0dff17d0b43d6d357..fe6c3d54ba306ea46a3dc17ebe1141216be17df3 100644 --- a/keys/key_store.go +++ b/keys/key_store.go @@ -59,14 +59,6 @@ func NewKeyFromPriv(curveType crypto.CurveType, PrivKeyBytes []byte) (*Key, erro }, nil } -type KeyStore interface { - GenerateKey(passphrase string, curveType crypto.CurveType) (*Key, error) - GetKey(passphrase string, addr []byte) (*Key, error) - GetAllAddresses() ([][]byte, error) - StoreKey(passphrase string, key *Key) error - DeleteKey(passphrase string, addr []byte) error -} - func (k *Key) Sign(hash []byte) ([]byte, error) { signature, err := k.PrivateKey.Sign(hash) if err != nil { diff --git a/keys/key_store_file.go b/keys/key_store_file.go index fc61ec69b6d27e36390dbd1846d7a371b827c72d..25c2f56728c7c436250bda1837c5b90c81874180 100644 --- a/keys/key_store_file.go +++ b/keys/key_store_file.go @@ -4,7 +4,6 @@ import ( "crypto/aes" "crypto/cipher" "crypto/rand" - "encoding/hex" "encoding/json" "fmt" "io/ioutil" @@ -14,15 +13,20 @@ import ( "sync" "github.com/hyperledger/burrow/crypto" + "github.com/tmthrgd/go-hex" "golang.org/x/crypto/scrypt" ) const ( - scryptN = 1 << 18 - scryptr = 8 - scryptp = 1 - scryptdkLen = 32 + scryptN = 1 << 18 + scryptr = 8 + scryptp = 1 + scryptdkLen = 32 + CryptoNone = "none" + CryptoAESGCM = "scrypt-aes-gcm" + HashEd25519 = "go-crypto-0.5.0" + HashSecp256k1 = "btc" ) //----------------------------------------------------------------------------- @@ -48,11 +52,11 @@ type privateKeyJSON struct { func (k *Key) MarshalJSON() (j []byte, err error) { jStruct := keyJSON{ - k.CurveType.String(), - fmt.Sprintf("%X", k.Address), - k.Pubkey(), - "go-crypto-0.5.0", - privateKeyJSON{Crypto: "none", Plain: k.PrivateKey.RawBytes()}, + CurveType: k.CurveType.String(), + Address: hex.EncodeToString(k.Address[:]), + PublicKey: k.Pubkey(), + AddressHash: k.PublicKey.AddressHashType(), + PrivateKey: privateKeyJSON{Crypto: CryptoNone, Plain: k.PrivateKey.RawBytes()}, } j, err = json.Marshal(jStruct) return j, err @@ -64,7 +68,6 @@ func (k *Key) UnmarshalJSON(j []byte) (err error) { if err != nil { return err } - // TODO: remove this if len(keyJ.PrivateKey.Plain) == 0 { return fmt.Errorf("no private key") } @@ -96,16 +99,12 @@ func IsValidKeyJson(j []byte) []byte { return nil } -type keyStoreFile struct { +type KeyStore struct { sync.Mutex keysDirPath string } -func NewKeyStoreFile(path string) KeyStore { - return &keyStoreFile{keysDirPath: path} -} - -func (ks keyStoreFile) GenerateKey(passphrase string, curveType crypto.CurveType) (key *Key, err error) { +func (ks KeyStore) Gen(passphrase string, curveType crypto.CurveType) (key *Key, err error) { defer func() { if r := recover(); r != nil { err = fmt.Errorf("GenerateNewKey error: %v", r) @@ -119,10 +118,14 @@ func (ks keyStoreFile) GenerateKey(passphrase string, curveType crypto.CurveType return key, err } -func (ks keyStoreFile) GetKey(passphrase string, keyAddr []byte) (*Key, error) { +func (ks KeyStore) GetKey(passphrase string, keyAddr []byte) (*Key, error) { ks.Lock() defer ks.Unlock() - fileContent, err := GetKeyFile(ks.keysDirPath, keyAddr) + dataDirPath, err := returnDataDir(ks.keysDirPath) + if err != nil { + return nil, err + } + fileContent, err := GetKeyFile(dataDirPath, keyAddr) if err != nil { return nil, err } @@ -140,6 +143,30 @@ func (ks keyStoreFile) GetKey(passphrase string, keyAddr []byte) (*Key, error) { } } +func (ks KeyStore) AllKeys() ([]*Key, error) { + + dataDirPath, err := returnDataDir(ks.keysDirPath) + if err != nil { + return nil, err + } + addrs, err := GetAllAddresses(dataDirPath) + if err != nil { + return nil, err + } + + var list []*Key + + for _, addr := range addrs { + k, err := ks.GetKey("", addr) + if err != nil { + return nil, err + } + list = append(list, k) + } + + return list, nil +} + func DecryptKey(passphrase string, keyProtected *keyJSON) (*Key, error) { salt := keyProtected.PrivateKey.Salt nonce := keyProtected.PrivateKey.Nonce @@ -181,13 +208,13 @@ func DecryptKey(passphrase string, keyProtected *keyJSON) (*Key, error) { return k, nil } -func (ks keyStoreFile) GetAllAddresses() (addresses [][]byte, err error) { +func (ks KeyStore) GetAllAddresses() (addresses [][]byte, err error) { ks.Lock() defer ks.Unlock() return GetAllAddresses(ks.keysDirPath) } -func (ks keyStoreFile) StoreKey(passphrase string, key *Key) error { +func (ks KeyStore) StoreKey(passphrase string, key *Key) error { ks.Lock() defer ks.Unlock() if passphrase != "" { @@ -197,16 +224,20 @@ func (ks keyStoreFile) StoreKey(passphrase string, key *Key) error { } } -func (ks keyStoreFile) StoreKeyPlain(key *Key) (err error) { +func (ks KeyStore) StoreKeyPlain(key *Key) (err error) { keyJSON, err := json.Marshal(key) if err != nil { return err } - err = WriteKeyFile(key.Address[:], ks.keysDirPath, keyJSON) + dataDirPath, err := returnDataDir(ks.keysDirPath) + if err != nil { + return err + } + err = WriteKeyFile(key.Address[:], dataDirPath, keyJSON) return err } -func (ks keyStoreFile) StoreKeyEncrypted(passphrase string, key *Key) error { +func (ks KeyStore) StoreKeyEncrypted(passphrase string, key *Key) error { authArray := []byte(passphrase) salt := make([]byte, 32) _, err := rand.Read(salt) @@ -242,53 +273,60 @@ func (ks keyStoreFile) StoreKeyEncrypted(passphrase string, key *Key) error { cipherText := gcm.Seal(nil, nonce, toEncrypt, nil) cipherStruct := privateKeyJSON{ - Crypto: "scrypt-aes-gcm", Salt: salt, Nonce: nonce, CipherText: cipherText, + Crypto: CryptoAESGCM, Salt: salt, Nonce: nonce, CipherText: cipherText, } keyStruct := keyJSON{ - key.CurveType.String(), - strings.ToUpper(hex.EncodeToString(key.Address[:])), - key.Pubkey(), - "go-crypto-0.5.0", - cipherStruct, + CurveType: key.CurveType.String(), + Address: strings.ToUpper(hex.EncodeToString(key.Address[:])), + PublicKey: key.Pubkey(), + AddressHash: key.PublicKey.AddressHashType(), + PrivateKey: cipherStruct, } keyJSON, err := json.Marshal(keyStruct) if err != nil { return err } + dataDirPath, err := returnDataDir(ks.keysDirPath) + if err != nil { + return err + } - return WriteKeyFile(key.Address[:], ks.keysDirPath, keyJSON) + return WriteKeyFile(key.Address[:], dataDirPath, keyJSON) } -func (ks keyStoreFile) DeleteKey(passphrase string, keyAddr []byte) (err error) { - keyDirPath := path.Join(ks.keysDirPath, strings.ToUpper(hex.EncodeToString(keyAddr))) - err = os.RemoveAll(keyDirPath) - return err +func (ks KeyStore) DeleteKey(passphrase string, keyAddr []byte) (err error) { + dataDirPath, err := returnDataDir(ks.keysDirPath) + if err != nil { + return err + } + keyDirPath := path.Join(dataDirPath, strings.ToUpper(hex.EncodeToString(keyAddr))+".json") + return os.Remove(keyDirPath) } -func GetKeyFile(keysDirPath string, keyAddr []byte) (fileContent []byte, err error) { +func GetKeyFile(dataDirPath string, keyAddr []byte) (fileContent []byte, err error) { fileName := strings.ToUpper(hex.EncodeToString(keyAddr)) - return ioutil.ReadFile(path.Join(keysDirPath, fileName, fileName)) + return ioutil.ReadFile(path.Join(dataDirPath, fileName+".json")) } -func WriteKeyFile(addr []byte, keysDirPath string, content []byte) (err error) { +func WriteKeyFile(addr []byte, dataDirPath string, content []byte) (err error) { addrHex := strings.ToUpper(hex.EncodeToString(addr)) - keyDirPath := path.Join(keysDirPath, addrHex) - keyFilePath := path.Join(keyDirPath, addrHex) - err = os.MkdirAll(keyDirPath, 0700) // read, write and dir search for user + keyFilePath := path.Join(dataDirPath, addrHex+".json") + err = os.MkdirAll(dataDirPath, 0700) // read, write and dir search for user if err != nil { return err } return ioutil.WriteFile(keyFilePath, content, 0600) // read, write for user } -func GetAllAddresses(keysDirPath string) (addresses [][]byte, err error) { - fileInfos, err := ioutil.ReadDir(keysDirPath) +func GetAllAddresses(dataDirPath string) (addresses [][]byte, err error) { + fileInfos, err := ioutil.ReadDir(dataDirPath) if err != nil { return nil, err } addresses = make([][]byte, len(fileInfos)) for i, fileInfo := range fileInfos { - address, err := hex.DecodeString(fileInfo.Name()) + addr := strings.TrimSuffix(fileInfo.Name(), "json") + address, err := hex.DecodeString(addr) if err != nil { continue } diff --git a/keys/pbkeys/keys.pb.go b/keys/pbkeys/keys.pb.go index 4038f4fdfc5fa0600c5ec5956d62937d4530fb2d..a099818d370ebfe3db85f66d429ccafa7ed8a008 100644 --- a/keys/pbkeys/keys.pb.go +++ b/keys/pbkeys/keys.pb.go @@ -26,7 +26,7 @@ It has these top-level messages: HashResponse Key ListResponse - AddRequest + AddNameRequest */ package pbkeys @@ -301,7 +301,8 @@ func (m *ExportResponse) GetExport() string { type SignRequest struct { Passphrase string `protobuf:"bytes,1,opt,name=passphrase" json:"passphrase,omitempty"` Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` - Hash []byte `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty"` + Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` + Message []byte `protobuf:"bytes,4,opt,name=message,proto3" json:"message,omitempty"` } func (m *SignRequest) Reset() { *m = SignRequest{} } @@ -323,9 +324,16 @@ func (m *SignRequest) GetAddress() string { return "" } -func (m *SignRequest) GetHash() []byte { +func (m *SignRequest) GetName() string { if m != nil { - return m.Hash + return m.Name + } + return "" +} + +func (m *SignRequest) GetMessage() []byte { + if m != nil { + return m.Message } return nil } @@ -357,7 +365,7 @@ func (m *SignResponse) GetCurvetype() string { type VerifyRequest struct { Curvetype string `protobuf:"bytes,1,opt,name=curvetype" json:"curvetype,omitempty"` Pub []byte `protobuf:"bytes,2,opt,name=pub,proto3" json:"pub,omitempty"` - Hash []byte `protobuf:"bytes,3,opt,name=hash,proto3" json:"hash,omitempty"` + Message []byte `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` Signature []byte `protobuf:"bytes,4,opt,name=signature,proto3" json:"signature,omitempty"` } @@ -380,9 +388,9 @@ func (m *VerifyRequest) GetPub() []byte { return nil } -func (m *VerifyRequest) GetHash() []byte { +func (m *VerifyRequest) GetMessage() []byte { if m != nil { - return m.Hash + return m.Message } return nil } @@ -474,24 +482,24 @@ func (m *ListResponse) GetKey() []*Key { return nil } -type AddRequest struct { +type AddNameRequest struct { Keyname string `protobuf:"bytes,1,opt,name=keyname" json:"keyname,omitempty"` Address string `protobuf:"bytes,2,opt,name=address" json:"address,omitempty"` } -func (m *AddRequest) Reset() { *m = AddRequest{} } -func (m *AddRequest) String() string { return proto.CompactTextString(m) } -func (*AddRequest) ProtoMessage() {} -func (*AddRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } +func (m *AddNameRequest) Reset() { *m = AddNameRequest{} } +func (m *AddNameRequest) String() string { return proto.CompactTextString(m) } +func (*AddNameRequest) ProtoMessage() {} +func (*AddNameRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } -func (m *AddRequest) GetKeyname() string { +func (m *AddNameRequest) GetKeyname() string { if m != nil { return m.Keyname } return "" } -func (m *AddRequest) GetAddress() string { +func (m *AddNameRequest) GetAddress() string { if m != nil { return m.Address } @@ -517,7 +525,7 @@ func init() { proto.RegisterType((*HashResponse)(nil), "pbkeys.HashResponse") proto.RegisterType((*Key)(nil), "pbkeys.Key") proto.RegisterType((*ListResponse)(nil), "pbkeys.ListResponse") - proto.RegisterType((*AddRequest)(nil), "pbkeys.AddRequest") + proto.RegisterType((*AddNameRequest)(nil), "pbkeys.AddNameRequest") } // Reference imports to suppress errors if they are not otherwise used. @@ -539,9 +547,9 @@ type KeysClient interface { ImportJSON(ctx context.Context, in *ImportJSONRequest, opts ...grpc.CallOption) (*ImportResponse, error) Export(ctx context.Context, in *ExportRequest, opts ...grpc.CallOption) (*ExportResponse, error) Hash(ctx context.Context, in *HashRequest, opts ...grpc.CallOption) (*HashResponse, error) - Remove(ctx context.Context, in *Name, opts ...grpc.CallOption) (*Empty, error) + RemoveName(ctx context.Context, in *Name, opts ...grpc.CallOption) (*Empty, error) List(ctx context.Context, in *Name, opts ...grpc.CallOption) (*ListResponse, error) - Add(ctx context.Context, in *AddRequest, opts ...grpc.CallOption) (*Empty, error) + AddName(ctx context.Context, in *AddNameRequest, opts ...grpc.CallOption) (*Empty, error) } type keysClient struct { @@ -624,9 +632,9 @@ func (c *keysClient) Hash(ctx context.Context, in *HashRequest, opts ...grpc.Cal return out, nil } -func (c *keysClient) Remove(ctx context.Context, in *Name, opts ...grpc.CallOption) (*Empty, error) { +func (c *keysClient) RemoveName(ctx context.Context, in *Name, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) - err := grpc.Invoke(ctx, "/pbkeys.Keys/Remove", in, out, c.cc, opts...) + err := grpc.Invoke(ctx, "/pbkeys.Keys/RemoveName", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -642,9 +650,9 @@ func (c *keysClient) List(ctx context.Context, in *Name, opts ...grpc.CallOption return out, nil } -func (c *keysClient) Add(ctx context.Context, in *AddRequest, opts ...grpc.CallOption) (*Empty, error) { +func (c *keysClient) AddName(ctx context.Context, in *AddNameRequest, opts ...grpc.CallOption) (*Empty, error) { out := new(Empty) - err := grpc.Invoke(ctx, "/pbkeys.Keys/Add", in, out, c.cc, opts...) + err := grpc.Invoke(ctx, "/pbkeys.Keys/AddName", in, out, c.cc, opts...) if err != nil { return nil, err } @@ -662,9 +670,9 @@ type KeysServer interface { ImportJSON(context.Context, *ImportJSONRequest) (*ImportResponse, error) Export(context.Context, *ExportRequest) (*ExportResponse, error) Hash(context.Context, *HashRequest) (*HashResponse, error) - Remove(context.Context, *Name) (*Empty, error) + RemoveName(context.Context, *Name) (*Empty, error) List(context.Context, *Name) (*ListResponse, error) - Add(context.Context, *AddRequest) (*Empty, error) + AddName(context.Context, *AddNameRequest) (*Empty, error) } func RegisterKeysServer(s *grpc.Server, srv KeysServer) { @@ -815,20 +823,20 @@ func _Keys_Hash_Handler(srv interface{}, ctx context.Context, dec func(interface return interceptor(ctx, in, info, handler) } -func _Keys_Remove_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { +func _Keys_RemoveName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(Name) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(KeysServer).Remove(ctx, in) + return srv.(KeysServer).RemoveName(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/pbkeys.Keys/Remove", + FullMethod: "/pbkeys.Keys/RemoveName", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(KeysServer).Remove(ctx, req.(*Name)) + return srv.(KeysServer).RemoveName(ctx, req.(*Name)) } return interceptor(ctx, in, info, handler) } @@ -851,20 +859,20 @@ func _Keys_List_Handler(srv interface{}, ctx context.Context, dec func(interface return interceptor(ctx, in, info, handler) } -func _Keys_Add_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(AddRequest) +func _Keys_AddName_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AddNameRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(KeysServer).Add(ctx, in) + return srv.(KeysServer).AddName(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/pbkeys.Keys/Add", + FullMethod: "/pbkeys.Keys/AddName", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(KeysServer).Add(ctx, req.(*AddRequest)) + return srv.(KeysServer).AddName(ctx, req.(*AddNameRequest)) } return interceptor(ctx, in, info, handler) } @@ -906,16 +914,16 @@ var _Keys_serviceDesc = grpc.ServiceDesc{ Handler: _Keys_Hash_Handler, }, { - MethodName: "Remove", - Handler: _Keys_Remove_Handler, + MethodName: "RemoveName", + Handler: _Keys_RemoveName_Handler, }, { MethodName: "List", Handler: _Keys_List_Handler, }, { - MethodName: "Add", - Handler: _Keys_Add_Handler, + MethodName: "AddName", + Handler: _Keys_AddName_Handler, }, }, Streams: []grpc.StreamDesc{}, @@ -925,45 +933,45 @@ var _Keys_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("keys.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 636 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0xd1, 0x6b, 0x13, 0x4f, - 0x10, 0x26, 0xb9, 0xfb, 0x5d, 0x9b, 0x2f, 0x49, 0xf9, 0xb9, 0x6a, 0x89, 0xa1, 0x4a, 0x59, 0x10, - 0x43, 0xc1, 0x40, 0xab, 0x58, 0x14, 0x44, 0x8b, 0x94, 0x6a, 0x2b, 0xb5, 0xa4, 0xe0, 0x8b, 0xf8, - 0x70, 0xe9, 0x8d, 0x4d, 0x88, 0x49, 0xae, 0xb7, 0x77, 0xc5, 0x7b, 0xf0, 0x1f, 0xf3, 0xaf, 0x93, - 0xdd, 0xdb, 0xcd, 0xde, 0x9e, 0x4d, 0x0d, 0xf8, 0x76, 0x33, 0x3b, 0x33, 0xdf, 0xb7, 0xb3, 0xdf, - 0xcc, 0x01, 0x13, 0xca, 0x45, 0x3f, 0x4e, 0xe6, 0xe9, 0x9c, 0x05, 0xf1, 0x50, 0x5a, 0x7c, 0x1b, - 0xfe, 0x69, 0x38, 0x25, 0xd6, 0xc1, 0xda, 0x84, 0xf2, 0x59, 0x38, 0xa5, 0x4e, 0x6d, 0xbb, 0xd6, - 0x6b, 0x0c, 0x8c, 0xc9, 0xd7, 0xf0, 0xdf, 0xe1, 0x34, 0x4e, 0x73, 0x1e, 0x01, 0x47, 0x34, 0x1b, - 0xd0, 0x55, 0x46, 0x22, 0x65, 0x8f, 0x80, 0x38, 0x14, 0x22, 0x1e, 0x25, 0xa1, 0x30, 0x39, 0x25, - 0x0f, 0xdb, 0x42, 0xe3, 0x22, 0x4b, 0xae, 0x29, 0xcd, 0x63, 0xea, 0xd4, 0xd5, 0xb1, 0x75, 0x94, - 0xe1, 0x3c, 0x17, 0xee, 0x09, 0x9a, 0x0a, 0x45, 0xc4, 0xf3, 0x99, 0x50, 0x81, 0x61, 0x14, 0x25, - 0x24, 0x84, 0xe1, 0xa5, 0x4d, 0xfe, 0x0a, 0x38, 0xcb, 0x86, 0x86, 0xce, 0xd2, 0x38, 0xc6, 0xe0, - 0x2b, 0x9c, 0x82, 0x83, 0xfa, 0xe6, 0xaf, 0xd1, 0x54, 0xb9, 0x1a, 0xe4, 0x7f, 0x78, 0x71, 0x36, - 0x54, 0x89, 0xad, 0x81, 0xfc, 0xbc, 0x9d, 0x3d, 0x3f, 0xc2, 0x9d, 0x0f, 0xd3, 0x78, 0x9e, 0xa4, - 0xc7, 0xe7, 0x9f, 0x4e, 0x57, 0x6d, 0x08, 0x83, 0x2f, 0xc3, 0x0d, 0x0f, 0xf9, 0xcd, 0x77, 0xb0, - 0x51, 0x14, 0x5a, 0xe1, 0xbe, 0x3f, 0xd1, 0x36, 0xb1, 0x2b, 0x03, 0x56, 0x2f, 0xee, 0xde, 0xcb, - 0xab, 0xbe, 0x4a, 0x17, 0xeb, 0x13, 0xca, 0x87, 0x79, 0x4a, 0xa2, 0xe3, 0xab, 0x66, 0x2c, 0x6c, - 0xfe, 0x15, 0xed, 0xc3, 0x1f, 0xff, 0x0a, 0x5f, 0xba, 0x9d, 0xe7, 0xde, 0xae, 0x87, 0x0d, 0x53, - 0x5e, 0x77, 0x62, 0x13, 0x01, 0x29, 0x8f, 0xae, 0xad, 0x2d, 0xfe, 0x05, 0xcd, 0xf3, 0xf1, 0xe5, - 0xca, 0x3a, 0x2c, 0x41, 0xd6, 0xff, 0x10, 0xc6, 0x28, 0x14, 0x23, 0xc5, 0xa4, 0x35, 0x50, 0xdf, - 0xfc, 0x18, 0xad, 0xa2, 0xb8, 0x26, 0xb1, 0x85, 0x86, 0x18, 0x5f, 0xce, 0xc2, 0x34, 0x4b, 0x48, - 0xeb, 0xc3, 0x3a, 0xfe, 0xa2, 0x92, 0x2b, 0xb4, 0x3f, 0x53, 0x32, 0xfe, 0x96, 0x1b, 0xaa, 0x4e, - 0x78, 0xad, 0xda, 0x7c, 0x2d, 0xc2, 0xba, 0x15, 0xe1, 0x0d, 0x04, 0x5d, 0x42, 0x7e, 0x85, 0x10, - 0x7f, 0x87, 0xe6, 0xfb, 0x50, 0x8c, 0x0c, 0x60, 0x17, 0xeb, 0x32, 0xa9, 0x84, 0xb7, 0xb0, 0x65, - 0x5f, 0xa6, 0x24, 0x44, 0x78, 0x49, 0x1a, 0xd2, 0x98, 0x9c, 0xa3, 0x55, 0x14, 0xd1, 0x3d, 0x30, - 0x34, 0x8a, 0x0a, 0x45, 0x9f, 0x5e, 0xc2, 0x3b, 0xa1, 0xfc, 0x96, 0xa9, 0x2b, 0x0d, 0x78, 0xdd, - 0x1d, 0xf0, 0xa7, 0x68, 0x7d, 0x1c, 0x0b, 0xfb, 0xce, 0x0f, 0xe1, 0x4d, 0x28, 0xef, 0xd4, 0xb6, - 0xbd, 0x5e, 0x73, 0xaf, 0xd9, 0x2f, 0xf6, 0x52, 0xff, 0x84, 0xf2, 0x81, 0xf4, 0xf3, 0xb7, 0xc0, - 0x41, 0x14, 0x95, 0xc6, 0xfc, 0xe6, 0x35, 0xb5, 0xfc, 0x9d, 0xf7, 0x7e, 0xf9, 0xf0, 0x4f, 0x28, - 0x17, 0xec, 0x85, 0x5a, 0x2d, 0x94, 0x84, 0x29, 0x49, 0xf2, 0xcc, 0x60, 0xd9, 0xad, 0xd6, 0xbd, - 0xeb, 0xf8, 0x34, 0xc3, 0xe7, 0x68, 0x9c, 0x65, 0xc3, 0xef, 0xe3, 0x0b, 0x27, 0xcb, 0x2e, 0x1f, - 0x9b, 0x55, 0x5e, 0x2a, 0xbb, 0xf0, 0xa5, 0x94, 0xd8, 0xe2, 0xb0, 0xa4, 0xda, 0xee, 0x3d, 0xd7, - 0xa9, 0x53, 0xfa, 0x08, 0x0a, 0xc5, 0xb0, 0xfb, 0xe6, 0xdc, 0x51, 0x50, 0xb7, 0x6d, 0xdc, 0x6a, - 0x23, 0xb3, 0x7d, 0x04, 0xc5, 0x4a, 0xb0, 0xf1, 0xce, 0x8a, 0xe8, 0x6e, 0x56, 0xdd, 0x1a, 0xe8, - 0x0d, 0x60, 0x17, 0x18, 0x7b, 0xe0, 0x46, 0x95, 0x96, 0xda, 0xd2, 0x02, 0xfb, 0x08, 0x8a, 0x71, - 0xb5, 0xc8, 0xce, 0x76, 0xb0, 0x89, 0x95, 0xa9, 0xde, 0x85, 0x2f, 0xc5, 0x65, 0xbb, 0x52, 0xd2, - 0xab, 0xed, 0x8a, 0xa3, 0xbf, 0xc7, 0x08, 0x06, 0x34, 0x9d, 0x5f, 0x13, 0x6b, 0x99, 0x73, 0xf9, - 0xcb, 0xaa, 0x36, 0x63, 0x07, 0xbe, 0xd4, 0x55, 0x25, 0x68, 0x51, 0xd2, 0xd1, 0x5c, 0x0f, 0xde, - 0x41, 0x14, 0xd9, 0xb7, 0xb4, 0x0a, 0xab, 0x54, 0x1d, 0x06, 0xea, 0x77, 0xf9, 0xec, 0x77, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x93, 0xa5, 0xa8, 0x54, 0x3c, 0x07, 0x00, 0x00, + // 640 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xa4, 0x55, 0x51, 0x6f, 0xd3, 0x3c, + 0x14, 0x55, 0x9b, 0x7c, 0xdd, 0x7a, 0xda, 0x4e, 0x1f, 0x06, 0xa6, 0x52, 0x0d, 0x34, 0xf9, 0x85, + 0x31, 0x89, 0x8a, 0x0d, 0xc4, 0x04, 0x12, 0x42, 0x08, 0xa6, 0xc1, 0x86, 0xc6, 0xd4, 0x49, 0xbc, + 0xf1, 0x90, 0xae, 0x97, 0xb5, 0x2a, 0x69, 0x43, 0x9c, 0x0c, 0xf2, 0xc0, 0xdf, 0xe3, 0x77, 0x21, + 0x3b, 0x76, 0x6d, 0x47, 0xeb, 0xa8, 0xc4, 0x9b, 0xef, 0xcd, 0xbd, 0xf7, 0x1c, 0xdf, 0x9c, 0x9c, + 0x00, 0x53, 0x2a, 0x44, 0x3f, 0x49, 0xe7, 0xd9, 0x9c, 0x35, 0x92, 0xa1, 0x8c, 0xf8, 0x36, 0xc2, + 0xd3, 0x28, 0x26, 0xd6, 0xc5, 0xda, 0x94, 0x8a, 0x59, 0x14, 0x53, 0xb7, 0xb6, 0x5d, 0xdb, 0x69, + 0x0e, 0x4c, 0xc8, 0xd7, 0xf0, 0xdf, 0x61, 0x9c, 0x64, 0x05, 0x1f, 0x01, 0x47, 0x34, 0x1b, 0xd0, + 0xf7, 0x9c, 0x44, 0xc6, 0x1e, 0x00, 0x49, 0x24, 0x44, 0x32, 0x4e, 0x23, 0x61, 0x7a, 0x9c, 0x0c, + 0xdb, 0x42, 0xf3, 0x22, 0x4f, 0xaf, 0x28, 0x2b, 0x12, 0xea, 0xd6, 0xd5, 0x63, 0x9b, 0x70, 0xe1, + 0x02, 0x1f, 0xee, 0x21, 0x5a, 0x0a, 0x45, 0x24, 0xf3, 0x99, 0x50, 0x85, 0xd1, 0x68, 0x94, 0x92, + 0x10, 0x86, 0x97, 0x0e, 0xf9, 0x4b, 0xe0, 0x2c, 0x1f, 0x1a, 0x3a, 0x4b, 0xeb, 0x18, 0x43, 0xa8, + 0x70, 0x4a, 0x0e, 0xea, 0xcc, 0x5f, 0xa1, 0xa5, 0x7a, 0x35, 0xc8, 0xff, 0x08, 0x92, 0x7c, 0xa8, + 0x1a, 0xdb, 0x03, 0x79, 0xbc, 0x99, 0x3d, 0x3f, 0xc2, 0xad, 0x0f, 0x71, 0x32, 0x4f, 0xb3, 0xe3, + 0xf3, 0x4f, 0xa7, 0xab, 0x2e, 0x84, 0x21, 0x94, 0xe5, 0x86, 0x87, 0x3c, 0xf3, 0x5d, 0x6c, 0x94, + 0x83, 0x56, 0xb8, 0xef, 0x2f, 0x74, 0x4c, 0xed, 0xca, 0x80, 0xd5, 0x8b, 0xfb, 0xf7, 0x0a, 0xaa, + 0x6f, 0xa5, 0x87, 0xf5, 0x29, 0x15, 0xc3, 0x22, 0x23, 0xd1, 0x0d, 0xd5, 0x32, 0x16, 0x31, 0xff, + 0x82, 0xce, 0xe1, 0xcf, 0x7f, 0x85, 0x77, 0x6e, 0x17, 0xf8, 0xb7, 0xdb, 0xc1, 0x86, 0x19, 0xaf, + 0x37, 0xb1, 0x89, 0x06, 0xa9, 0x8c, 0x9e, 0xad, 0x23, 0x9e, 0xa3, 0x75, 0x3e, 0xb9, 0x5c, 0x59, + 0x87, 0x0e, 0x64, 0xfd, 0x7a, 0x61, 0x04, 0x3e, 0xc1, 0x98, 0x84, 0x88, 0x2e, 0x49, 0x2f, 0xc0, + 0x84, 0xfc, 0x18, 0xed, 0x12, 0x56, 0xd3, 0xdb, 0x42, 0x53, 0x4c, 0x2e, 0x67, 0x51, 0x96, 0xa7, + 0xa4, 0x95, 0x63, 0x13, 0x7f, 0xd1, 0xcf, 0x0f, 0x74, 0x3e, 0x53, 0x3a, 0xf9, 0x5a, 0x98, 0x4b, + 0x78, 0xe5, 0xb5, 0xea, 0x6b, 0xd1, 0xf2, 0xac, 0x5b, 0x79, 0x3a, 0x34, 0x03, 0x8f, 0xa6, 0x4f, + 0x2b, 0xac, 0xd0, 0xe2, 0x6f, 0xd1, 0x7a, 0x1f, 0x89, 0xb1, 0x81, 0xed, 0x61, 0x7d, 0x1c, 0x89, + 0xb1, 0x83, 0xba, 0x88, 0x5d, 0x88, 0xba, 0xbf, 0x09, 0x8e, 0x76, 0x39, 0x44, 0x6f, 0x82, 0x21, + 0x94, 0x5d, 0x7a, 0x82, 0x3a, 0xf3, 0x17, 0x08, 0x4e, 0xa8, 0xb8, 0xe1, 0xab, 0x74, 0x0c, 0xa0, + 0xee, 0x1b, 0xc0, 0x63, 0xb4, 0x3f, 0x4e, 0x84, 0xd5, 0xc1, 0x7d, 0x04, 0x53, 0x2a, 0xba, 0xb5, + 0xed, 0x60, 0xa7, 0xb5, 0xdf, 0xea, 0x97, 0xbe, 0xd5, 0x3f, 0xa1, 0x62, 0x20, 0xf3, 0xfc, 0x1d, + 0x36, 0xde, 0x8c, 0x46, 0xd2, 0xc3, 0x1c, 0x2b, 0xb8, 0xde, 0xca, 0x96, 0x6b, 0x61, 0xff, 0x77, + 0x88, 0xf0, 0x84, 0x0a, 0xc1, 0x9e, 0x2b, 0xfb, 0xa1, 0x34, 0xca, 0x48, 0x5e, 0x80, 0x19, 0x3c, + 0xeb, 0x7c, 0xbd, 0xdb, 0x5e, 0x4e, 0xb3, 0x7c, 0x86, 0xe6, 0x59, 0x3e, 0xfc, 0x36, 0xb9, 0xf0, + 0xba, 0xac, 0x41, 0xd9, 0x2e, 0xd7, 0x78, 0xf6, 0x10, 0x4a, 0x51, 0xb1, 0xc5, 0x43, 0x47, 0xd9, + 0xbd, 0x3b, 0x7e, 0x52, 0xb7, 0xf4, 0xd1, 0x28, 0xb5, 0xc3, 0xee, 0x9a, 0xe7, 0x9e, 0x96, 0x7a, + 0x1d, 0x93, 0x56, 0xae, 0xcd, 0x0e, 0xd0, 0x28, 0x6d, 0xc3, 0xd6, 0x7b, 0x36, 0xd2, 0xdb, 0xac, + 0xa6, 0x35, 0xd0, 0x6b, 0xc0, 0x9a, 0x1c, 0xbb, 0xe7, 0x57, 0x39, 0xc6, 0xb7, 0x74, 0xc0, 0x01, + 0x1a, 0xe5, 0x27, 0x6d, 0x91, 0x3d, 0x07, 0xb1, 0x8d, 0x95, 0x2f, 0x7f, 0x0f, 0xa1, 0x14, 0x98, + 0xdd, 0x8a, 0xa3, 0x59, 0xbb, 0x15, 0x4f, 0x83, 0x8f, 0x80, 0x01, 0xc5, 0xf3, 0x2b, 0x52, 0x3f, + 0xb3, 0xb6, 0xa9, 0x91, 0x51, 0x75, 0x21, 0xbb, 0x08, 0xa5, 0xbe, 0x2a, 0x45, 0x8b, 0xb1, 0x9e, + 0xf6, 0x9e, 0x60, 0x4d, 0x8b, 0x8b, 0x2d, 0xc8, 0xfa, 0x6a, 0xab, 0x4c, 0x1f, 0x36, 0xd4, 0xef, + 0xf5, 0xe9, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3b, 0xed, 0x32, 0x21, 0x6c, 0x07, 0x00, 0x00, } diff --git a/keys/pbkeys/keys.proto b/keys/pbkeys/keys.proto index c5db218480544bccac3d12254d52c9a9fe19e1e1..06ef091eee5694daa1f546e04a85badf2acb9f9e 100644 --- a/keys/pbkeys/keys.proto +++ b/keys/pbkeys/keys.proto @@ -11,9 +11,9 @@ service Keys { rpc ImportJSON(ImportJSONRequest) returns (ImportResponse); rpc Export(ExportRequest) returns (ExportResponse); rpc Hash(HashRequest) returns (HashResponse); - rpc Remove(Name) returns (Empty); + rpc RemoveName(Name) returns (Empty); rpc List(Name) returns (ListResponse); - rpc Add(AddRequest) returns (Empty); + rpc AddName(AddNameRequest) returns (Empty); } message Name { @@ -73,7 +73,8 @@ message ExportResponse { message SignRequest { string passphrase = 1; string address = 2; - bytes hash = 3; + string name = 3; + bytes message = 4; } message SignResponse { @@ -84,7 +85,7 @@ message SignResponse { message VerifyRequest { string curvetype = 1; bytes pub = 2; - bytes hash = 3; + bytes message = 3; bytes signature = 4; } @@ -106,7 +107,7 @@ message ListResponse { repeated Key key = 1; } -message AddRequest { +message AddNameRequest { string keyname = 1; string address = 2; } diff --git a/keys/server.go b/keys/server.go index 63232326a07bb630ff7e2630e9442af98f931b3c..3ffa0e4375084c987baf075fea31fdc00dc5e8f5 100644 --- a/keys/server.go +++ b/keys/server.go @@ -10,76 +10,45 @@ import ( "github.com/hyperledger/burrow/crypto" "github.com/hyperledger/burrow/keys/pbkeys" + "github.com/tmthrgd/go-hex" "golang.org/x/crypto/ripemd160" "google.golang.org/grpc" ) //------------------------------------------------------------------------ -// all cli commands pass through the http server -// the server process also maintains the unlocked accounts - -type server struct{} - -var GlobalKeyServer server - -func startServer() error { - if GlobalKeystore == nil { - ks, err := newKeyStore() - if err != nil { - return err - } - - GlobalKeystore = ks - } - GlobalKeyServer = server{} - - return nil -} - -func StartGRPCServer(grpcserver *grpc.Server, keyConfig *KeysConfig) error { - err := startServer() - if err != nil { - return err - } - if keyConfig.ServerEnabled { - pbkeys.RegisterKeysServer(grpcserver, &GlobalKeyServer) - } - return nil -} - -func StartStandAloneServer(host, port string) error { - err := startServer() - if err != nil { - return err - } +// all cli commands pass through the http KeyStore +// the KeyStore process also maintains the unlocked accounts +func StartStandAloneServer(keysDir, host, port string) error { listen, err := net.Listen("tcp", host+":"+port) if err != nil { return err } + ks := NewKeyStore(keysDir) + grpcServer := grpc.NewServer() - pbkeys.RegisterKeysServer(grpcServer, &server{}) + pbkeys.RegisterKeysServer(grpcServer, &ks) return grpcServer.Serve(listen) } //------------------------------------------------------------------------ // handlers -func (k *server) GenerateKey(ctx context.Context, in *pbkeys.GenRequest) (*pbkeys.GenResponse, error) { +func (k *KeyStore) GenerateKey(ctx context.Context, in *pbkeys.GenRequest) (*pbkeys.GenResponse, error) { curveT, err := crypto.CurveTypeFromString(in.Curvetype) if err != nil { return nil, err } - key, err := GlobalKeystore.GenerateKey(in.Passphrase, curveT) + key, err := k.Gen(in.Passphrase, curveT) if err != nil { return nil, fmt.Errorf("error generating key %s %s", curveT, err) } addrH := key.Address.String() if in.Keyname != "" { - err = coreNameAdd(in.Keyname, addrH) + err = coreNameAdd(k.keysDirPath, in.Keyname, addrH) if err != nil { return nil, err } @@ -88,14 +57,24 @@ func (k *server) GenerateKey(ctx context.Context, in *pbkeys.GenRequest) (*pbkey return &pbkeys.GenResponse{Address: addrH}, nil } -func (k *server) Export(ctx context.Context, in *pbkeys.ExportRequest) (*pbkeys.ExportResponse, error) { - addr, err := getNameAddr(in.GetName(), in.GetAddress()) +func (k *KeyStore) Export(ctx context.Context, in *pbkeys.ExportRequest) (*pbkeys.ExportResponse, error) { + addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress()) if err != nil { return nil, err } - resp, err := coreExport(in.GetPassphrase(), addr) + addrB, err := crypto.AddressFromHexString(addr) + if err != nil { + return nil, err + } + + // No phrase needed for public key. I hope. + key, err := k.GetKey(in.GetPassphrase(), addrB.Bytes()) + if err != nil { + return nil, err + } + resp, err := coreExport(key) if err != nil { return nil, err } @@ -103,8 +82,8 @@ func (k *server) Export(ctx context.Context, in *pbkeys.ExportRequest) (*pbkeys. return &pbkeys.ExportResponse{Export: string(resp)}, nil } -func (k *server) PublicKey(ctx context.Context, in *pbkeys.PubRequest) (*pbkeys.PubResponse, error) { - addr, err := getNameAddr(in.GetName(), in.GetAddress()) +func (k *KeyStore) PublicKey(ctx context.Context, in *pbkeys.PubRequest) (*pbkeys.PubResponse, error) { + addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress()) if err != nil { return nil, err } @@ -115,7 +94,7 @@ func (k *server) PublicKey(ctx context.Context, in *pbkeys.PubRequest) (*pbkeys. } // No phrase needed for public key. I hope. - key, err := GlobalKeystore.GetKey("", addrB.Bytes()) + key, err := k.GetKey("", addrB.Bytes()) if key == nil { return nil, err } @@ -123,27 +102,32 @@ func (k *server) PublicKey(ctx context.Context, in *pbkeys.PubRequest) (*pbkeys. return &pbkeys.PubResponse{Curvetype: key.CurveType.String(), Pub: key.Pubkey()}, nil } -func (k *server) Sign(ctx context.Context, in *pbkeys.SignRequest) (*pbkeys.SignResponse, error) { - addr, err := crypto.AddressFromHexString(in.Address) +func (k *KeyStore) Sign(ctx context.Context, in *pbkeys.SignRequest) (*pbkeys.SignResponse, error) { + addr, err := getNameAddr(k.keysDirPath, in.GetName(), in.GetAddress()) + if err != nil { + return nil, err + } + + addrB, err := crypto.AddressFromHexString(addr) if err != nil { return nil, err } - key, err := GlobalKeystore.GetKey(in.GetPassphrase(), addr[:]) + key, err := k.GetKey(in.GetPassphrase(), addrB[:]) if err != nil { return nil, err } - sig, err := key.Sign(in.GetHash()) + sig, err := key.Sign(in.GetMessage()) return &pbkeys.SignResponse{Signature: sig}, nil } -func (k *server) Verify(ctx context.Context, in *pbkeys.VerifyRequest) (*pbkeys.Empty, error) { +func (k *KeyStore) Verify(ctx context.Context, in *pbkeys.VerifyRequest) (*pbkeys.Empty, error) { if in.GetPub() == nil { return nil, fmt.Errorf("must provide a pubkey") } - if in.GetHash() == nil { + if in.GetMessage() == nil { return nil, fmt.Errorf("must provide a message") } if in.GetSignature() == nil { @@ -162,7 +146,7 @@ func (k *server) Verify(ctx context.Context, in *pbkeys.VerifyRequest) (*pbkeys. if err != nil { return nil, err } - match := pubkey.Verify(in.GetHash(), sig) + match := pubkey.Verify(in.GetMessage(), sig) if !match { return nil, fmt.Errorf("Signature does not match") } @@ -170,7 +154,7 @@ func (k *server) Verify(ctx context.Context, in *pbkeys.VerifyRequest) (*pbkeys. return &pbkeys.Empty{}, nil } -func (k *server) Hash(ctx context.Context, in *pbkeys.HashRequest) (*pbkeys.HashResponse, error) { +func (k *KeyStore) Hash(ctx context.Context, in *pbkeys.HashRequest) (*pbkeys.HashResponse, error) { var hasher hash.Hash switch in.GetHashtype() { case "ripemd160": @@ -184,25 +168,25 @@ func (k *server) Hash(ctx context.Context, in *pbkeys.HashRequest) (*pbkeys.Hash hasher.Write(in.GetMessage()) - return &pbkeys.HashResponse{Hash: fmt.Sprintf("%X", hasher.Sum(nil))}, nil + return &pbkeys.HashResponse{Hash: hex.EncodeUpperToString(hasher.Sum(nil))}, nil } -func (k *server) ImportJSON(ctx context.Context, in *pbkeys.ImportJSONRequest) (*pbkeys.ImportResponse, error) { +func (k *KeyStore) ImportJSON(ctx context.Context, in *pbkeys.ImportJSONRequest) (*pbkeys.ImportResponse, error) { keyJSON := []byte(in.GetJSON()) var err error addr := IsValidKeyJson(keyJSON) if addr != nil { - _, err = writeKey(KeysDir, addr, keyJSON) + _, err = writeKey(k.keysDirPath, addr, keyJSON) } else { err = fmt.Errorf("invalid json key passed on command line") } if err != nil { return nil, err } - return &pbkeys.ImportResponse{Address: fmt.Sprintf("%X", addr)}, nil + return &pbkeys.ImportResponse{Address: hex.EncodeUpperToString(addr)}, nil } -func (k *server) Import(ctx context.Context, in *pbkeys.ImportRequest) (*pbkeys.ImportResponse, error) { +func (k *KeyStore) Import(ctx context.Context, in *pbkeys.ImportRequest) (*pbkeys.ImportResponse, error) { curveT, err := crypto.CurveTypeFromString(in.GetCurvetype()) if err != nil { return nil, err @@ -213,20 +197,20 @@ func (k *server) Import(ctx context.Context, in *pbkeys.ImportRequest) (*pbkeys. } // store the new key - if err = GlobalKeystore.StoreKey(in.GetPassphrase(), key); err != nil { + if err = k.StoreKey(in.GetPassphrase(), key); err != nil { return nil, err } if in.GetName() != "" { - if err := coreNameAdd(in.GetName(), key.Address.String()); err != nil { + if err := coreNameAdd(k.keysDirPath, in.GetName(), key.Address.String()); err != nil { return nil, err } } - return &pbkeys.ImportResponse{Address: fmt.Sprintf("%X", key.Address)}, nil + return &pbkeys.ImportResponse{Address: hex.EncodeUpperToString(key.Address[:])}, nil } -func (k *server) List(ctx context.Context, in *pbkeys.Name) (*pbkeys.ListResponse, error) { - names, err := coreNameList() +func (k *KeyStore) List(ctx context.Context, in *pbkeys.Name) (*pbkeys.ListResponse, error) { + names, err := coreNameList(k.keysDirPath) if err != nil { return nil, err } @@ -240,15 +224,15 @@ func (k *server) List(ctx context.Context, in *pbkeys.Name) (*pbkeys.ListRespons return &pbkeys.ListResponse{Key: list}, nil } -func (k *server) Remove(ctx context.Context, in *pbkeys.Name) (*pbkeys.Empty, error) { +func (k *KeyStore) RemoveName(ctx context.Context, in *pbkeys.Name) (*pbkeys.Empty, error) { if in.GetKeyname() == "" { return nil, fmt.Errorf("please specify a name") } - return &pbkeys.Empty{}, coreNameRm(in.GetKeyname()) + return &pbkeys.Empty{}, coreNameRm(k.keysDirPath, in.GetKeyname()) } -func (k *server) Add(ctx context.Context, in *pbkeys.AddRequest) (*pbkeys.Empty, error) { +func (k *KeyStore) AddName(ctx context.Context, in *pbkeys.AddNameRequest) (*pbkeys.Empty, error) { if in.GetKeyname() == "" { return nil, fmt.Errorf("please specify a name") } @@ -257,5 +241,5 @@ func (k *server) Add(ctx context.Context, in *pbkeys.AddRequest) (*pbkeys.Empty, return nil, fmt.Errorf("please specify an address") } - return &pbkeys.Empty{}, coreNameAdd(in.GetKeyname(), strings.ToUpper(in.GetAddress())) + return &pbkeys.Empty{}, coreNameAdd(k.keysDirPath, in.GetKeyname(), strings.ToUpper(in.GetAddress())) } diff --git a/keys/server_test.go b/keys/server_test.go index c5266089ec79451b30181e216105cfc2dda1697e..614daaecb6f9eba0950acc29d9b1d43feef7f72a 100644 --- a/keys/server_test.go +++ b/keys/server_test.go @@ -37,7 +37,7 @@ var ( func init() { failedCh := make(chan error) go func() { - err := StartStandAloneServer(DefaultHost, TestPort) + err := StartStandAloneServer(DefaultKeysDir, DefaultHost, TestPort) failedCh <- err }() tick := time.NewTicker(time.Second) @@ -126,12 +126,12 @@ func testServerSignAndVerify(t *testing.T, typ string) { } hash := sha3.Sha3([]byte("the hash of something!")) - sig, err := c.Sign(ctx, &pbkeys.SignRequest{Address: addr, Hash: hash}) + sig, err := c.Sign(ctx, &pbkeys.SignRequest{Address: addr, Message: hash}) if err != nil { t.Fatal(err) } - _, err = c.Verify(ctx, &pbkeys.VerifyRequest{Signature: sig.GetSignature(), Pub: resp.GetPub(), Hash: hash, Curvetype: typ}) + _, err = c.Verify(ctx, &pbkeys.VerifyRequest{Signature: sig.GetSignature(), Pub: resp.GetPub(), Message: hash, Curvetype: typ}) if err != nil { t.Fatal(err) } diff --git a/keys/test.sh b/keys/test.sh index d25704af191fe7434033cc9e69aa2d5d1abaaf1d..7bb16ed18f12b9ee425fdc03a178aaa4d91fb7cb 100755 --- a/keys/test.sh +++ b/keys/test.sh @@ -1,14 +1,17 @@ #! /bin/bash -set -e # tests # run the suite with and without the daemon # TODO: run the suite with/without encryption! + +burrow_bin=${burrow_bin:-burrow} + echo "-----------------------------" echo "starting the server" -monax-keys server & +$burrow_bin keys server & +keys_pid=$! sleep 1 echo "-----------------------------" echo "testing the cli" @@ -18,37 +21,40 @@ echo "testing the cli" echo "testing keys" -KEYTYPES=("ed25519,ripemd160" "secp256k1,sha3" "secp256k1,ripemd160sha256") -for KEYTYPE in ${KEYTYPES[*]} +CURVETYPES=("ed25519" "secp256k1") +for CURVETYPE in ${CURVETYPES[*]} do # test key gen, sign verify: # for each step, ensure it works using --addr or --name - echo "... $KEYTYPE" + echo "... $CURVETYPE" - HASH=`monax-keys hash --type sha256 ok` + HASH=`$burrow_bin keys hash --type sha256 ok` #echo "HASH: $HASH" NAME=testkey1 - ADDR=`monax-keys gen --type $KEYTYPE --name $NAME --no-pass` + ADDR=`$burrow_bin keys gen --curvetype $CURVETYPE --name $NAME --no-password` #echo "my addr: $ADDR" - PUB1=`monax-keys pub --name $NAME` - PUB2=`monax-keys pub --addr $ADDR` + PUB1=`$burrow_bin keys pub --name $NAME` + PUB2=`$burrow_bin keys pub --addr $ADDR` if [ "$PUB1" != "$PUB2" ]; then echo "FAILED pub: got $PUB2, expected $PUB1" + kill $keys_pid exit 1 fi echo "...... passed pub" - SIG1=`monax-keys sign --name $NAME $HASH` - VERIFY1=`monax-keys verify --type $KEYTYPE $HASH $SIG1 $PUB1` + SIG1=`$burrow_bin keys sign --name $NAME $HASH` + VERIFY1=`$burrow_bin keys verify --curvetype $CURVETYPE $HASH $SIG1 $PUB1` if [ $VERIFY1 != "true" ]; then echo "FAILED verify: got $VERIFY1 expected true" + kill $keys_pid exit 1 fi - SIG2=`monax-keys sign --addr $ADDR $HASH` - VERIFY1=`monax-keys verify --type $KEYTYPE $HASH $SIG2 $PUB1` + SIG2=`$burrow_bin keys sign --addr $ADDR $HASH` + VERIFY1=`$burrow_bin keys verify --curvetype $CURVETYPE $HASH $SIG2 $PUB1` if [ $VERIFY1 != "true" ]; then echo "FAILED verify: got $VERIFY1 expected true" + kill $keys_pid exit 1 fi @@ -64,7 +70,7 @@ for HASHTYPE in ${HASHTYPES[*]} do echo "... $HASHTYPE" HASH0=`echo -n $TOHASH | openssl dgst -$HASHTYPE | awk '{print toupper($2)}'` - HASH1=`monax-keys hash --type $HASHTYPE $TOHASH` + HASH1=`$burrow_bin keys hash --type $HASHTYPE $TOHASH` if [ "$HASH0" != "$HASH1" ]; then echo "FAILED hash $HASHTYPE: got $HASH1 expected $HASH0" fi @@ -77,39 +83,42 @@ echo "testing imports" # for each key type, import a priv key, ensure it returns # the right address. do again with both plain and encrypted jsons -for KEYTYPE in ${KEYTYPES[*]} +for CURVETYPE in ${CURVETYPES[*]} do - echo "... $KEYTYPE" + echo "... $CURVETYPE" # create a key, get its address and priv, backup the json, delete the key - ADDR=`monax-keys gen --type $KEYTYPE --no-pass` - DIR=$HOME/.monax/keys/data/$ADDR - FILE=$DIR/$ADDR - PRIV=`cat $FILE | jq -r .PrivateKey` - HEXPRIV=`echo -n "$PRIV" | base64 -d | hexdump -ve '1/1 "%.2X"'` + ADDR=`$burrow_bin keys gen --curvetype $CURVETYPE --no-password` + DIR=.keys/data + FILE=$DIR/$ADDR.json + PRIV=`cat $FILE | jq -r .PrivateKey.Plain` + HEXPRIV=`echo -n "$PRIV" | base64 -d | xxd -p -u -c 256` cp $FILE ~/$ADDR rm -rf $DIR # import the key via priv - ADDR2=`monax-keys import --no-pass --type $KEYTYPE $HEXPRIV` + ADDR2=`$burrow_bin keys import --no-password --curvetype $CURVETYPE $HEXPRIV` if [ "$ADDR" != "$ADDR2" ]; then - echo "FAILED import $KEYTYPE: got $ADDR2 expected $ADDR" + echo "FAILED import $CURVETYPE: got $ADDR2 expected $ADDR" + kill $keys_pid exit fi rm -rf $DIR # import the key via json JSON=`cat ~/$ADDR` - ADDR2=`monax-keys import --no-pass --type $KEYTYPE $JSON` + ADDR2=`$burrow_bin keys import --no-password --curvetype $CURVETYPE $JSON` if [ "$ADDR" != "$ADDR2" ]; then - echo "FAILED import (json) $KEYTYPE: got $ADDR2 expected $ADDR" + echo "FAILED import (json) $CURVETYPE: got $ADDR2 expected $ADDR" + kill $keys_pid exit fi rm -rf $DIR # import the key via path - ADDR2=`monax-keys import --no-pass --type $KEYTYPE ~/$ADDR` + ADDR2=`$burrow_bin keys import --no-password --curvetype $CURVETYPE ~/$ADDR` if [ "$ADDR" != "$ADDR2" ]; then - echo "FAILED import $KEYTYPE: got $ADDR2 expected $ADDR" + echo "FAILED import $CURVETYPE: got $ADDR2 expected $ADDR" + kill $keys_pid exit fi rm -rf $DIR @@ -121,23 +130,26 @@ done echo "testing names" NAME=mykey -ADDR=`monax-keys gen --name $NAME --no-pass` -ADDR2=`monax-keys name $NAME` +ADDR=`$burrow_bin keys gen --name $NAME --no-password` +ADDR2=`$burrow_bin keys list --name $NAME` if [ "$ADDR" != "$ADDR2" ]; then - echo "FAILED name: got $ADDR2 expected $ADDR" + echo "FAILED name: got $ADDR2 expected $ADDR" + kill $keys_pid exit fi NAME2=mykey2 -monax-keys name $NAME2 $ADDR -ADDR2=`monax-keys name $NAME2` +$burrow_bin keys name $NAME2 $ADDR +ADDR2=`$burrow_bin keys list --name $NAME2` if [ "$ADDR" != "$ADDR2" ]; then - echo "FAILED rename: got $ADDR2 expected $ADDR" + echo "FAILED rename: got $ADDR2 expected $ADDR" + kill $keys_pid exit fi echo "... passed" +kill $keys_pid # TODO a little more on names... diff --git a/keys/tests/build_tool.sh b/keys/tests/build_tool.sh deleted file mode 100755 index 80b8f00016d28a3194199b0f48e154c8bafbb810..0000000000000000000000000000000000000000 --- a/keys/tests/build_tool.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash -# ---------------------------------------------------------- -# PURPOSE - -# This is the build script for the monax stack. It will -# build the tool into docker containers in a reliable and -# predicatable manner. - -# ---------------------------------------------------------- -# REQUIREMENTS - -# docker installed locally - -# ---------------------------------------------------------- -# USAGE - -# build_tool.sh - -# ---------------------------------------------------------- - -TARGET=monax-keys -IMAGE=quay.io/monax/keys - -set -e - -if [ "$JENKINS_URL" ] || [ "$CIRCLE_BRANCH" ] -then - REPO=`pwd` - CI="true" -else - REPO=$GOPATH/src/github.com/hyperledger/burrow/keys -fi - -release_min=$(cat $REPO/version/version.go | tail -n 1 | cut -d \ -f 4 | tr -d '"') -release_maj=$(echo $release_min | cut -d . -f 1-2) - -# Build -docker build -t $IMAGE:build $REPO -docker run --rm --entrypoint cat $IMAGE:build /usr/local/bin/$TARGET > $REPO/"$TARGET"_build_artifact - -#----------------------------------------------------------------------------- - -docker build -t $IMAGE:$release_min -f Dockerfile.deploy $REPO - -# Cleanup -rm $REPO/"$TARGET"_build_artifact - -# Extra Tags -if [[ "$branch" = "master" ]] -then - docker tag -f $IMAGE:$release_min $IMAGE:$release_maj - docker tag -f $IMAGE:$release_min $IMAGE:latest -fi - -if [ "$CIRCLE_BRANCH" ] -then - docker tag -f $IMAGE:$release_min $IMAGE:latest -fi diff --git a/rpc/config.go b/rpc/config.go index 9ece9ccc3aee5606e333e23ab180f0677003a12e..9449609d98ead8a4330fa4fac0f4d2a8930ff9bf 100644 --- a/rpc/config.go +++ b/rpc/config.go @@ -3,13 +3,13 @@ package rpc import "github.com/hyperledger/burrow/rpc/v0/server" type RPCConfig struct { - V0 *V0Config `json:",omitempty" toml:",omitempty"` - TM *TMConfig `json:",omitempty" toml:",omitempty"` - Profiler *ProfilerConfig `json:",omitempty" toml:",omitempty"` - GRPC *GRPCConfig `json:",omitempty" toml:",omitempty"` + V0 *V0Config `json:",omitempty" toml:",omitempty"` + TM *ServerConfig `json:",omitempty" toml:",omitempty"` + Profiler *ServerConfig `json:",omitempty" toml:",omitempty"` + GRPC *ServerConfig `json:",omitempty" toml:",omitempty"` } -type TMConfig struct { +type ServerConfig struct { Enabled bool ListenAddress string } @@ -45,22 +45,22 @@ func DefaultV0Config() *V0Config { } } -func DefaultTMConfig() *TMConfig { - return &TMConfig{ +func DefaultTMConfig() *ServerConfig { + return &ServerConfig{ Enabled: true, ListenAddress: "tcp://localhost:46657", } } -func DefaultGRPCConfig() *GRPCConfig { - return &GRPCConfig{ +func DefaultGRPCConfig() *ServerConfig { + return &ServerConfig{ Enabled: true, ListenAddress: "localhost:10997", } } -func DefaultProfilerConfig() *ProfilerConfig { - return &ProfilerConfig{ +func DefaultProfilerConfig() *ServerConfig { + return &ServerConfig{ Enabled: false, ListenAddress: "tcp://localhost:6060", }