Skip to content

Commit

Permalink
R4R: keys support ledger nano s (#125)
Browse files Browse the repository at this point in the history
* bnbcli support ledger

* for test

* Optimize sign flow

* check ledger app version

* refactor app version check

* Update ledger-cosmos-go dependency
  • Loading branch information
HaoyangLiu authored and notatestuser committed Apr 23, 2019
1 parent adaf2e0 commit d8721e5
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 24 deletions.
47 changes: 32 additions & 15 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions Gopkg.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,9 @@
revision = "52158e4697b87de16ed390e1bdaf813e581008fa"

[[constraint]]
name = "github.com/zondax/ledger-goclient"
version = "=v0.1.0"
name = "github.com/zondax/ledger-cosmos-go"
source = "https://github.com/binance-chain/ledger-cosmos-go"
version = "v0.9.9-binance.1"

## transitive deps, with releases:

Expand Down Expand Up @@ -116,5 +117,8 @@
[prune]
go-tests = true
unused-packages = true
[[prune.project]]
name = "github.com/zondax/hid"
unused-packages = false


2 changes: 1 addition & 1 deletion client/keys/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ func runAddCmd(cmd *cobra.Command, args []string) error {
if viper.GetBool(client.FlagUseLedger) {
account := uint32(viper.GetInt(flagAccount))
index := uint32(viper.GetInt(flagIndex))
path := ccrypto.DerivationPath{44, 118, account, 0, index}
path := ccrypto.DerivationPath{44, 714, account, 0, index}
algo := keys.SigningAlgo(viper.GetString(flagType))
info, err := kb.CreateLedger(name, path, algo)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions crypto/ledger.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
package crypto

import (
ledger "github.com/zondax/ledger-goclient"
ledger "github.com/zondax/ledger-cosmos-go"
)

// If ledger support (build tag) has been enabled, which implies a CGO dependency,
// set the discoverLedger function which is responsible for loading the Ledger
// device at runtime or returning an error.
func init() {
discoverLedger = func() (LedgerSECP256K1, error) {
device, err := ledger.FindLedger()
device, err := ledger.FindLedgerCosmosUserApp()
if err != nil {
return nil, err
}
Expand Down
47 changes: 43 additions & 4 deletions crypto/ledger_secp256k1.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package crypto

import (
"bufio"
"fmt"
"os"
"strings"

"github.com/pkg/errors"
"github.com/btcsuite/btcd/btcec"
sdk "github.com/cosmos/cosmos-sdk/types"
ledgergo "github.com/zondax/ledger-cosmos-go"

secp256k1 "github.com/btcsuite/btcd/btcec"
"github.com/pkg/errors"
tmbtcec "github.com/tendermint/btcd/btcec"
tmcrypto "github.com/tendermint/tendermint/crypto"
tmsecp256k1 "github.com/tendermint/tendermint/crypto/secp256k1"
)
Expand All @@ -29,7 +35,9 @@ type (
// the SECP256K1 scheme.
LedgerSECP256K1 interface {
GetPublicKeySECP256K1([]uint32) ([]byte, error)
ShowAddressSECP256K1([]uint32, string) error
SignSECP256K1([]uint32, []byte) ([]byte, error)
GetVersion() (*ledgergo.VersionInfo, error)
}

// PrivKeyLedgerSecp256k1 implements PrivKey, calling the ledger nano we
Expand Down Expand Up @@ -117,12 +125,43 @@ func (pkl PrivKeyLedgerSecp256k1) Equals(other tmcrypto.PrivKey) bool {
// an error, so this should only trigger if the private key is held in memory
// for a while before use.
func (pkl PrivKeyLedgerSecp256k1) Sign(msg []byte) ([]byte, error) {
ledgerAppVersion, err := pkl.ledger.GetVersion()
if err != nil {
return nil, err
}
if ledgerAppVersion.Major > 1 || ledgerAppVersion.Major == 1 && ledgerAppVersion.Minor >= 1 {
fmt.Print(fmt.Sprintf("Please confirm if address displayed on ledger is identical to %s (yes/no)?", sdk.AccAddress(pkl.CachedPubKey.Address()).String()))
err = pkl.ledger.ShowAddressSECP256K1(pkl.Path, sdk.GetConfig().GetBech32AccountAddrPrefix())
if err != nil {
return nil, err
}

buf, err := bufio.NewReader(os.Stdin).ReadString('\n')
if err != nil {
return nil, err
}
confirm := strings.ToLower(strings.TrimSpace(buf))
if confirm != "y" && confirm != "yes" {
return nil, fmt.Errorf("ledger account doesn't match")
}
}
fmt.Println("Please verify the transaction data on ledger")

sig, err := pkl.signLedgerSecp256k1(msg)
if err != nil {
return nil, err
}

return sig, nil
return convertDERtoBER(sig)
}

func convertDERtoBER(signatureDER []byte) ([]byte, error) {
sigDER, err := btcec.ParseDERSignature(signatureDER[:], btcec.S256())
if err != nil {
return nil, err
}
sigBER := tmbtcec.Signature{R: sigDER.R, S: sigDER.S}
return sigBER.Serialize(), nil
}

// getPubKey reads the pubkey the ledger itself
Expand Down Expand Up @@ -150,7 +189,7 @@ func (pkl PrivKeyLedgerSecp256k1) pubkeyLedgerSecp256k1() (pub tmcrypto.PubKey,
var pk tmsecp256k1.PubKeySecp256k1

// re-serialize in the 33-byte compressed format
cmp, err := secp256k1.ParsePubKey(key[:], secp256k1.S256())
cmp, err := btcec.ParsePubKey(key[:], btcec.S256())
if err != nil {
return nil, fmt.Errorf("error parsing public key: %v", err)
}
Expand Down

0 comments on commit d8721e5

Please sign in to comment.