Merge pull request #7793
13a8a57
trezor: try empty passphrase first (Dusan Klinec)
This commit is contained in:
commit
7f477c1902
@ -162,6 +162,26 @@ namespace hw {
|
||||
* Live refresh process termination
|
||||
*/
|
||||
virtual void live_refresh_finish() =0;
|
||||
|
||||
/**
|
||||
* Requests public address, uses empty passphrase if asked for.
|
||||
*/
|
||||
virtual bool get_public_address_with_no_passphrase(cryptonote::account_public_address &pubkey) =0;
|
||||
|
||||
/**
|
||||
* Reset session ID, restart with a new session.
|
||||
*/
|
||||
virtual void reset_session() =0;
|
||||
|
||||
/**
|
||||
* Returns true if device already asked for passphrase entry before (i.e., obviously supports passphrase entry)
|
||||
*/
|
||||
virtual bool seen_passphrase_entry_prompt() =0;
|
||||
|
||||
/**
|
||||
* Uses empty passphrase for all passphrase queries.
|
||||
*/
|
||||
virtual void set_use_empty_passphrase(bool always_use_empty_passphrase) =0;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -178,6 +178,15 @@ namespace trezor {
|
||||
}
|
||||
}
|
||||
|
||||
bool device_trezor::get_public_address_with_no_passphrase(cryptonote::account_public_address &pubkey) {
|
||||
m_reply_with_empty_passphrase = true;
|
||||
const auto empty_passphrase_reverter = epee::misc_utils::create_scope_leave_handler([&]() {
|
||||
m_reply_with_empty_passphrase = false;
|
||||
});
|
||||
|
||||
return get_public_address(pubkey);
|
||||
}
|
||||
|
||||
bool device_trezor::get_secret_keys(crypto::secret_key &viewkey , crypto::secret_key &spendkey) {
|
||||
try {
|
||||
MDEBUG("Loading view-only key from the Trezor. Please check the Trezor for a confirmation.");
|
||||
@ -206,6 +215,18 @@ namespace trezor {
|
||||
get_address(index, payment_id, true);
|
||||
}
|
||||
|
||||
void device_trezor::reset_session() {
|
||||
m_device_session_id.clear();
|
||||
}
|
||||
|
||||
bool device_trezor::seen_passphrase_entry_prompt() {
|
||||
return m_seen_passphrase_entry_message;
|
||||
}
|
||||
|
||||
void device_trezor::set_use_empty_passphrase(bool always_use_empty_passphrase) {
|
||||
m_always_use_empty_passphrase = always_use_empty_passphrase;
|
||||
}
|
||||
|
||||
/* ======================================================================= */
|
||||
/* Helpers */
|
||||
/* ======================================================================= */
|
||||
|
@ -205,6 +205,26 @@ namespace trezor {
|
||||
const ::tools::wallet2::unsigned_tx_set & unsigned_tx,
|
||||
::tools::wallet2::signed_tx_set & signed_tx,
|
||||
hw::tx_aux_data & aux_data) override;
|
||||
|
||||
/**
|
||||
* Requests public address, uses empty passphrase if asked for.
|
||||
*/
|
||||
bool get_public_address_with_no_passphrase(cryptonote::account_public_address &pubkey) override;
|
||||
|
||||
/**
|
||||
* Reset session ID, restart with a new session.
|
||||
*/
|
||||
virtual void reset_session() override;
|
||||
|
||||
/**
|
||||
* Returns true if device already asked for passphrase entry before (i.e., obviously supports passphrase entry)
|
||||
*/
|
||||
bool seen_passphrase_entry_prompt() override;
|
||||
|
||||
/**
|
||||
* Uses empty passphrase for all passphrase queries.
|
||||
*/
|
||||
void set_use_empty_passphrase(bool use_always_empty_passphrase) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -45,7 +45,10 @@ namespace trezor {
|
||||
|
||||
const uint32_t device_trezor_base::DEFAULT_BIP44_PATH[] = {0x8000002c, 0x80000080};
|
||||
|
||||
device_trezor_base::device_trezor_base(): m_callback(nullptr), m_last_msg_type(messages::MessageType_Success) {
|
||||
device_trezor_base::device_trezor_base(): m_callback(nullptr), m_last_msg_type(messages::MessageType_Success),
|
||||
m_reply_with_empty_passphrase(false),
|
||||
m_always_use_empty_passphrase(false),
|
||||
m_seen_passphrase_entry_message(false) {
|
||||
#ifdef WITH_TREZOR_DEBUGGING
|
||||
m_debug = false;
|
||||
#endif
|
||||
@ -155,6 +158,9 @@ namespace trezor {
|
||||
TREZOR_AUTO_LOCK_DEVICE();
|
||||
m_device_session_id.clear();
|
||||
m_features.reset();
|
||||
m_seen_passphrase_entry_message = false;
|
||||
m_reply_with_empty_passphrase = false;
|
||||
m_always_use_empty_passphrase = false;
|
||||
|
||||
if (m_transport){
|
||||
try {
|
||||
@ -476,6 +482,7 @@ namespace trezor {
|
||||
return;
|
||||
}
|
||||
|
||||
m_seen_passphrase_entry_message = true;
|
||||
bool on_device = true;
|
||||
if (msg->has__on_device() && !msg->_on_device()){
|
||||
on_device = false; // do not enter on device, old devices.
|
||||
@ -491,19 +498,21 @@ namespace trezor {
|
||||
}
|
||||
|
||||
boost::optional<epee::wipeable_string> passphrase;
|
||||
TREZOR_CALLBACK_GET(passphrase, on_passphrase_request, on_device);
|
||||
if (m_reply_with_empty_passphrase || m_always_use_empty_passphrase) {
|
||||
MDEBUG("Answering passphrase prompt with an empty passphrase, always use empty: " << m_always_use_empty_passphrase);
|
||||
on_device = false;
|
||||
passphrase = epee::wipeable_string("");
|
||||
} else if (m_passphrase){
|
||||
MWARNING("Answering passphrase prompt with a stored passphrase (do not use; passphrase can be seen by a potential malware / attacker)");
|
||||
on_device = false;
|
||||
passphrase = epee::wipeable_string(m_passphrase.get());
|
||||
} else {
|
||||
TREZOR_CALLBACK_GET(passphrase, on_passphrase_request, on_device);
|
||||
}
|
||||
|
||||
messages::common::PassphraseAck m;
|
||||
m.set_on_device(on_device);
|
||||
if (!on_device) {
|
||||
if (!passphrase && m_passphrase) {
|
||||
passphrase = m_passphrase;
|
||||
}
|
||||
|
||||
if (m_passphrase) {
|
||||
m_passphrase = boost::none;
|
||||
}
|
||||
|
||||
if (passphrase) {
|
||||
m.set_allocated_passphrase(new std::string(passphrase->data(), passphrase->size()));
|
||||
}
|
||||
|
@ -101,6 +101,9 @@ namespace trezor {
|
||||
messages::MessageType m_last_msg_type;
|
||||
|
||||
cryptonote::network_type network_type;
|
||||
bool m_reply_with_empty_passphrase;
|
||||
bool m_always_use_empty_passphrase;
|
||||
bool m_seen_passphrase_entry_message;
|
||||
|
||||
#ifdef WITH_TREZOR_DEBUGGING
|
||||
std::shared_ptr<trezor_debug_callback> m_debug_callback;
|
||||
|
@ -4467,7 +4467,26 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
|
||||
m_account.set_device(hwdev);
|
||||
|
||||
account_public_address device_account_public_address;
|
||||
THROW_WALLET_EXCEPTION_IF(!hwdev.get_public_address(device_account_public_address), error::wallet_internal_error, "Cannot get a device address");
|
||||
bool fetch_device_address = true;
|
||||
|
||||
::hw::device_cold* dev_cold = nullptr;
|
||||
if (m_key_device_type == hw::device::device_type::TREZOR && (dev_cold = dynamic_cast<::hw::device_cold*>(&hwdev)) != nullptr) {
|
||||
THROW_WALLET_EXCEPTION_IF(!dev_cold->get_public_address_with_no_passphrase(device_account_public_address), error::wallet_internal_error, "Cannot get a device address");
|
||||
if (device_account_public_address == m_account.get_keys().m_account_address) {
|
||||
LOG_PRINT_L0("Wallet opened with an empty passphrase");
|
||||
fetch_device_address = false;
|
||||
dev_cold->set_use_empty_passphrase(true);
|
||||
} else {
|
||||
fetch_device_address = true;
|
||||
LOG_PRINT_L0("Wallet opening with an empty passphrase failed. Retry again: " << fetch_device_address);
|
||||
dev_cold->reset_session();
|
||||
}
|
||||
}
|
||||
|
||||
if (fetch_device_address) {
|
||||
THROW_WALLET_EXCEPTION_IF(!hwdev.get_public_address(device_account_public_address), error::wallet_internal_error, "Cannot get a device address");
|
||||
}
|
||||
|
||||
THROW_WALLET_EXCEPTION_IF(device_account_public_address != m_account.get_keys().m_account_address, error::wallet_internal_error, "Device wallet does not match wallet address. If the device uses the passphrase feature, please check whether the passphrase was entered correctly (it may have been misspelled - different passphrases generate different wallets, passphrase is case-sensitive). "
|
||||
"Device address: " + cryptonote::get_account_address_as_str(m_nettype, false, device_account_public_address) +
|
||||
", wallet address: " + m_account.get_public_address_str(m_nettype));
|
||||
|
Loading…
Reference in New Issue
Block a user