Merge pull request #7793

13a8a57 trezor: try empty passphrase first (Dusan Klinec)
This commit is contained in:
luigi1111 2021-10-11 12:54:17 -05:00
commit 7f477c1902
No known key found for this signature in database
GPG key ID: F4ACA0183641E010
6 changed files with 103 additions and 11 deletions

View file

@ -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;
};
}

View file

@ -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 */
/* ======================================================================= */

View file

@ -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

View file

@ -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()));
}

View file

@ -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;

View file

@ -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));