Browse Source

Add nano ledger to key manager

pull/1782/head
Ethan Frey 7 years ago
parent
commit
8c98c4fdf4
2 changed files with 34 additions and 8 deletions
  1. +18
    -0
      keys/cryptostore/generator.go
  2. +16
    -8
      nano/keys.go

+ 18
- 0
keys/cryptostore/generator.go View File

@ -4,6 +4,7 @@ import (
"github.com/pkg/errors"
crypto "github.com/tendermint/go-crypto"
"github.com/tendermint/go-crypto/nano"
)
var (
@ -11,6 +12,8 @@ var (
GenEd25519 Generator = GenFunc(genEd25519)
// GenSecp256k1 produces Secp256k1 private keys
GenSecp256k1 Generator = GenFunc(genSecp256)
// GenLedger used Ed25519 keys stored on nano ledger s with cosmos app
GenLedger Generator = GenFunc(genLedger)
)
// Generator determines the type of private key the keystore creates
@ -33,12 +36,25 @@ func genSecp256(secret []byte) crypto.PrivKey {
return crypto.GenPrivKeySecp256k1FromSecret(secret).Wrap()
}
// secret is completely ignored for the ledger...
// just for interface compatibility
func genLedger(secret []byte) crypto.PrivKey {
key, err := nano.NewPrivKeyLedger()
if err != nil {
// TODO: cleaner error handling
panic(err)
}
return key
}
func getGenerator(algo string) (Generator, error) {
switch algo {
case crypto.NameEd25519:
return GenEd25519, nil
case crypto.NameSecp256k1:
return GenSecp256k1, nil
case nano.NameLedger:
return GenLedger, nil
default:
return nil, errors.Errorf("Cannot generate keys for algorithm: %s", algo)
}
@ -50,6 +66,8 @@ func getGeneratorByType(typ byte) (Generator, error) {
return GenEd25519, nil
case crypto.TypeSecp256k1:
return GenSecp256k1, nil
case nano.TypeLedger:
return GenLedger, nil
default:
return nil, errors.Errorf("Cannot generate keys for algorithm: %X", typ)
}


+ 16
- 8
nano/keys.go View File

@ -12,6 +12,11 @@ import (
wire "github.com/tendermint/go-wire"
)
const (
NameLedger = "ledger"
TypeLedger = 0x10
)
var device *ledger.Ledger
// getLedger gets a copy of the device, and caches it
@ -48,7 +53,10 @@ func signLedger(device *ledger.Ledger, msg []byte) (pk crypto.PubKey, sig crypto
// PrivKeyLedger implements PrivKey, calling the ledger nano
// we cache the PubKey from the first call to use it later
type PrivKeyLedger struct {
pubKey crypto.PubKey
// PubKey should be private, but we want to encode it via go-wire
// so we can view the address later, even without having the ledger
// attached
CachedPubKey crypto.PubKey
}
func NewPrivKeyLedger() (crypto.PrivKey, error) {
@ -82,8 +90,8 @@ func (pk *PrivKeyLedger) Sign(msg []byte) crypto.Signature {
}
// if we have no pubkey yet, store it for future queries
if pk.pubKey.Empty() {
pk.pubKey = pub
if pk.CachedPubKey.Empty() {
pk.CachedPubKey = pub
}
return sig
}
@ -103,17 +111,17 @@ func (pk *PrivKeyLedger) PubKey() crypto.PubKey {
// in the PubKey interface, so this function allows better error handling
func (pk *PrivKeyLedger) getPubKey() (key crypto.PubKey, err error) {
// if we have no pubkey, set it
if pk.pubKey.Empty() {
if pk.CachedPubKey.Empty() {
dev, err := getLedger()
if err != nil {
return key, errors.WithMessage(err, "Can't connect to ledger")
}
pk.pubKey, _, err = signLedger(dev, []byte{0})
pk.CachedPubKey, _, err = signLedger(dev, []byte{0})
if err != nil {
return key, errors.WithMessage(err, "Can't sign with app")
}
}
return pk.pubKey, nil
return pk.CachedPubKey, nil
}
// Equals fulfils PrivKey Interface
@ -219,11 +227,11 @@ func (pk PubKeyLedger) Equals(other crypto.PubKey) bool {
func init() {
crypto.PrivKeyMapper.
RegisterImplementation(&PrivKeyLedger{}, "ledger", 0x10).
RegisterImplementation(&PrivKeyLedger{}, NameLedger, TypeLedger).
RegisterImplementation(MockPrivKeyLedger{}, "mock-ledger", 0x11)
crypto.PubKeyMapper.
RegisterImplementation(PubKeyLedger{}, "ledger", 0x10)
RegisterImplementation(PubKeyLedger{}, NameLedger, TypeLedger)
}
// Wrap fulfils interface for PrivKey struct


Loading…
Cancel
Save