From 971af2c4b1440af8134c14582f6ab27a537f1d9b Mon Sep 17 00:00:00 2001 From: David Yan Date: Tue, 28 Jan 2020 14:57:42 -0800 Subject: [PATCH] cmd/signer: Add signer extract command, add entity signer pk check --- .changelog/2609.feature.md | 5 +++++ go/common/entity/entity.go | 5 +++++ go/oasis-node/cmd/common/common.go | 16 ++++++++++++++ go/oasis-node/cmd/signer/signer.go | 35 ++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+) create mode 100644 .changelog/2609.feature.md diff --git a/.changelog/2609.feature.md b/.changelog/2609.feature.md new file mode 100644 index 00000000000..de8acf66a5a --- /dev/null +++ b/.changelog/2609.feature.md @@ -0,0 +1,5 @@ +Export signer public key to entity + +We added a command to export entities from existing signers, and a check to ensure +that the entity and signer public keys match. +This makes it so that a dummy entity cannot be used for signers backed by Ledger. diff --git a/go/common/entity/entity.go b/go/common/entity/entity.go index 5fd8baffc80..553f9cbe7dc 100644 --- a/go/common/entity/entity.go +++ b/go/common/entity/entity.go @@ -77,6 +77,11 @@ func Load(baseDir string, signerFactory signature.SignerFactory) (*Entity, signa return nil, nil, err } + if !ent.ID.Equal(signer.Public()) { + signer.Reset() + return nil, nil, fmt.Errorf("public key mismatch (signer: %s, entity: %s)", signer.Public(), ent.ID) + } + return ent, signer, nil } diff --git a/go/oasis-node/cmd/common/common.go b/go/oasis-node/cmd/common/common.go index f63cb0d6cc6..d462d63a82c 100644 --- a/go/oasis-node/cmd/common/common.go +++ b/go/oasis-node/cmd/common/common.go @@ -278,3 +278,19 @@ func LoadEntity(signerBackend string, entityDir string) (*entity.Entity, signatu return entity.Load(entityDir, factory) } + +// ExportEntity creates an empty entity from the public key of the signer +// generated with the specified backend, and writes it to a file in entityDir. +func ExportEntity(signerBackend string, entityDir string) error { + factory, err := SignerFactory(signerBackend, entityDir) + if err != nil { + return err + } + signer, err := factory.Load(signature.SignerEntity) + if err != nil { + return err + } + var entity entity.Entity + entity.ID = signer.Public() + return entity.Save(entityDir) +} diff --git a/go/oasis-node/cmd/signer/signer.go b/go/oasis-node/cmd/signer/signer.go index b97d4dcc0a5..f8b79ae6822 100644 --- a/go/oasis-node/cmd/signer/signer.go +++ b/go/oasis-node/cmd/signer/signer.go @@ -2,8 +2,13 @@ package signer import ( + "os" + "github.com/spf13/cobra" + "github.com/oasislabs/oasis-core/go/common/logging" + cmdCommon "github.com/oasislabs/oasis-core/go/oasis-node/cmd/common" + cmdFlags "github.com/oasislabs/oasis-core/go/oasis-node/cmd/common/flags" "github.com/oasislabs/oasis-core/go/oasis-node/cmd/signer/ledger" ) @@ -12,8 +17,35 @@ var ( Use: "signer", Short: "signer backend utilities", } + + exportCmd = &cobra.Command{ + Use: "export", + Short: "export the public key from signer as an empty entity", + Run: doExport, + } + + logger = logging.GetLogger("cmd/signer") ) +func doExport(cmd *cobra.Command, args []string) { + if err := cmdCommon.Init(); err != nil { + cmdCommon.EarlyLogAndExit(err) + } + entityDir, err := cmdFlags.SignerDirOrPwd() + if err != nil { + logger.Error("failed to retrieve signer dir", + "err", err, + ) + os.Exit(1) + } + if err := cmdCommon.ExportEntity(cmdFlags.Signer(), entityDir); err != nil { + logger.Error("failed to export entity", + "err", err, + ) + os.Exit(1) + } +} + func Register(parentCmd *cobra.Command) { for _, v := range []func(*cobra.Command){ ledger.Register, @@ -21,5 +53,8 @@ func Register(parentCmd *cobra.Command) { v(signerCmd) } + exportCmd.Flags().AddFlagSet(cmdFlags.SignerFlags) + + signerCmd.AddCommand(exportCmd) parentCmd.AddCommand(signerCmd) }