openethereum/hw/src/ledger.rs

363 lines
39 KiB
Rust
Raw Normal View History

// Copyright 2015-2017 Parity Technologies (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Ledger hardware wallet module. Supports Ledger Blue and Nano S.
/// See https://github.com/LedgerHQ/blue-app-eth/blob/master/doc/ethapp.asc for protocol details.
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
use super::{WalletInfo, KeyPath};
use bigint::hash::H256;
use ethkey::{Address, Signature};
use hidapi;
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
use parking_lot::{Mutex, RwLock};
use std::cmp::min;
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
use std::fmt;
use std::str::FromStr;
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
use std::sync::Arc;
use std::time::Duration;
const LEDGER_VID: u16 = 0x2c97;
const LEDGER_PIDS: [u16; 2] = [0x0000, 0x0001]; // Nano S and Blue
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
const ETH_DERIVATION_PATH_BE: [u8; 17] = [4, 0x80, 0, 0, 44, 0x80, 0, 0, 60, 0x80, 0, 0, 0, 0, 0, 0, 0]; // 44'/60'/0'/0
const ETC_DERIVATION_PATH_BE: [u8; 21] = [5, 0x80, 0, 0, 44, 0x80, 0, 0, 60, 0x80, 0x02, 0x73, 0xd0, 0x80, 0, 0, 0, 0, 0, 0, 0]; // 44'/60'/160720'/0'/0
const APDU_TAG: u8 = 0x05;
const APDU_CLA: u8 = 0xe0;
#[cfg(windows)] const HID_PREFIX_ZERO: usize = 1;
#[cfg(not(windows))] const HID_PREFIX_ZERO: usize = 0;
mod commands {
pub const GET_APP_CONFIGURATION: u8 = 0x06;
pub const GET_ETH_PUBLIC_ADDRESS: u8 = 0x02;
pub const SIGN_ETH_TRANSACTION: u8 = 0x04;
}
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
/// Hardware wallet error.
#[derive(Debug)]
pub enum Error {
/// Ethereum wallet protocol error.
Protocol(&'static str),
/// Hidapi error.
Usb(hidapi::HidError),
/// Device with request key is not available.
KeyNotFound,
/// Signing has been cancelled by user.
UserCancel,
}
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
match *self {
Error::Protocol(ref s) => write!(f, "Ledger protocol error: {}", s),
Error::Usb(ref e) => write!(f, "USB communication error: {}", e),
Error::KeyNotFound => write!(f, "Key not found"),
Error::UserCancel => write!(f, "Operation has been cancelled"),
}
}
}
impl From<hidapi::HidError> for Error {
fn from(err: hidapi::HidError) -> Error {
Error::Usb(err)
}
}
/// Ledger device manager.
pub struct Manager {
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
usb: Arc<Mutex<hidapi::HidApi>>,
devices: RwLock<Vec<Device>>,
key_path: RwLock<KeyPath>,
}
#[derive(Debug)]
struct Device {
path: String,
info: WalletInfo,
}
impl Manager {
/// Create a new instance.
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
pub fn new(hidapi: Arc<Mutex<hidapi::HidApi>>) -> Manager {
Manager {
usb: hidapi,
devices: RwLock::new(Vec::new()),
key_path: RwLock::new(KeyPath::Ethereum),
}
}
/// Re-populate device list. Only those devices that have Ethereum app open will be added.
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
pub fn update_devices(&self) -> Result<usize, Error> {
let mut usb = self.usb.lock();
usb.refresh_devices();
let devices = usb.devices();
let mut new_devices = Vec::new();
let mut num_new_devices = 0;
for device in devices {
trace!("Checking device: {:?}", device);
if device.vendor_id != LEDGER_VID || !LEDGER_PIDS.contains(&device.product_id) {
continue;
}
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
match self.read_device_info(&usb, &device) {
Ok(info) => {
debug!("Found device: {:?}", info);
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
if !self.devices.read().iter().any(|d| d.path == info.path) {
num_new_devices += 1;
}
new_devices.push(info);
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
}
Err(e) => debug!("Error reading device info: {}", e),
};
}
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
*self.devices.write() = new_devices;
Ok(num_new_devices)
}
/// Select key derivation path for a known chain.
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
pub fn set_key_path(&self, key_path: KeyPath) {
*self.key_path.write() = key_path;
}
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
fn read_device_info(&self, usb: &hidapi::HidApi, dev_info: &hidapi::HidDeviceInfo) -> Result<Device, Error> {
let mut handle = self.open_path(|| usb.open_path(&dev_info.path))?;
let address = Self::read_wallet_address(&mut handle, *self.key_path.read())?;
let manufacturer = dev_info.manufacturer_string.clone().unwrap_or("Unknown".to_owned());
let name = dev_info.product_string.clone().unwrap_or("Unknown".to_owned());
let serial = dev_info.serial_number.clone().unwrap_or("Unknown".to_owned());
Ok(Device {
path: dev_info.path.clone(),
info: WalletInfo {
name: name,
manufacturer: manufacturer,
serial: serial,
address: address,
},
})
}
fn read_wallet_address(handle: &hidapi::HidDevice, key_path: KeyPath) -> Result<Address, Error> {
let ver = Self::send_apdu(handle, commands::GET_APP_CONFIGURATION, 0, 0, &[])?;
if ver.len() != 4 {
return Err(Error::Protocol("Version packet size mismatch"));
}
let (major, minor, patch) = (ver[1], ver[2], ver[3]);
if major < 1 || (major == 1 && minor == 0 && patch < 3) {
return Err(Error::Protocol("App version 1.0.3 is required."));
}
let eth_path = &ETH_DERIVATION_PATH_BE[..];
let etc_path = &ETC_DERIVATION_PATH_BE[..];
let derivation_path = match key_path {
KeyPath::Ethereum => eth_path,
KeyPath::EthereumClassic => etc_path,
};
let key_and_address = Self::send_apdu(handle, commands::GET_ETH_PUBLIC_ADDRESS, 0, 0, derivation_path)?;
if key_and_address.len() != 107 { // 1 + 65 PK + 1 + 40 Addr (ascii-hex)
return Err(Error::Protocol("Key packet size mismatch"));
}
let address_string = ::std::str::from_utf8(&key_and_address[67..107])
.map_err(|_| Error::Protocol("Invalid address string"))?;
let address = Address::from_str(&address_string)
.map_err(|_| Error::Protocol("Invalid address string"))?;
Ok(address)
}
/// List connected wallets. This only returns wallets that are ready to be used.
pub fn list_devices(&self) -> Vec<WalletInfo> {
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
self.devices.read().iter().map(|d| d.info.clone()).collect()
}
/// Get wallet info.
pub fn device_info(&self, address: &Address) -> Option<WalletInfo> {
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
self.devices.read().iter().find(|d| &d.info.address == address).map(|d| d.info.clone())
}
/// Sign transaction data with wallet managing `address`.
pub fn sign_transaction(&self, address: &Address, data: &[u8]) -> Result<Signature, Error> {
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
let usb = self.usb.lock();
let devices = self.devices.read();
let device = devices.iter().find(|d| &d.info.address == address).ok_or(Error::KeyNotFound)?;
let handle = self.open_path(|| usb.open_path(&device.path))?;
let eth_path = &ETH_DERIVATION_PATH_BE[..];
let etc_path = &ETC_DERIVATION_PATH_BE[..];
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
let derivation_path = match *self.key_path.read() {
KeyPath::Ethereum => eth_path,
KeyPath::EthereumClassic => etc_path,
};
const MAX_CHUNK_SIZE: usize = 255;
let mut chunk: [u8; MAX_CHUNK_SIZE] = [0; MAX_CHUNK_SIZE];
&mut chunk[0..derivation_path.len()].copy_from_slice(derivation_path);
let mut dest_offset = derivation_path.len();
let mut data_pos = 0;
let mut result;
loop {
let p1 = if data_pos == 0 { 0x00 } else { 0x80 };
let dest_left = MAX_CHUNK_SIZE - dest_offset;
let chunk_data_size = min(dest_left, data.len() - data_pos);
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
&mut chunk[dest_offset..][0..chunk_data_size].copy_from_slice(&data[data_pos..][0..chunk_data_size]);
result = Self::send_apdu(&handle, commands::SIGN_ETH_TRANSACTION, p1, 0, &chunk[0..(dest_offset + chunk_data_size)])?;
dest_offset = 0;
data_pos += chunk_data_size;
if data_pos == data.len() {
break;
}
}
if result.len() != 65 {
return Err(Error::Protocol("Signature packet size mismatch"));
}
2017-02-16 17:45:12 +01:00
let v = (result[0] + 1) % 2;
let r = H256::from_slice(&result[1..33]);
let s = H256::from_slice(&result[33..65]);
Ok(Signature::from_rsv(&r, &s, v))
}
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
fn open_path<R, F>(&self, f: F) -> Result<R, Error>
where F: Fn() -> Result<R, &'static str>
{
let mut err = Error::KeyNotFound;
// Try to open device a few times.
for _ in 0..10 {
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
match f() {
Ok(handle) => return Ok(handle),
Err(e) => err = From::from(e),
}
::std::thread::sleep(Duration::from_millis(200));
}
Err(err)
}
fn send_apdu(handle: &hidapi::HidDevice, command: u8, p1: u8, p2: u8, data: &[u8]) -> Result<Vec<u8>, Error> {
const HID_PACKET_SIZE: usize = 64 + HID_PREFIX_ZERO;
let mut offset = 0;
let mut chunk_index = 0;
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
loop {
let mut hid_chunk: [u8; HID_PACKET_SIZE] = [0; HID_PACKET_SIZE];
let mut chunk_size = if chunk_index == 0 { 12 } else { 5 };
let size = min(64 - chunk_size, data.len() - offset);
{
let mut chunk = &mut hid_chunk[HID_PREFIX_ZERO..];
&mut chunk[0..5].copy_from_slice(&[0x01, 0x01, APDU_TAG, (chunk_index >> 8) as u8, (chunk_index & 0xff) as u8 ]);
if chunk_index == 0 {
let data_len = data.len() + 5;
&mut chunk[5..12].copy_from_slice(&[ (data_len >> 8) as u8, (data_len & 0xff) as u8, APDU_CLA, command, p1, p2, data.len() as u8 ]);
}
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
&mut chunk[chunk_size..chunk_size + size].copy_from_slice(&data[offset..offset + size]);
offset += size;
chunk_size += size;
}
trace!("writing {:?}", &hid_chunk[..]);
let n = handle.write(&hid_chunk[..])?;
if n < chunk_size {
return Err(Error::Protocol("Write data size mismatch"));
}
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
if offset == data.len() {
break;
}
chunk_index += 1;
}
// read response
chunk_index = 0;
let mut message_size = 0;
let mut message = Vec::new();
loop {
let mut chunk: [u8; HID_PACKET_SIZE] = [0; HID_PACKET_SIZE];
let chunk_size = handle.read(&mut chunk)?;
trace!("read {:?}", &chunk[..]);
2017-02-16 17:45:12 +01:00
if chunk_size < 5 || chunk[0] != 0x01 || chunk[1] != 0x01 || chunk[2] != APDU_TAG {
return Err(Error::Protocol("Unexpected chunk header"));
}
let seq = (chunk[3] as usize) << 8 | (chunk[4] as usize);
if seq != chunk_index {
return Err(Error::Protocol("Unexpected chunk header"));
}
let mut offset = 5;
if seq == 0 {
// read message size and status word.
if chunk_size < 7 {
return Err(Error::Protocol("Unexpected chunk header"));
}
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
message_size = (chunk[5] as usize) << 8 | (chunk[6] as usize);
offset += 2;
}
message.extend_from_slice(&chunk[offset..chunk_size]);
message.truncate(message_size);
if message.len() == message_size {
break;
}
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
chunk_index += 1;
}
if message.len() < 2 {
return Err(Error::Protocol("No status word"));
}
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
let status = (message[message.len() - 2] as usize) << 8 | (message[message.len() - 1] as usize);
debug!("Read status {:x}", status);
match status {
0x6700 => Err(Error::Protocol("Incorrect length")),
0x6982 => Err(Error::Protocol("Security status not satisfied (Canceled by user)")),
0x6a80 => Err(Error::Protocol("Invalid data")),
0x6a82 => Err(Error::Protocol("File not found")),
0x6a85 => Err(Error::UserCancel),
0x6b00 => Err(Error::Protocol("Incorrect parameters")),
0x6d00 => Err(Error::Protocol("Not implemented. Make sure Ethereum app is running.")),
0x6faa => Err(Error::Protocol("You Ledger need to be unplugged")),
0x6f00...0x6fff => Err(Error::Protocol("Internal error")),
0x9000 => Ok(()),
_ => Err(Error::Protocol("Unknown error")),
}?;
let new_len = message.len() - 2;
message.truncate(new_len);
Ok(message)
}
}
#[test]
fn smoke() {
use rustc_hex::FromHex;
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
let hidapi = Arc::new(Mutex::new(hidapi::HidApi::new().unwrap()));
let manager = Manager::new(hidapi.clone());
manager.update_devices().unwrap();
Trezor Support (#6403) * Copy modal from keepkey branch and generalize The keepkey PinMatrix modal needs to be the same for Trezor, but we should probably try to keep it general since it can be used for both. * Add trezor communication code This is a result of much trial-and-error and a couple of dead-ends in how to communicate and wire everything up. Code here is still a bit WIP with lots of debug prints and stuff. The test works though, it is possible to sign a transaction. * Extend the basic lib to allow Trezor This is kind of ugly and needs some cleanup and generalization. I’ve just copy-pasted some things to bring in the trezor wallets. I’ve also had to add a lock to the USB API so that only one thing talks to the USB at once. * Add RPC plumbing needed We need to be able to get “locked” devices from the frontend to figure out if we’re going to display the PinMatrix or not. Then we need to be able to send a pin to a device. * Add logic to query backend for Trezor and display PinMatrix There’s a bug somewhere here because signing a transaction fails if you take too long to press the confirm button on the device. * Change back to paritytech branch As my fork has been merged in. * Converting spaces to tabs, as it should be * Incorporate correct handling of EIP-155 Turns out the Trezor was adjusting the v part of the signature, and we’re already doing that so it was done twice. * Some circular logic here that was incorrect BE-encoded U256 is almost the same as RLP encoded without the size-byte, except for <u8 sized values. What’s really done is BE-encoded U256 and then left-trimmed to the smallest size. Kind of obvious in hindsight. * Resolve issue where not clicking fast enough fails The device will not repeat a ButtonRequest when you read from it, so you need to have a blocking `read` for whatever amount of time that you want to give the user to click. You could also have a shorter timeout but keep retrying for some amount of time, but it would amount to the same thing. * Scan after pin entry to make accepting it faster * Remove ability to cancel pin request * Some slight cleanup * Probe for the correct HID Version to determine padding * Move the PinMatrix from Accounts to Application * Removing unused dependencies * Mistake in copying over stuff from keepkey branch * Simplify FormattedMessage * Move generated code to external crate * Remove ethcore-util dependency * Fix broken import in test This test is useless without a connected Trezor, not sure how to make it useful without one. * Merge branch 'master' into fh-4500-trezor-support # Conflicts: # rpc/src/v1/helpers/dispatch.rs * Ignore test that can't be run without trezor device * Fixing grumbles * Avoiding owning data in RPC method * Checking for overflow in v part of signature * s/network_id/chain_id * Propagating an error from the HID Api * Condensing code a little bit * Fixing UI. * Debugging trezor. * Minor styling tweak * Make message type into an actual type This makes the message type that the RPC message accepts into an actual type as opposed to just a string, based on feedback. Although I’m not 100% sure this has actually improved the situation. Overall I think the hardware wallet interface needs some refactoring love. * Split the trezor RPC endpoint It’s split into two more generic endpoints that should be suitable for any hardware wallets with the same behavior to sit behind. * Reflect RPC method split in javascript * Fix bug with pin entry * Fix deadlock for Ledger * Avoid having a USB lock in just listing locked wallets * Fix javascript issue (see #6509) * Replace Mutex with RwLock * Update Ledger test * Fix typo causing faulty signatures (sometimes) * *Actually* fix tests * Update git submodule Needed to make tests pass * Swap line orders to prevent possible deadlock * Make setPinMatrixRequest an @action
2017-09-14 19:28:43 +02:00
for d in &*manager.devices.read() {
println!("Device: {:?}", d);
}
if let Some(address) = manager.list_devices().first().map(|d| d.address.clone()) {
let tx = FromHex::from_hex("eb018504a817c80082520894a6ca2e6707f2cc189794a9dd459d5b05ed1bcd1c8703f26fcfb7a22480018080").unwrap();
let signature = manager.sign_transaction(&address, &tx);
println!("Got {:?}", signature);
assert!(signature.is_ok());
let large_tx = FromHex::from_hex("f8cb81968504e3b2920083024f279475b02a3c39710d6a3f2870d0d788299d48e790f180b8a4b61d27f6000000000000000000000000e1af840a5a1cb1efdf608a97aa632f4aa39ed199000000000000000000000000000000000000000000000000105ff43f46a9a800000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018080").unwrap();
let signature = manager.sign_transaction(&address, &large_tx);
println!("Got {:?}", signature);
assert!(signature.is_ok());
let huge_tx = FromHex::from_hex("f935e98201048505d21dba00833b82608080b935946103e86003908155620d2f00600455601460055560a060405260608190527f2e2e2e00000000000000000000000000000000000000000000000000000000006080908152600d805460008290527f2e2e2e00000000000000000000000000000000000000000000000000000000068255909260008051602062003474833981519152602060026001851615610100026000190190941693909304601f0192909204820192909190620000dc565b82800160010185558215620000dc579182015b82811115620000dc578251825591602001919060010190620000bf565b5b50620001009291505b80821115620000fc5760008155600101620000e6565b5090565b5050600e8054600360ff199182168117909255604080518082019091528281527f2e2e2e00000000000000000000000000000000000000000000000000000000006020918201908152600f80546000829052825160069516949094178155937f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80260026101006001871615026000190190951694909404601f019290920483019290620001d7565b82800160010185558215620001d7579182015b82811115620001d7578251825591602001919060010190620001ba565b5b50620001fb9291505b80821115620000fc5760008155600101620000e6565b5090565b50506010805460ff19166001179055346200000057604051620034943803806200349483398101604090815281516020830151918301516060840151919390810191015b5b5b60068054600160a060020a0319166c01000000000000000000000000338102041790558151600d80546000829052909160008051602062003474833981519152602060026101006001861615026000190190941693909304601f908101849004820193870190839010620002c157805160ff1916838001178555620002f1565b82800160010185558215620002f1579182015b82811115620002f1578251825591602001919060010190620002d4565b5b50620003159291505b80821115620000fc5760008155600101620000e6565b5090565b505080600f9080519060200190828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200036557805160ff191683800117855562000395565b8280016001018555821562000395579182015b828111156200039557825182559160200191906001019062000378565b5b50620003b99291505b80821115620000fc5760008155600101620000e6565b5090565b5050600980546c01000000000000000000000000808602819004600160a060020a0319928316179092556007805487840293909304929091169190911790555b505050505b613066806200040e6000396000f300606060405236156102035760e060020a600035046306fdde03811461034b578063095ea7b3146103c65780630b0b6d5b146103ed5780631b1ccc47146103fc57806320e870931461047757806323b872dd1461049657806325b29d84146104c057806327187991146104df578063277ccde2146104f15780632e1fbfcd14610510578063308b2fdc14610532578063313ce5671461055457806338cc48311461057757806340eddc4e146105a057806341f4793a146105bf578063467ed261146105de578063471ad963146105fd5780634e860ebb1461060f5780634efbe9331461061e57806354786b4e1461064257806354e35ba2146106bd57806358793ad4146106d25780635abedab21461073f5780635af2f8211461074e57806360483a3f1461076d57806360d12fa0146107da578063698f2e84146108035780636a749986146108155780636d5f66391461082a5780636e9c36831461083c57806370a082311461085e5780637a290fe5146108805780637e7541461461088f57806394c41bdb1461090a57806395d89b4114610929578063962a64cd146109a4578063a0b6533214610a09578063a9059cbb14610a2b578063ab62438f14610a52578063b63ca98114610aa9578063b7c54c6f14610abb578063c4e41b2214610ada578063ca7c4dba14610af9578063cb79e31b14610b18578063dd62ed3e14610b3a575b6103495b60006000600c546000141561021b57610000565b600354600c54670de0b6b3a764000091349091020204915060009050816001600030600160a060020a031681526020019081526020016000205410156102c557600160a060020a033016600090815260016020526040902054600c54909250828115610000570466038d7ea4c68000023403905033600160a060020a03166108fc829081150290604051809050600060405180830381858888f1935050505015156102c557610000565b5b600160a060020a03338116600081815260016020908152604080832080548801905530909416825283822080548790039055601380543487900301908190559154600c548551908152918201879052845190949293927f5a0391f2a67f11ed0034b68f8cf14e7e41d6f86e0a7622f2af5ea8f07b488396928290030190a45b5050565b005b3461000057610358610b5f565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156103b85780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34610000
let signature = manager.sign_transaction(&address, &huge_tx);
println!("Got {:?}", signature);
assert!(signature.is_ok());
}
}