mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 10:52:25 +00:00
accounts/usbwallet: trezor signed message support
This commit is contained in:
parent
e8c9579fb7
commit
24d7201acd
4 changed files with 72 additions and 2 deletions
|
|
@ -168,6 +168,12 @@ func (w *ledgerDriver) SignTx(path accounts.DerivationPath, tx *types.Transactio
|
||||||
return w.ledgerSign(path, tx, chainID)
|
return w.ledgerSign(path, tx, chainID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SignData sends a blob of data to the USB device and waits for the user to confirm
|
||||||
|
// or deny the transaction.
|
||||||
|
func (w *ledgerDriver) SignData(path accounts.DerivationPath, hash []byte) (common.Address, []byte, error) {
|
||||||
|
return common.Address{}, nil, accounts.ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
// ledgerVersion retrieves the current version of the Ethereum wallet app running
|
// ledgerVersion retrieves the current version of the Ethereum wallet app running
|
||||||
// on the Ledger wallet.
|
// on the Ledger wallet.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,29 @@ func (w *trezorDriver) SignTx(path accounts.DerivationPath, tx *types.Transactio
|
||||||
return w.trezorSign(path, tx, chainID)
|
return w.trezorSign(path, tx, chainID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SignData sends a blob of data to the xUSB device and waits for the user to confirm
|
||||||
|
// or deny the transaction.
|
||||||
|
func (w *trezorDriver) SignData(path accounts.DerivationPath, hash []byte) (common.Address, []byte, error) {
|
||||||
|
request := &trezor.EthereumSignMessage{
|
||||||
|
AddressN: path,
|
||||||
|
Message: hash,
|
||||||
|
}
|
||||||
|
response := new(trezor.EthereumMessageSignature)
|
||||||
|
if _, err := w.trezorExchange(request, response); err != nil {
|
||||||
|
return common.Address{}, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var address common.Address
|
||||||
|
if addr := response.GetAddressBin(); len(addr) > 0 { // Older firmwares use binary fomats
|
||||||
|
address = common.BytesToAddress(addr)
|
||||||
|
}
|
||||||
|
if addr := response.GetAddressHex(); len(addr) > 0 { // Newer firmwares use hexadecimal fomats
|
||||||
|
address = common.HexToAddress(addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return address, response.Signature, nil
|
||||||
|
}
|
||||||
|
|
||||||
// trezorDerive sends a derivation request to the Trezor device and returns the
|
// trezorDerive sends a derivation request to the Trezor device and returns the
|
||||||
// Ethereum address located on that path.
|
// Ethereum address located on that path.
|
||||||
func (w *trezorDriver) trezorDerive(derivationPath []uint32) (common.Address, error) {
|
func (w *trezorDriver) trezorDerive(derivationPath []uint32) (common.Address, error) {
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,10 @@ type driver interface {
|
||||||
// SignTx sends the transaction to the USB device and waits for the user to confirm
|
// SignTx sends the transaction to the USB device and waits for the user to confirm
|
||||||
// or deny the transaction.
|
// or deny the transaction.
|
||||||
SignTx(path accounts.DerivationPath, tx *types.Transaction, chainID *big.Int) (common.Address, *types.Transaction, error)
|
SignTx(path accounts.DerivationPath, tx *types.Transaction, chainID *big.Int) (common.Address, *types.Transaction, error)
|
||||||
|
|
||||||
|
// SignData sends a blob of data to the USB device and waits for the user to confirm
|
||||||
|
// or deny the transaction.
|
||||||
|
SignData(path accounts.DerivationPath, hash []byte) (common.Address, []byte, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// wallet represents the common functionality shared by all USB hardware
|
// wallet represents the common functionality shared by all USB hardware
|
||||||
|
|
@ -515,7 +519,44 @@ func (w *wallet) SelfDerive(bases []accounts.DerivationPath, chain ethereum.Chai
|
||||||
// signHash implements accounts.Wallet, however signing arbitrary data is not
|
// signHash implements accounts.Wallet, however signing arbitrary data is not
|
||||||
// supported for hardware wallets, so this method will always return an error.
|
// supported for hardware wallets, so this method will always return an error.
|
||||||
func (w *wallet) signHash(account accounts.Account, hash []byte) ([]byte, error) {
|
func (w *wallet) signHash(account accounts.Account, hash []byte) ([]byte, error) {
|
||||||
return nil, accounts.ErrNotSupported
|
w.stateLock.RLock() // Comms have their own mutex
|
||||||
|
defer w.stateLock.RUnlock()
|
||||||
|
|
||||||
|
// If the wallet is closed, abort
|
||||||
|
if w.device == nil {
|
||||||
|
return nil, accounts.ErrWalletClosed
|
||||||
|
}
|
||||||
|
// Make sure the requested account is contained within
|
||||||
|
path, ok := w.paths[account.Address]
|
||||||
|
if !ok {
|
||||||
|
return nil, accounts.ErrUnknownAccount
|
||||||
|
}
|
||||||
|
|
||||||
|
// All infos gathered and metadata checks out, request signing
|
||||||
|
<-w.commsLock
|
||||||
|
defer func() { w.commsLock <- struct{}{} }()
|
||||||
|
|
||||||
|
// Ensure the device isn't screwed with while user confirmation is pending
|
||||||
|
// TODO(karalabe): remove if hotplug lands on Windows
|
||||||
|
w.hub.commsLock.Lock()
|
||||||
|
w.hub.commsPend++
|
||||||
|
w.hub.commsLock.Unlock()
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
w.hub.commsLock.Lock()
|
||||||
|
w.hub.commsPend--
|
||||||
|
w.hub.commsLock.Unlock()
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Sign the transaction and verify the sender to avoid hardware fault surprises
|
||||||
|
sender, signed, err := w.driver.SignData(path, hash)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if sender != account.Address {
|
||||||
|
return nil, fmt.Errorf("signer mismatch: expected %s, got %s", account.Address.Hex(), sender.Hex())
|
||||||
|
}
|
||||||
|
return signed, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed
|
// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ func (api *SignerAPI) sign(addr common.MixedcaseAddress, req *SignDataRequest, l
|
||||||
}
|
}
|
||||||
pw, err := api.lookupOrQueryPassword(account.Address,
|
pw, err := api.lookupOrQueryPassword(account.Address,
|
||||||
"Password for signing",
|
"Password for signing",
|
||||||
fmt.Sprintf("Please enter password for signing data with account %s", account.Address.Hex()))
|
fmt.Sprintf("Please enter password for signing data with account %s, or just press 'RETURN'", account.Address.Hex()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue