From bb7fbe76162a3f28935f71038b8d2ac0d66d14bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tadej=20Jane=C5=BE?= Date: Thu, 25 Jun 2020 12:25:05 +0200 Subject: [PATCH] go/common/crypto/signature/signers/ledger: Descriptive error on reject Make Ledger signer return a more descriptive error message when a user rejects a transaction on the Ledger device. --- .changelog/3050.feature.md | 4 ++++ .../signature/signers/ledger/ledger_signer.go | 21 ++++++++++++++++++- go/go.mod | 1 + 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 .changelog/3050.feature.md diff --git a/.changelog/3050.feature.md b/.changelog/3050.feature.md new file mode 100644 index 00000000000..635bff32fef --- /dev/null +++ b/.changelog/3050.feature.md @@ -0,0 +1,4 @@ +go/common/crypto/signature/signers/ledger: Descriptive error on user reject + +Make Ledger signer return a more descriptive error message when a user rejects +a transaction on the Ledger device. diff --git a/go/common/crypto/signature/signers/ledger/ledger_signer.go b/go/common/crypto/signature/signers/ledger/ledger_signer.go index b293842a86d..844789b1048 100644 --- a/go/common/crypto/signature/signers/ledger/ledger_signer.go +++ b/go/common/crypto/signature/signers/ledger/ledger_signer.go @@ -2,9 +2,12 @@ package ledger import ( + "errors" "fmt" "io" + ledger "github.com/zondax/ledger-go" + "github.com/oasisprotocol/oasis-core/go/common/crypto/signature" ledgerCommon "github.com/oasisprotocol/oasis-core/go/common/ledger" ) @@ -33,6 +36,10 @@ var ( roleDerivationRootPaths = map[signature.SignerRole][]uint32{ signature.SignerEntity: SignerDerivationRootPath, } + + // NOTE: The 0x6986 ISO 7816 error code is returned by the Oasis Ledger App + // iff when a user rejects the transaction on the Ledger device. + ledgerRejectTxErrorMsg = ledger.ErrorMessage(0x6986) ) // Factory is a Ledger backed SignerFactory. @@ -125,7 +132,19 @@ func (s *Signer) ContextSign(context signature.Context, message []byte) ([]byte, if err != nil { return nil, err } - return s.device.SignEd25519(s.path, preparedContext, message) + signature, err := s.device.SignEd25519(s.path, preparedContext, message) + switch { + case err == nil: + return signature, nil + // XXX: At the moment, ledger-go doesn't use proper Go error semantics and + // doesn't expose errors as variables so we can't compare them directly with + // errors.Is(). + case err.Error() == ledgerRejectTxErrorMsg: + // Replace Ledger's raw APDU error with a more descriptive one. + return nil, errors.New("transaction was rejected on Ledger device") + default: + return nil, err + } } // String returns the address of the account on the Ledger device. diff --git a/go/go.mod b/go/go.mod index 1a7bf5f9d4f..473ca794e77 100644 --- a/go/go.mod +++ b/go/go.mod @@ -57,6 +57,7 @@ require ( github.com/uber/jaeger-client-go v2.16.0+incompatible github.com/uber/jaeger-lib v2.0.0+incompatible // indirect github.com/whyrusleeping/go-logging v0.0.1 + github.com/zondax/ledger-go v0.11.0 github.com/zondax/ledger-oasis-go v0.3.0 gitlab.com/yawning/dynlib.git v0.0.0-20200603163025-35fe007b0761 golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9