diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptonote_config.h | 3 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 2 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.cpp | 5 | ||||
-rw-r--r-- | src/daemon/command_line_args.h | 6 | ||||
-rw-r--r-- | src/device/device.hpp | 37 | ||||
-rw-r--r-- | src/device/device_default.cpp | 30 | ||||
-rw-r--r-- | src/device/device_default.hpp | 13 | ||||
-rw-r--r-- | src/device/device_ledger.cpp | 710 | ||||
-rw-r--r-- | src/device/device_ledger.hpp | 47 | ||||
-rw-r--r-- | src/device/log.cpp | 10 | ||||
-rw-r--r-- | src/p2p/net_node.cpp | 2 | ||||
-rw-r--r-- | src/p2p/net_node.inl | 6 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.cpp | 2 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.h | 2 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 23 | ||||
-rw-r--r-- | src/wallet/api/wallet.cpp | 2 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 140 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 2 |
18 files changed, 528 insertions, 514 deletions
diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index 0ad8a6005..3e64073dd 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -200,6 +200,7 @@ namespace cryptonote MAINNET = 0, TESTNET, STAGENET, - FAKECHAIN + FAKECHAIN, + UNDEFINED = 255 }; } diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 3db516847..f02a1f8d6 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -4365,7 +4365,7 @@ void Blockchain::cancel() } #if defined(PER_BLOCK_CHECKPOINT) -static const char expected_block_hashes_hash[] = "4b553162ee4e7af3c53666506591489c68560b9175e6e941dc96c89f96f0e35c"; +static const char expected_block_hashes_hash[] = "1d3df1a177bd6f752d87c0d7b960e502605742721afb39953265f1e0f7f9b01f"; void Blockchain::load_compiled_in_block_hashes() { const bool testnet = m_nettype == TESTNET; diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index adccd0469..4d852fc99 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -81,7 +81,7 @@ namespace cryptonote , "Specify data directory" , tools::get_default_data_dir() , {{ &arg_testnet_on, &arg_stagenet_on }} - , [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val) { + , [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val)->std::string { if (testnet_stagenet[0]) return (boost::filesystem::path(val) / "testnet").string(); else if (testnet_stagenet[1]) @@ -171,7 +171,8 @@ namespace cryptonote m_last_json_checkpoints_update(0), m_disable_dns_checkpoints(false), m_threadpool(tools::threadpool::getInstance()), - m_update_download(0) + m_update_download(0), + m_nettype(UNDEFINED) { m_checkpoints_updating.clear(); set_cryptonote_protocol(pprotocol); diff --git a/src/daemon/command_line_args.h b/src/daemon/command_line_args.h index add752029..4673590aa 100644 --- a/src/daemon/command_line_args.h +++ b/src/daemon/command_line_args.h @@ -42,7 +42,7 @@ namespace daemon_args , "Specify configuration file" , (daemonizer::get_default_data_dir() / std::string(CRYPTONOTE_NAME ".conf")).string() , {{ &cryptonote::arg_testnet_on, &cryptonote::arg_stagenet_on }} - , [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val) { + , [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val)->std::string { if (testnet_stagenet[0] && defaulted) return (daemonizer::get_default_data_dir() / "testnet" / std::string(CRYPTONOTE_NAME ".conf")).string(); @@ -57,7 +57,7 @@ namespace daemon_args , "Specify log file" , (daemonizer::get_default_data_dir() / std::string(CRYPTONOTE_NAME ".log")).string() , {{ &cryptonote::arg_testnet_on, &cryptonote::arg_stagenet_on }} - , [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val) { + , [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val)->std::string { if (testnet_stagenet[0] && defaulted) return (daemonizer::get_default_data_dir() / "testnet" / std::string(CRYPTONOTE_NAME ".log")).string(); @@ -102,7 +102,7 @@ namespace daemon_args , "Port for ZMQ RPC server to listen on" , std::to_string(config::ZMQ_RPC_DEFAULT_PORT) , {{ &cryptonote::arg_testnet_on, &cryptonote::arg_stagenet_on }} - , [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val) { + , [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val)->std::string { if (testnet_stagenet[0] && defaulted) return std::to_string(config::testnet::ZMQ_RPC_DEFAULT_PORT); if (testnet_stagenet[1] && defaulted) diff --git a/src/device/device.hpp b/src/device/device.hpp index b47460472..9df0cb39d 100644 --- a/src/device/device.hpp +++ b/src/device/device.hpp @@ -80,6 +80,9 @@ namespace hw { class device { + protected: + std::string name; + public: device() {} @@ -87,12 +90,12 @@ namespace hw { virtual ~device() {} explicit virtual operator bool() const = 0; - - static const int SIGNATURE_REAL = 0; - static const int SIGNATURE_FAKE = 1; - - - std::string name; + enum device_mode { + NONE, + TRANSACTION_CREATE_REAL, + TRANSACTION_CREATE_FAKE, + TRANSACTION_PARSE + }; /* ======================================================================= */ /* SETUP/TEARDOWN */ @@ -104,7 +107,18 @@ namespace hw { virtual bool release() = 0; virtual bool connect(void) = 0; - virtual bool disconnect() = 0; + virtual bool disconnect(void) = 0; + + virtual bool set_mode(device_mode mode) = 0; + + + /* ======================================================================= */ + /* LOCKER */ + /* ======================================================================= */ + virtual void lock(void) = 0; + virtual void unlock(void) = 0; + virtual bool try_lock(void) = 0; + /* ======================================================================= */ /* WALLET & ADDRESS */ @@ -131,6 +145,7 @@ namespace hw { virtual bool sc_secret_add( crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) = 0; virtual crypto::secret_key generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false) = 0; virtual bool generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) = 0; + virtual bool conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations) = 0; virtual bool derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) = 0; virtual bool derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &sec, crypto::secret_key &derived_sec) = 0; virtual bool derive_public_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::public_key &pub, crypto::public_key &derived_pub) = 0; @@ -158,8 +173,6 @@ namespace hw { virtual bool open_tx(crypto::secret_key &tx_key) = 0; - virtual bool set_signature_mode(unsigned int sig_mode) = 0; - virtual bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) = 0; bool decrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) { @@ -183,6 +196,12 @@ namespace hw { virtual bool close_tx(void) = 0; } ; + struct reset_mode { + device& hwref; + reset_mode(hw::device& dev) : hwref(dev) { } + ~reset_mode() { hwref.set_mode(hw::device::NONE);} + }; + device& get_device(const std::string device_descriptor) ; } diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp index d63dafe9e..0071f7d4f 100644 --- a/src/device/device_default.cpp +++ b/src/device/device_default.cpp @@ -31,6 +31,7 @@ #include "device_default.hpp" +#include "common/int-util.h" #include "cryptonote_basic/account.h" #include "cryptonote_basic/subaddress_index.h" #include "ringct/rctOps.h" @@ -81,6 +82,20 @@ namespace hw { dfns(); } + bool device_default::set_mode(device_mode mode) { + return true; + } + + /* ======================================================================= */ + /* LOCKER */ + /* ======================================================================= */ + + void device_default::lock() { } + + bool device_default::try_lock() { return true; } + + void device_default::unlock() { } + /* ======================================================================= */ /* WALLET & ADDRESS */ /* ======================================================================= */ @@ -181,10 +196,13 @@ namespace hw { crypto::secret_key device_default::get_subaddress_secret_key(const crypto::secret_key &a, const cryptonote::subaddress_index &index) { const char prefix[] = "SubAddr"; - char data[sizeof(prefix) + sizeof(crypto::secret_key) + sizeof(cryptonote::subaddress_index)]; + char data[sizeof(prefix) + sizeof(crypto::secret_key) + 2 * sizeof(uint32_t)]; memcpy(data, prefix, sizeof(prefix)); memcpy(data + sizeof(prefix), &a, sizeof(crypto::secret_key)); - memcpy(data + sizeof(prefix) + sizeof(crypto::secret_key), &index, sizeof(cryptonote::subaddress_index)); + uint32_t idx = SWAP32LE(index.major); + memcpy(data + sizeof(prefix) + sizeof(crypto::secret_key), &idx, sizeof(uint32_t)); + idx = SWAP32LE(index.minor); + memcpy(data + sizeof(prefix) + sizeof(crypto::secret_key) + sizeof(uint32_t), &idx, sizeof(uint32_t)); crypto::secret_key m; crypto::hash_to_scalar(data, sizeof(data), m); return m; @@ -246,6 +264,10 @@ namespace hw { return true; } + bool device_default::conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations){ + return true; + } + /* ======================================================================= */ /* TRANSACTION */ /* ======================================================================= */ @@ -262,10 +284,6 @@ namespace hw { return true; } - bool device_default::set_signature_mode(unsigned int sig_mode) { - return true; - } - bool device_default::encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) { crypto::key_derivation derivation; crypto::hash hash; diff --git a/src/device/device_default.hpp b/src/device/device_default.hpp index 02faeba0c..649fed862 100644 --- a/src/device/device_default.hpp +++ b/src/device/device_default.hpp @@ -58,8 +58,17 @@ namespace hw { bool connect(void) override; bool disconnect() override; + + bool set_mode(device_mode mode) override; /* ======================================================================= */ + /* LOCKER */ + /* ======================================================================= */ + void lock(void) override; + void unlock(void) override; + bool try_lock(void) override; + + /* ======================================================================= */ /* WALLET & ADDRESS */ /* ======================================================================= */ bool get_public_address(cryptonote::account_public_address &pubkey) override; @@ -84,6 +93,7 @@ namespace hw { bool sc_secret_add(crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) override; crypto::secret_key generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false) override; bool generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) override; + bool conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations); bool derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) override; bool derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &sec, crypto::secret_key &derived_sec) override; bool derive_public_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::public_key &pub, crypto::public_key &derived_pub) override; @@ -97,9 +107,6 @@ namespace hw { bool open_tx(crypto::secret_key &tx_key) override; - //bool get_additional_key(const bool subaddr, cryptonote::keypair &additional_txkey) override; - bool set_signature_mode(unsigned int sig_mode) override; - bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override; bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) override; diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index b3c0035a1..3b9ab6744 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -33,7 +33,8 @@ #include "cryptonote_basic/account.h" #include "cryptonote_basic/subaddress_index.h" - +#include <boost/thread/locks.hpp> +#include <boost/thread/lock_guard.hpp> namespace hw { @@ -55,10 +56,11 @@ namespace hw { #define ASSERT_RV(rv) CHECK_AND_ASSERT_THROW_MES((rv)==SCARD_S_SUCCESS, "Fail SCard API : (" << (rv) << ") "<< pcsc_stringify_error(rv)<<" Device="<<this->id<<", hCard="<<hCard<<", hContext="<<hContext); #define ASSERT_SW(sw,ok,msk) CHECK_AND_ASSERT_THROW_MES(((sw)&(mask))==(ok), "Wrong Device Status : SW=" << std::hex << (sw) << " (EXPECT=" << std::hex << (ok) << ", MASK=" << std::hex << (mask) << ")") ; #define ASSERT_T0(exp) CHECK_AND_ASSERT_THROW_MES(exp, "Protocol assert failure: "#exp ) ; + #define ASSERT_X(exp,msg) CHECK_AND_ASSERT_THROW_MES(exp, msg); #ifdef DEBUG_HWDEVICE - crypto::secret_key viewkey; - crypto::secret_key spendkey; + crypto::secret_key dbg_viewkey; + crypto::secret_key dbg_spendkey; #endif /* ===================================================================== */ @@ -118,7 +120,18 @@ namespace hw { #endif /* ===================================================================== */ - /* === Device ==== */ + /* === Internal Helpers ==== */ + /* ===================================================================== */ + static bool is_fake_view_key(const crypto::secret_key &sec) { + return sec == crypto::null_skey; + } + + bool operator==(const crypto::key_derivation &d0, const crypto::key_derivation &d1) { + return !memcmp(&d0, &d1, sizeof(d0)); + } + + /* ===================================================================== */ + /* === Device ==== */ /* ===================================================================== */ static int device_id = 0; @@ -196,6 +209,8 @@ namespace hw { this->hCard = 0; this->hContext = 0; this->reset_buffer(); + this->mode = NONE; + this->has_view_key = false; MDEBUG( "Device "<<this->id <<" Created"); } @@ -204,14 +219,51 @@ namespace hw { MDEBUG( "Device "<<this->id <<" Destroyed"); } + /* ======================================================================= */ + /* LOCKER */ + /* ======================================================================= */ + + //automatic lock one more level on device ensuring the current thread is allowed to use it + #define AUTO_LOCK_CMD() \ + /* lock both mutexes without deadlock*/ \ + boost::lock(device_locker, command_locker); \ + /* make sure both already-locked mutexes are unlocked at the end of scope */ \ + boost::lock_guard<boost::recursive_mutex> lock1(device_locker, boost::adopt_lock); \ + boost::lock_guard<boost::mutex> lock2(command_locker, boost::adopt_lock) + + //lock the device for a long sequence + void device_ledger::lock(void) { + MDEBUG( "Ask for LOCKING for device "<<this->name << " in thread "); + device_locker.lock(); + MDEBUG( "Device "<<this->name << " LOCKed"); + } + + //lock the device for a long sequence + bool device_ledger::try_lock(void) { + MDEBUG( "Ask for LOCKING(try) for device "<<this->name << " in thread "); + bool r = device_locker.try_lock(); + if (r) { + MDEBUG( "Device "<<this->name << " LOCKed(try)"); + } else { + MDEBUG( "Device "<<this->name << " not LOCKed(try)"); + } + return r; + } + + //lock the device for a long sequence + void device_ledger::unlock(void) { + try { + MDEBUG( "Ask for UNLOCKING for device "<<this->name << " in thread "); + } catch (...) { + } + device_locker.unlock(); + MDEBUG( "Device "<<this->name << " UNLOCKed"); + } /* ======================================================================= */ /* MISC */ /* ======================================================================= */ bool device_ledger::reset() { - - lock_device(); - try { int offset; reset_buffer(); @@ -227,12 +279,7 @@ namespace hw { this->buffer_send[4] = offset-5; this->length_send = offset; this->exchange(); - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } unsigned int device_ledger::exchange(unsigned int ok, unsigned int mask) { @@ -261,30 +308,6 @@ namespace hw { memset(this->buffer_recv, 0, BUFFER_RECV_SIZE); } - void device_ledger::lock_device() { - MDEBUG( "Ask for LOCKING for device "<<this->id); - device_locker.lock(); - MDEBUG( "Device "<<this->id << " LOCKed"); - } - void device_ledger::unlock_device() { - try { - MDEBUG( "Ask for UNLOCKING for device "<<this->id); - } catch (...) { - } - device_locker.unlock(); - MDEBUG( "Device "<<this->id << " UNLOCKed"); - } - void device_ledger::lock_tx() { - MDEBUG( "Ask for LOCKING for TX "<<this->id); - //tx_locker.lock(); - MDEBUG( "TX "<<this->id << " LOCKed"); - } - void device_ledger::unlock_tx() { - MDEBUG( "Ask for UNLOCKING for TX "<<this->id); - //tx_locker.unlock(); - MDEBUG( "TX "<<this->id << " UNLOCKed"); - } - /* ======================================================================= */ /* SETUP/TEARDOWN */ /* ======================================================================= */ @@ -394,10 +417,10 @@ namespace hw { #ifdef DEBUG_HWDEVICE cryptonote::account_public_address pubkey; this->get_public_address(pubkey); + #endif crypto::secret_key vkey; crypto::secret_key skey; this->get_secret_keys(vkey,skey); - #endif return rv==SCARD_S_SUCCESS; } @@ -411,16 +434,55 @@ namespace hw { return true; } + bool device_ledger::set_mode(device_mode mode) { + AUTO_LOCK_CMD(); + + int offset; + + reset_buffer(); + + switch(mode) { + case TRANSACTION_CREATE_REAL: + case TRANSACTION_CREATE_FAKE: + this->buffer_send[0] = 0x00; + this->buffer_send[1] = INS_SET_SIGNATURE_MODE; + this->buffer_send[2] = 0x01; + this->buffer_send[3] = 0x00; + this->buffer_send[4] = 0x00; + offset = 5; + //options + this->buffer_send[offset] = 0x00; + offset += 1; + //account + this->buffer_send[offset] = mode; + offset += 1; + + this->buffer_send[4] = offset-5; + this->length_send = offset; + this->exchange(); + + this->mode = mode; + break; + + case TRANSACTION_PARSE: + case NONE: + this->mode = mode; + break; + default: + CHECK_AND_ASSERT_THROW_MES(false, " device_ledger::set_mode(unsigned int mode): invalid mode: "<<mode); + } + MDEBUG("Switch to mode: " <<mode); + return true; + } + /* ======================================================================= */ /* WALLET & ADDRESS */ /* ======================================================================= */ - /* Application API */ bool device_ledger::get_public_address(cryptonote::account_public_address &pubkey){ + AUTO_LOCK_CMD(); - lock_device(); - try { int offset; reset_buffer(); @@ -440,21 +502,17 @@ namespace hw { memmove(pubkey.m_view_public_key.data, this->buffer_recv, 32); memmove(pubkey.m_spend_public_key.data, this->buffer_recv+32, 32); - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + + return true; } - bool device_ledger::get_secret_keys(crypto::secret_key &viewkey , crypto::secret_key &spendkey) { - memset(viewkey.data, 0x00, 32); - memset(spendkey.data, 0xFF, 32); + bool device_ledger::get_secret_keys(crypto::secret_key &vkey , crypto::secret_key &skey) { + AUTO_LOCK_CMD(); + + //secret key are represented as fake key on the wallet side + memset(vkey.data, 0x00, 32); + memset(skey.data, 0xFF, 32); - #ifdef DEBUG_HWDEVICE - lock_device(); - try { //spcialkey, normal conf handled in decrypt int offset; reset_buffer(); @@ -473,21 +531,26 @@ namespace hw { this->length_send = offset; this->exchange(); - //clear key - memmove(ledger::viewkey.data, this->buffer_recv+64, 32); - memmove(ledger::spendkey.data, this->buffer_recv+96, 32); - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - #endif - return true; + //View key is retrievied, if allowed, to speed up blockchain parsing + memmove(this->viewkey.data, this->buffer_recv+0, 32); + if (is_fake_view_key(this->viewkey)) { + MDEBUG("Have Not view key"); + this->has_view_key = false; + } else { + MDEBUG("Have view key"); + this->has_view_key = true; + } + + #ifdef DEBUG_HWDEVICE + memmove(dbg_viewkey.data, this->buffer_recv+0, 32); + memmove(dbg_spendkey.data, this->buffer_recv+32, 32); + #endif + + return true; } bool device_ledger::generate_chacha_key(const cryptonote::account_keys &keys, crypto::chacha_key &key) { - lock_device(); - try { + AUTO_LOCK_CMD(); int offset; #ifdef DEBUG_HWDEVICE @@ -519,11 +582,6 @@ namespace hw { hw::ledger::check32("generate_chacha_key_prehashed", "key", (char*)key_x.data(), (char*)key.data()); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } return true; } @@ -532,15 +590,15 @@ namespace hw { /* ======================================================================= */ bool device_ledger::derive_subaddress_public_key(const crypto::public_key &pub, const crypto::key_derivation &derivation, const std::size_t output_index, crypto::public_key &derived_pub){ - - lock_device(); - try { - int offset =0; - unsigned char options = 0; - + AUTO_LOCK_CMD(); #ifdef DEBUG_HWDEVICE const crypto::public_key pub_x = pub; - const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation); + crypto::key_derivation derivation_x; + if ((this->mode == TRANSACTION_PARSE) && has_view_key) { + derivation_x = derivation; + } else { + derivation_x = hw::ledger::decrypt(derivation); + } const std::size_t output_index_x = output_index; crypto::public_key derived_pub_x; hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] pub ", pub_x.data, 32); @@ -550,10 +608,17 @@ namespace hw { hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[OUT]] derived_pub", derived_pub_x.data, 32); #endif + if ((this->mode == TRANSACTION_PARSE) && has_view_key) { + //If we are in TRANSACTION_PARSE, the given derivation has been retrieved uncrypted (wihtout the help + //of the device), so continue that way. + MDEBUG( "derive_subaddress_public_key : PARSE mode with known viewkey"); + crypto::derive_subaddress_public_key(pub, derivation, output_index,derived_pub); + } else { + + int offset =0; + reset_buffer(); - options = 0; - this->buffer_send[0] = 0x00; this->buffer_send[1] = INS_DERIVE_SUBADDRESS_PUBLIC_KEY; this->buffer_send[2] = 0x00; @@ -561,7 +626,7 @@ namespace hw { this->buffer_send[4] = 0x00; offset = 5; //options - this->buffer_send[offset] = options; + this->buffer_send[offset] = 0; offset += 1; //pub memmove(this->buffer_send+offset, pub.data, 32); @@ -582,34 +647,27 @@ namespace hw { //pub key memmove(derived_pub.data, &this->buffer_recv[0], 32); - - #ifdef DEBUG_HWDEVICE - hw::ledger::check32("derive_subaddress_public_key", "derived_pub", derived_pub_x.data, derived_pub.data); - #endif - - unlock_device(); - }catch (...) { - unlock_device(); - throw; } + #ifdef DEBUG_HWDEVICE + hw::ledger::check32("derive_subaddress_public_key", "derived_pub", derived_pub_x.data, derived_pub.data); + #endif + return true; } crypto::public_key device_ledger::get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) { - crypto::public_key D; - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + crypto::public_key D; + int offset; #ifdef DEBUG_HWDEVICE const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys); const cryptonote::subaddress_index index_x = index; crypto::public_key D_x; - hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data,32); - hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_spend_secret_key", keys_x.m_spend_secret_key.data,32); + hw::ledger::log_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data,32); + hw::ledger::log_hexbuffer("get_subaddress_spend_public_key: [[IN]] keys.m_spend_secret_key", keys_x.m_spend_secret_key.data,32); hw::ledger::log_message ("get_subaddress_spend_public_key: [[IN]] index ", std::to_string(index_x.major)+"."+std::to_string(index_x.minor)); - this->controle_device->get_subaddress_spend_public_key(keys_x, index_x, D_x); + D_x = this->controle_device->get_subaddress_spend_public_key(keys_x, index_x); hw::ledger::log_hexbuffer("get_subaddress_spend_public_key: [[OUT]] derivation ", D_x.data, 32); #endif @@ -644,12 +702,7 @@ namespace hw { hw::ledger::check32("get_subaddress_spend_public_key", "D", D_x.data, D.data); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return D; + return D; } std::vector<crypto::public_key> device_ledger::get_subaddress_spend_public_keys(const cryptonote::account_keys &keys, uint32_t account, uint32_t begin, uint32_t end) { @@ -665,24 +718,22 @@ namespace hw { } cryptonote::account_public_address device_ledger::get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) { - cryptonote::account_public_address address; - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + cryptonote::account_public_address address; + int offset; #ifdef DEBUG_HWDEVICE const cryptonote::account_keys keys_x = hw::ledger::decrypt(keys); const cryptonote::subaddress_index index_x = index; cryptonote::account_public_address address_x; - hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32); - hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_public_key", keys_x.m_account_address.m_view_public_key.data, 32); - hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32); - hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_spend_public_key", keys_x.m_account_address.m_spend_public_key.data, 32); + hw::ledger::log_hexbuffer("get_subaddress: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32); + hw::ledger::log_hexbuffer("get_subaddress: [[IN]] keys.m_view_public_key", keys_x.m_account_address.m_view_public_key.data, 32); + hw::ledger::log_hexbuffer("get_subaddress: [[IN]] keys.m_view_secret_key ", keys_x.m_view_secret_key.data, 32); + hw::ledger::log_hexbuffer("get_subaddress: [[IN]] keys.m_spend_public_key", keys_x.m_account_address.m_spend_public_key.data, 32); hw::ledger::log_message ("get_subaddress: [[IN]] index ", std::to_string(index_x.major)+"."+std::to_string(index_x.minor)); - this->controle_device->get_subaddress(keys_x, index_x, address_x); - hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_view_public_key ", address_x.m_view_public_key.data, 32); - hw::ledger::log_hexbuffer("derive_subaddress_public_key: [[IN]] keys.m_spend_public_key", address_x.m_spend_public_key.data, 32); + address_x = this->controle_device->get_subaddress(keys_x, index_x); + hw::ledger::log_hexbuffer("get_subaddress: [[OUT]] keys.m_view_public_key ", address_x.m_view_public_key.data, 32); + hw::ledger::log_hexbuffer("get_subaddress: [[OUT]] keys.m_spend_public_key", address_x.m_spend_public_key.data, 32); #endif if (index.is_zero()) { @@ -717,20 +768,13 @@ namespace hw { hw::ledger::check32("get_subaddress", "address.m_spend_public_key.data", address_x.m_spend_public_key.data, address.m_spend_public_key.data); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return address; + return address; } crypto::secret_key device_ledger::get_subaddress_secret_key(const crypto::secret_key &sec, const cryptonote::subaddress_index &index) { - crypto::secret_key sub_sec; - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + crypto::secret_key sub_sec; + int offset; #ifdef DEBUG_HWDEVICE const crypto::secret_key sec_x = hw::ledger::decrypt(sec); @@ -738,7 +782,7 @@ namespace hw { crypto::secret_key sub_sec_x; hw::ledger::log_message ("get_subaddress_secret_key: [[IN]] index ", std::to_string(index.major)+"."+std::to_string(index.minor)); hw::ledger::log_hexbuffer("get_subaddress_secret_key: [[IN]] sec ", sec_x.data, 32); - this->controle_device->get_subaddress_secret_key(sec_x, index_x, sub_sec_x); + sub_sec_x = this->controle_device->get_subaddress_secret_key(sec_x, index_x); hw::ledger::log_hexbuffer("get_subaddress_secret_key: [[OUT]] sub_sec", sub_sec_x.data, 32); #endif @@ -751,7 +795,7 @@ namespace hw { this->buffer_send[4] = 0x00; offset = 5; //options - this->buffer_send[offset] = options; + this->buffer_send[offset] = 0; offset += 1; //sec memmove(this->buffer_send+offset, sec.data, 32); @@ -772,12 +816,7 @@ namespace hw { hw::ledger::check32("get_subaddress_secret_key", "sub_sec", sub_sec_x.data, sub_sec_clear.data); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return sub_sec; + return sub_sec; } /* ======================================================================= */ @@ -785,10 +824,9 @@ namespace hw { /* ======================================================================= */ bool device_ledger::verify_keys(const crypto::secret_key &secret_key, const crypto::public_key &public_key) { - lock_device(); - try { - int offset =0,sw; - unsigned char options = 0; + AUTO_LOCK_CMD(); + int offset, sw; + reset_buffer(); this->buffer_send[0] = 0x00; this->buffer_send[1] = INS_VERIFY_KEY; @@ -816,20 +854,12 @@ namespace hw { this->buffer_recv[2] << 8 | this->buffer_recv[3] << 0 ; - unlock_device(); return verified == 1; - }catch (...) { - unlock_device(); - throw; - } - return false; } bool device_ledger::scalarmultKey(rct::key & aP, const rct::key &P, const rct::key &a) { - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + int offset; #ifdef DEBUG_HWDEVICE const rct::key P_x = P; @@ -843,8 +873,6 @@ namespace hw { reset_buffer(); - options = 0; - this->buffer_send[0] = 0x00; this->buffer_send[1] = INS_SECRET_SCAL_MUL_KEY; this->buffer_send[2] = 0x00; @@ -852,7 +880,7 @@ namespace hw { this->buffer_send[4] = 0x00; offset = 5; //options - this->buffer_send[offset] = options; + this->buffer_send[offset] = 0; offset += 1; //pub memmove(this->buffer_send+offset, P.bytes, 32); @@ -873,19 +901,12 @@ namespace hw { hw::ledger::check32("scalarmultKey", "mulkey", (char*)aP_x.bytes, (char*)aP.bytes); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } bool device_ledger::scalarmultBase(rct::key &aG, const rct::key &a) { - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + int offset; #ifdef DEBUG_HWDEVICE const rct::key a_x = hw::ledger::decrypt(a); @@ -897,8 +918,6 @@ namespace hw { reset_buffer(); - options = 0; - this->buffer_send[0] = 0x00; this->buffer_send[1] = INS_SECRET_SCAL_MUL_BASE; this->buffer_send[2] = 0x00; @@ -906,7 +925,7 @@ namespace hw { this->buffer_send[4] = 0x00; offset = 5; //options - this->buffer_send[offset] = options; + this->buffer_send[offset] = 0; offset += 1; //sec memmove(this->buffer_send+offset, a.bytes, 32); @@ -923,20 +942,12 @@ namespace hw { hw::ledger::check32("scalarmultBase", "mulkey", (char*)aG_x.bytes, (char*)aG.bytes); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } bool device_ledger::sc_secret_add( crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) { - - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + int offset; #ifdef DEBUG_HWDEVICE const crypto::secret_key a_x = hw::ledger::decrypt(a); @@ -947,8 +958,6 @@ namespace hw { reset_buffer(); - options = 0; - this->buffer_send[0] = 0x00; this->buffer_send[1] = INS_SECRET_KEY_ADD; this->buffer_send[2] = 0x00; @@ -956,7 +965,7 @@ namespace hw { this->buffer_send[4] = 0x00; offset = 5; //options - this->buffer_send[offset] = options; + this->buffer_send[offset] = 0; offset += 1; //sec key memmove(this->buffer_send+offset, a.data, 32); @@ -977,23 +986,16 @@ namespace hw { hw::ledger::check32("sc_secret_add", "r", r_x.data, r_clear.data); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } crypto::secret_key device_ledger::generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key, bool recover) { - if (recover) { - throw std::runtime_error("device generate key does not support recover"); - } + AUTO_LOCK_CMD(); + if (recover) { + throw std::runtime_error("device generate key does not support recover"); + } - lock_device(); - try { - int offset =0; - unsigned char options = 0; + int offset; #ifdef DEBUG_HWDEVICE bool recover_x = recover; @@ -1004,8 +1006,6 @@ namespace hw { reset_buffer(); - options = 0; - this->buffer_send[0] = 0x00; this->buffer_send[1] = INS_GENERATE_KEYPAIR; this->buffer_send[2] = 0x00; @@ -1013,7 +1013,7 @@ namespace hw { this->buffer_send[4] = 0x00; offset = 5; //options - this->buffer_send[offset] = options; + this->buffer_send[offset] = 0; offset += 1; this->buffer_send[4] = offset-5; @@ -1031,20 +1031,13 @@ namespace hw { hw::ledger::check32("generate_keys", "pub", pub_x.data, pub.data); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return sec; + return sec; } bool device_ledger::generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) { - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + bool r = false; #ifdef DEBUG_HWDEVICE const crypto::public_key pub_x = pub; @@ -1056,6 +1049,17 @@ namespace hw { hw::ledger::log_hexbuffer("generate_key_derivation: [[OUT]] derivation", derivation_x.data, 32); #endif + if ((this->mode == TRANSACTION_PARSE) && has_view_key) { + //A derivation is resquested in PASRE mode and we have the view key, + //so do that wihtout the device and return the derivation unencrypted. + MDEBUG( "generate_key_derivation : PARSE mode with known viewkey"); + //Note derivation in PARSE mode can only happen with viewkey, so assert it! + assert(is_fake_view_key(sec)); + r = crypto::generate_key_derivation(pub, this->viewkey, derivation); + } else { + + int offset; + reset_buffer(); this->buffer_send[0] = 0x00; @@ -1065,7 +1069,7 @@ namespace hw { this->buffer_send[4] = 0x00; offset = 5; //options - this->buffer_send[offset] = options; + this->buffer_send[offset] = 0; offset += 1; //pub memmove(this->buffer_send+offset, pub.data, 32); @@ -1080,25 +1084,42 @@ namespace hw { //derivattion data memmove(derivation.data, &this->buffer_recv[0], 32); + r = true; + } + #ifdef DEBUG_HWDEVICE + crypto::key_derivation derivation_clear ; + if ((this->mode == TRANSACTION_PARSE) && has_view_key) { + derivation_clear = derivation; + }else { + derivation_clear = hw::ledger::decrypt(derivation); + } + hw::ledger::check32("generate_key_derivation", "derivation", derivation_x.data, derivation_clear.data); + #endif - #ifdef DEBUG_HWDEVICE - crypto::key_derivation derivation_clear = hw::ledger::decrypt(derivation); - hw::ledger::check32("generate_key_derivation", "derivation", derivation_x.data, derivation_clear.data); - #endif + return r; + } - unlock_device(); - }catch (...) { - unlock_device(); - throw; + bool device_ledger::conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations) { + const crypto::public_key *pkey=NULL; + if (derivation == main_derivation) { + pkey = &tx_pub_key; + MDEBUG("conceal derivation with main tx pub key"); + } else { + for(size_t n=0; n < additional_derivations.size();++n) { + if(derivation == additional_derivations[n]) { + pkey = &additional_tx_pub_keys[n]; + MDEBUG("conceal derivation with additionnal tx pub key"); + break; + } + } } - return true; - } + ASSERT_X(pkey, "Mismatched derivation on scan info"); + return this->generate_key_derivation(*pkey, crypto::null_skey, derivation); + } bool device_ledger::derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) { - lock_device(); - try { + AUTO_LOCK_CMD(); int offset; - unsigned char options; #ifdef DEBUG_HWDEVICE const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation); @@ -1112,8 +1133,6 @@ namespace hw { reset_buffer(); - options = 0; - this->buffer_send[0] = 0x00; this->buffer_send[1] = INS_DERIVATION_TO_SCALAR; this->buffer_send[2] = 0x00; @@ -1121,7 +1140,7 @@ namespace hw { this->buffer_send[4] = 0x00; offset = 5; //options - this->buffer_send[offset] = options; + this->buffer_send[offset] = 0; offset += 1; //derivattion memmove(this->buffer_send+offset, derivation.data, 32); @@ -1145,19 +1164,12 @@ namespace hw { hw::ledger::check32("derivation_to_scalar", "res", res_x.data, res_clear.data); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } bool device_ledger::derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &sec, crypto::secret_key &derived_sec) { - lock_device(); - try { + AUTO_LOCK_CMD(); int offset; - unsigned char options; #ifdef DEBUG_HWDEVICE const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation); @@ -1173,8 +1185,6 @@ namespace hw { reset_buffer(); - options = 0; - this->buffer_send[0] = 0x00; this->buffer_send[1] = INS_DERIVE_SECRET_KEY; this->buffer_send[2] = 0x00; @@ -1182,7 +1192,7 @@ namespace hw { this->buffer_send[4] = 0x00; offset = 5; //options - this->buffer_send[offset] = options; + this->buffer_send[offset] = 0; offset += 1; //derivation memmove(this->buffer_send+offset, derivation.data, 32); @@ -1209,20 +1219,13 @@ namespace hw { hw::ledger::check32("derive_secret_key", "derived_sec", derived_sec_x.data, derived_sec_clear.data); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } bool device_ledger::derive_public_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::public_key &pub, crypto::public_key &derived_pub){ - lock_device(); - try { + AUTO_LOCK_CMD(); int offset; - unsigned char options; - + #ifdef DEBUG_HWDEVICE const crypto::key_derivation derivation_x = hw::ledger::decrypt(derivation); const std::size_t output_index_x = output_index; @@ -1237,8 +1240,6 @@ namespace hw { reset_buffer(); - options = 0; - this->buffer_send[0] = 0x00; this->buffer_send[1] = INS_DERIVE_PUBLIC_KEY; this->buffer_send[2] = 0x00; @@ -1246,7 +1247,7 @@ namespace hw { this->buffer_send[4] = 0x00; offset = 5; //options - this->buffer_send[offset] = options; + this->buffer_send[offset] = 0; offset += 1; //derivation memmove(this->buffer_send+offset, derivation.data, 32); @@ -1272,19 +1273,12 @@ namespace hw { hw::ledger::check32("derive_public_key", "derived_pub", derived_pub_x.data, derived_pub.data); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } bool device_ledger::secret_key_to_public_key(const crypto::secret_key &sec, crypto::public_key &pub) { - lock_device(); - try { + AUTO_LOCK_CMD(); int offset; - unsigned char options; #ifdef DEBUG_HWDEVICE const crypto::secret_key sec_x = hw::ledger::decrypt(sec); @@ -1299,8 +1293,6 @@ namespace hw { reset_buffer(); - options = 0; - this->buffer_send[0] = 0x00; this->buffer_send[1] = INS_SECRET_KEY_TO_PUBLIC_KEY; this->buffer_send[2] = 0x00; @@ -1308,7 +1300,7 @@ namespace hw { this->buffer_send[4] = 0x00; offset = 5; //options - this->buffer_send[offset] = options; + this->buffer_send[offset] = 0; offset += 1; //sec key memmove(this->buffer_send+offset, sec.data, 32); @@ -1325,19 +1317,12 @@ namespace hw { hw::ledger::check32("secret_key_to_public_key", "pub", pub_x.data, pub.data); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } bool device_ledger::generate_key_image(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_image &image){ - lock_device(); - try { + AUTO_LOCK_CMD(); int offset; - unsigned char options; #ifdef DEBUG_HWDEVICE const crypto::public_key pub_x = pub; @@ -1351,8 +1336,6 @@ namespace hw { reset_buffer(); - options = 0; - this->buffer_send[0] = 0x00; this->buffer_send[1] = INS_GEN_KEY_IMAGE; this->buffer_send[2] = 0x00; @@ -1360,7 +1343,7 @@ namespace hw { this->buffer_send[4] = 0x00; offset = 5; //options - this->buffer_send[offset] = options; + this->buffer_send[offset] = 0; offset += 1; //pub memmove(this->buffer_send+offset, pub.data, 32); @@ -1380,12 +1363,7 @@ namespace hw { hw::ledger::check32("generate_key_image", "image", image_x.data, image.data); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } /* ======================================================================= */ @@ -1393,12 +1371,9 @@ namespace hw { /* ======================================================================= */ bool device_ledger::open_tx(crypto::secret_key &tx_key) { - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + int offset; - lock_tx(); reset_buffer(); key_map.clear(); @@ -1423,57 +1398,19 @@ namespace hw { this->exchange(); memmove(tx_key.data, &this->buffer_recv[32], 32); - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; - } - - bool device_ledger::set_signature_mode(unsigned int sig_mode) { - lock_device(); - try { - int offset =0; - unsigned char options = 0; - - reset_buffer(); - - this->buffer_send[0] = 0x00; - this->buffer_send[1] = INS_SET_SIGNATURE_MODE; - this->buffer_send[2] = 0x01; - this->buffer_send[3] = 0x00; - this->buffer_send[4] = 0x00; - offset = 5; - //options - this->buffer_send[offset] = 0x00; - offset += 1; - //account - this->buffer_send[offset] = sig_mode; - offset += 1; - - this->buffer_send[4] = offset-5; - this->length_send = offset; - this->exchange(); - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + + return true; } bool device_ledger::encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) { - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + int offset; #ifdef DEBUG_HWDEVICE const crypto::public_key public_key_x = public_key; const crypto::secret_key secret_key_x = hw::ledger::decrypt(secret_key); crypto::hash8 payment_id_x = payment_id; - this->controle_device->encrypt_payment_id(public_key_x, secret_key_x, payment_id_x); + this->controle_device->encrypt_payment_id(payment_id_x, public_key_x, secret_key_x); #endif reset_buffer(); @@ -1506,32 +1443,19 @@ namespace hw { hw::ledger::check8("stealth", "payment_id", payment_id_x.data, payment_id.data); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } bool device_ledger::add_output_key_mapping(const crypto::public_key &Aout, const crypto::public_key &Bout, const bool is_subaddress, const size_t real_output_index, const rct::key &amount_key, const crypto::public_key &out_eph_public_key) { - lock_device(); - try { + AUTO_LOCK_CMD(); key_map.add(ABPkeys(rct::pk2rct(Aout),rct::pk2rct(Bout), is_subaddress, real_output_index, rct::pk2rct(out_eph_public_key), amount_key)); - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } bool device_ledger::ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & AKout) { - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + int offset; #ifdef DEBUG_HWDEVICE const rct::key AKout_x = hw::ledger::decrypt(AKout); @@ -1574,19 +1498,12 @@ namespace hw { hw::ledger::log_hexbuffer("Blind AKV input", (char*)&this->buffer_recv[64], 3*32); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } bool device_ledger::ecdhDecode(rct::ecdhTuple & masked, const rct::key & AKout) { - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + int offset; #ifdef DEBUG_HWDEVICE const rct::key AKout_x = hw::ledger::decrypt(AKout); @@ -1627,21 +1544,13 @@ namespace hw { hw::ledger::check32("ecdhDecode", "mask", (char*)masked_x.mask.bytes,(char*) masked.mask.bytes); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } bool device_ledger::mlsag_prehash(const std::string &blob, size_t inputs_size, size_t outputs_size, const rct::keyV &hashes, const rct::ctkeyV &outPk, rct::key &prehash) { - - lock_device(); - try { - unsigned char options = 0; + AUTO_LOCK_CMD(); unsigned int data_offset, C_offset, kv_offset, i; const char *data; @@ -1834,21 +1743,15 @@ namespace hw { hw::ledger::check32("mlsag_prehash", "prehash", (char*)prehash_x.bytes, (char*)prehash.bytes); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } bool device_ledger::mlsag_prepare(const rct::key &H, const rct::key &xx, rct::key &a, rct::key &aG, rct::key &aHP, rct::key &II) { - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + int offset; + unsigned char options; #ifdef DEBUG_HWDEVICE const rct::key H_x = H; @@ -1897,19 +1800,13 @@ namespace hw { hw::ledger::check32("mlsag_prepare", "II", (char*)II_x.bytes, (char*)II.bytes); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } bool device_ledger::mlsag_prepare(rct::key &a, rct::key &aG) { - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + int offset; + unsigned char options; #ifdef DEBUG_HWDEVICE rct::key a_x; @@ -1941,19 +1838,13 @@ namespace hw { hw::ledger::check32("mlsag_prepare", "AG", (char*)aG_x.bytes, (char*)aG.bytes); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } bool device_ledger::mlsag_hash(const rct::keyV &long_message, rct::key &c) { - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + int offset; + unsigned char options; size_t cnt; #ifdef DEBUG_HWDEVICE @@ -1991,20 +1882,12 @@ namespace hw { hw::ledger::check32("mlsag_hash", "c", (char*)c_x.bytes, (char*)c.bytes); #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; - + return true; } bool device_ledger::mlsag_sign(const rct::key &c, const rct::keyV &xx, const rct::keyV &alpha, const size_t rows, const size_t dsRows, rct::keyV &ss) { - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + int offset; CHECK_AND_ASSERT_THROW_MES(dsRows<=rows, "dsRows greater than rows"); CHECK_AND_ASSERT_THROW_MES(xx.size() == rows, "xx size does not match rows"); @@ -2061,19 +1944,12 @@ namespace hw { } #endif - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } bool device_ledger::close_tx() { - lock_device(); - try { - int offset =0; - unsigned char options = 0; + AUTO_LOCK_CMD(); + int offset; reset_buffer(); @@ -2091,13 +1967,7 @@ namespace hw { this->length_send = offset; this->exchange(); - unlock_tx(); - unlock_device(); - }catch (...) { - unlock_device(); - throw; - } - return true; + return true; } /* ---------------------------------------------------------- */ diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp index e06c5f72c..9f73bd070 100644 --- a/src/device/device_ledger.hpp +++ b/src/device/device_ledger.hpp @@ -32,11 +32,11 @@ #include <cstddef> #include <string> -#include <mutex> #include "device.hpp" #include <PCSC/winscard.h> #include <PCSC/wintypes.h> - +#include <boost/thread/mutex.hpp> +#include <boost/thread/recursive_mutex.hpp> namespace hw { @@ -80,13 +80,11 @@ namespace hw { class device_ledger : public hw::device { private: - mutable std::mutex device_locker; - mutable std::mutex tx_locker; - void lock_device() ; - void unlock_device() ; - void lock_tx() ; - void unlock_tx() ; - + // Locker for concurrent access + mutable boost::recursive_mutex device_locker; + mutable boost::mutex command_locker; + + //PCSC management std::string full_name; SCARDCONTEXT hContext; SCARDHANDLE hCard; @@ -95,15 +93,21 @@ namespace hw { DWORD length_recv; BYTE buffer_recv[BUFFER_RECV_SIZE]; unsigned int id; - - Keymap key_map; - - void logCMD(void); void logRESP(void); unsigned int exchange(unsigned int ok=0x9000, unsigned int mask=0xFFFF); void reset_buffer(void); + // hw running mode + device_mode mode; + // map public destination key to ephemeral destination key + Keymap key_map; + + // To speed up blockchain parsing the view key maybe handle here. + crypto::secret_key viewkey; + bool has_view_key; + + //extra debug #ifdef DEBUG_HWDEVICE device *controle_device; #endif @@ -130,6 +134,15 @@ namespace hw { bool connect(void) override; bool disconnect() override; + bool set_mode(device_mode mode) override; + + /* ======================================================================= */ + /* LOCKER */ + /* ======================================================================= */ + void lock(void) override; + void unlock(void) override; + bool try_lock(void) override; + /* ======================================================================= */ /* WALLET & ADDRESS */ /* ======================================================================= */ @@ -156,6 +169,7 @@ namespace hw { bool sc_secret_add(crypto::secret_key &r, const crypto::secret_key &a, const crypto::secret_key &b) override; crypto::secret_key generate_keys(crypto::public_key &pub, crypto::secret_key &sec, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false) override; bool generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) override; + bool conceal_derivation(crypto::key_derivation &derivation, const crypto::public_key &tx_pub_key, const std::vector<crypto::public_key> &additional_tx_pub_keys, const crypto::key_derivation &main_derivation, const std::vector<crypto::key_derivation> &additional_derivations); bool derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res) override; bool derive_secret_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::secret_key &sec, crypto::secret_key &derived_sec) override; bool derive_public_key(const crypto::key_derivation &derivation, const std::size_t output_index, const crypto::public_key &pub, crypto::public_key &derived_pub) override; @@ -168,8 +182,6 @@ namespace hw { bool open_tx(crypto::secret_key &tx_key) override; - bool set_signature_mode(unsigned int sig_mode) override; - bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override; bool ecdhEncode(rct::ecdhTuple & unmasked, const rct::key & sharedSec) override; @@ -190,10 +202,9 @@ namespace hw { }; - #ifdef DEBUG_HWDEVICE - extern crypto::secret_key viewkey; - extern crypto::secret_key spendkey; + extern crypto::secret_key dbg_viewkey; + extern crypto::secret_key dbg_spendkey; #endif #endif //WITH_DEVICE_LEDGER diff --git a/src/device/log.cpp b/src/device/log.cpp index a2ad0f4f4..cbbcfc953 100644 --- a/src/device/log.cpp +++ b/src/device/log.cpp @@ -56,8 +56,8 @@ namespace hw { } #ifdef DEBUG_HWDEVICE - extern crypto::secret_key viewkey; - extern crypto::secret_key spendkey; + extern crypto::secret_key dbg_viewkey; + extern crypto::secret_key dbg_spendkey; void decrypt(char* buf, size_t len) { @@ -69,7 +69,7 @@ namespace hw { if (buf[i] != 0) break; } if (i == 32) { - memmove(buf, hw::ledger::viewkey.data, 32); + memmove(buf, hw::ledger::dbg_viewkey.data, 32); return; } //spend key? @@ -77,7 +77,7 @@ namespace hw { if (buf[i] != (char)0xff) break; } if (i == 32) { - memmove(buf, hw::ledger::spendkey.data, 32); + memmove(buf, hw::ledger::dbg_spendkey.data, 32); return; } } @@ -161,4 +161,4 @@ namespace hw { } #endif //WITH_DEVICE_LEDGER -}
\ No newline at end of file +} diff --git a/src/p2p/net_node.cpp b/src/p2p/net_node.cpp index bde6fc88e..c9ca63f43 100644 --- a/src/p2p/net_node.cpp +++ b/src/p2p/net_node.cpp @@ -39,7 +39,7 @@ namespace nodetool , "Port for p2p network protocol" , std::to_string(config::P2P_DEFAULT_PORT) , {{ &cryptonote::arg_testnet_on, &cryptonote::arg_stagenet_on }} - , [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val) { + , [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val)->std::string { if (testnet_stagenet[0] && defaulted) return std::to_string(config::testnet::P2P_DEFAULT_PORT); else if (testnet_stagenet[1] && defaulted) diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 54875e619..3b0d1c394 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -397,8 +397,8 @@ namespace nodetool full_addrs.insert("163.172.182.165:18080"); full_addrs.insert("161.67.132.39:18080"); full_addrs.insert("198.74.231.92:18080"); - full_addrs.insert("195.154.123.123:28080"); - full_addrs.insert("212.83.172.165:28080"); + full_addrs.insert("195.154.123.123:18080"); + full_addrs.insert("212.83.172.165:18080"); } return full_addrs; } @@ -490,7 +490,7 @@ namespace nodetool if (result.size()) { for (const auto& addr_string : result) - full_addrs.insert(addr_string + ":18080"); + full_addrs.insert(addr_string + ":" + std::to_string(m_nettype == cryptonote::TESTNET ? ::config::testnet::P2P_DEFAULT_PORT : m_nettype == cryptonote::STAGENET ? ::config::stagenet::P2P_DEFAULT_PORT : ::config::P2P_DEFAULT_PORT)); } ++i; } diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index c3d1a9d11..69e527fd8 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -2117,7 +2117,7 @@ namespace cryptonote , "Port for RPC server" , std::to_string(config::RPC_DEFAULT_PORT) , {{ &cryptonote::arg_testnet_on, &cryptonote::arg_stagenet_on }} - , [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val) { + , [](std::array<bool, 2> testnet_stagenet, bool defaulted, std::string val)->std::string { if (testnet_stagenet[0] && defaulted) return std::to_string(config::testnet::RPC_DEFAULT_PORT); else if (testnet_stagenet[1] && defaulted) diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index a5755e062..86e41e047 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -153,7 +153,7 @@ namespace cryptonote MAP_JON_RPC_WE_IF("relay_tx", on_relay_tx, COMMAND_RPC_RELAY_TX, !m_restricted) MAP_JON_RPC_WE_IF("sync_info", on_sync_info, COMMAND_RPC_SYNC_INFO, !m_restricted) MAP_JON_RPC_WE("get_txpool_backlog", on_get_txpool_backlog, COMMAND_RPC_GET_TRANSACTION_POOL_BACKLOG) - MAP_JON_RPC_WE_IF("get_output_distribution", on_get_output_distribution, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION, !m_restricted) + MAP_JON_RPC_WE("get_output_distribution", on_get_output_distribution, COMMAND_RPC_GET_OUTPUT_DISTRIBUTION) END_JSON_RPC_MAP() END_URI_MAP2() diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 97dadb126..b2651026f 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -2974,6 +2974,22 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) // create wallet bool r = new_wallet(vm, "Ledger"); CHECK_AND_ASSERT_MES(r, false, tr("account creation failed")); + // if no block_height is specified, assume its a new account and start it "now" + if(m_wallet->get_refresh_from_block_height() == 0) { + { + tools::scoped_message_writer wrt = tools::msg_writer(); + wrt << tr("No restore height is specified."); + wrt << tr("Assumed you are creating a new account, restore will be done from current estimated blockchain height."); + wrt << tr("Use --restore-height if you want to restore an already setup account from a specific height"); + } + std::string confirm = input_line(tr("Is this okay? (Y/Yes/N/No): ")); + if (std::cin.eof() || !command_line::is_yes(confirm)) + CHECK_AND_ASSERT_MES(false, false, tr("account creation aborted")); + + m_wallet->set_refresh_from_block_height(m_wallet->estimate_blockchain_height()-1); + m_wallet->explicit_refresh_from_block_height(true); + m_restore_height = m_wallet->get_refresh_from_block_height(); + } } else { @@ -2990,7 +3006,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) CHECK_AND_ASSERT_MES(r, false, tr("account creation failed")); } - if (m_restoring && m_generate_from_json.empty()) + if (m_restoring && m_generate_from_json.empty() && m_generate_from_device.empty()) { m_wallet->explicit_refresh_from_block_height(!command_line::is_arg_defaulted(vm, arg_restore_height)); } @@ -3101,6 +3117,9 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) if (!m_trusted_daemon) message_writer() << (boost::format(tr("Warning: using an untrusted daemon at %s, privacy will be lessened")) % m_wallet->get_daemon_address()).str(); + if (m_wallet->get_ring_database().empty()) + fail_msg_writer() << tr("Failed to initialize ring database: privacy enhancing features will be inactive"); + m_wallet->callback(this); return true; @@ -3385,7 +3404,7 @@ bool simple_wallet::new_wallet(const boost::program_options::variables_map& vm, try { m_wallet->restore(m_wallet_file, std::move(rc.second).password(), device_name); - message_writer(console_color_white, true) << tr("Generated new on device wallet: ") + message_writer(console_color_white, true) << tr("Generated new wallet on hw device: ") << m_wallet->get_account().get_public_address_str(m_wallet->nettype()); } catch (const std::exception& e) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index b02884f67..b78a471b9 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -60,7 +60,7 @@ namespace Monero { namespace { // copy-pasted from simplewallet - static const size_t DEFAULT_MIXIN = 4; + static const size_t DEFAULT_MIXIN = 6; static const int DEFAULT_REFRESH_INTERVAL_MILLIS = 1000 * 10; // limit maximum refresh interval as one minute static const int MAX_REFRESH_INTERVAL_MILLIS = 1000 * 60 * 1; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 4b7e6dd93..8a1d29143 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -145,7 +145,7 @@ struct options { "shared-ringdb-dir", tools::wallet2::tr("Set shared ring database path"), get_default_ringdb_path(), testnet, - [](bool testnet, bool defaulted, std::string val) { + [](bool testnet, bool defaulted, std::string val)->std::string { if (testnet) return (boost::filesystem::path(val) / "testnet").string(); return val; @@ -1007,13 +1007,16 @@ void wallet2::set_unspent(size_t idx) //---------------------------------------------------------------------------------------------------- void wallet2::check_acc_out_precomp(const tx_out &o, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, size_t i, tx_scan_info_t &tx_scan_info) const { + hw::device &hwdev = m_account.get_device(); + boost::unique_lock<hw::device> hwdev_lock (hwdev); + hwdev.set_mode(hw::device::TRANSACTION_PARSE); if (o.target.type() != typeid(txout_to_key)) { tx_scan_info.error = true; LOG_ERROR("wrong type id in transaction out"); return; } - tx_scan_info.received = is_out_to_acc_precomp(m_subaddresses, boost::get<txout_to_key>(o.target).key, derivation, additional_derivations, i, m_account.get_device()); + tx_scan_info.received = is_out_to_acc_precomp(m_subaddresses, boost::get<txout_to_key>(o.target).key, derivation, additional_derivations, i, hwdev); if(tx_scan_info.received) { tx_scan_info.money_transfered = o.amount; // may be 0 for ringct outputs @@ -1080,9 +1083,15 @@ void wallet2::scan_output(const cryptonote::transaction &tx, const crypto::publi //---------------------------------------------------------------------------------------------------- void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote::transaction& tx, const std::vector<uint64_t> &o_indices, uint64_t height, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen) { - // In this function, tx (probably) only contains the base information - // (that is, the prunable stuff may or may not be included) + //ensure device is let in NONE mode in any case + hw::device &hwdev = m_account.get_device(); + + boost::unique_lock<hw::device> hwdev_lock (hwdev); + hw::reset_mode rst(hwdev); + hwdev_lock.unlock(); + // In this function, tx (probably) only contains the base information + // (that is, the prunable stuff may or may not be included) if (!miner_tx && !pool) process_unconfirmed(txid, tx, height); std::vector<size_t> outs; @@ -1119,8 +1128,10 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote tools::threadpool& tpool = tools::threadpool::getInstance(); tools::threadpool::waiter waiter; const cryptonote::account_keys& keys = m_account.get_keys(); - hw::device &hwdev = m_account.get_device(); crypto::key_derivation derivation; + + hwdev_lock.lock(); + hwdev.set_mode(hw::device::TRANSACTION_PARSE); if (!hwdev.generate_key_derivation(tx_pub_key, keys.m_view_secret_key, derivation)) { MWARNING("Failed to generate key derivation from tx pubkey, skipping"); @@ -1140,6 +1151,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote additional_derivations.pop_back(); } } + hwdev_lock.unlock(); if (miner_tx && m_refresh_type == RefreshNoCoinbase) { @@ -1161,16 +1173,19 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote std::ref(tx_scan_info[i]))); } waiter.wait(); - // then scan all outputs from 0 + hwdev_lock.lock(); + hwdev.set_mode(hw::device::NONE); for (size_t i = 0; i < tx.vout.size(); ++i) { THROW_WALLET_EXCEPTION_IF(tx_scan_info[i].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys()); if (tx_scan_info[i].received) { + hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys, derivation, additional_derivations); scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs); } } + hwdev_lock.unlock(); } } else if (tx.vout.size() > 1 && tools::threadpool::getInstance().get_max_concurrency() > 1) @@ -1181,14 +1196,19 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote std::ref(tx_scan_info[i]))); } waiter.wait(); + + hwdev_lock.lock(); + hwdev.set_mode(hw::device::NONE); for (size_t i = 0; i < tx.vout.size(); ++i) { THROW_WALLET_EXCEPTION_IF(tx_scan_info[i].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys()); if (tx_scan_info[i].received) { + hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys, derivation, additional_derivations); scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs); } } + hwdev_lock.unlock(); } else { @@ -1198,7 +1218,11 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote THROW_WALLET_EXCEPTION_IF(tx_scan_info[i].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys()); if (tx_scan_info[i].received) { + hwdev_lock.lock(); + hwdev.set_mode(hw::device::NONE); + hwdev.conceal_derivation(tx_scan_info[i].received->derivation, tx_pub_key, additional_tx_pub_keys, derivation, additional_derivations); scan_output(tx, tx_pub_key, i, tx_scan_info[i], num_vouts_received, tx_money_got_in_outs, outs); + hwdev_lock.unlock(); } } } @@ -2669,6 +2693,9 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_ m_confirm_backlog_threshold = 0; m_confirm_export_overwrite = true; m_auto_low_priority = true; + m_segregate_pre_fork_outputs = true; + m_key_reuse_mitigation2 = true; + m_segregation_height = 0; m_key_on_device = false; } else if(json.IsObject()) @@ -2785,6 +2812,12 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_ (boost::format("%s wallet cannot be opened as %s wallet") % (field_nettype == 0 ? "Mainnet" : field_nettype == 1 ? "Testnet" : "Stagenet") % (m_nettype == MAINNET ? "mainnet" : m_nettype == TESTNET ? "testnet" : "stagenet")).str()); + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, segregate_pre_fork_outputs, int, Int, false, true); + m_segregate_pre_fork_outputs = field_segregate_pre_fork_outputs; + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, key_reuse_mitigation2, int, Int, false, true); + m_key_reuse_mitigation2 = field_key_reuse_mitigation2; + GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, segregation_height, int, Uint, false, 0); + m_segregation_height = field_segregation_height; } else { @@ -5467,29 +5500,43 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions(std::vector<crypto } } -void wallet2::set_ring_database(const std::string &filename) +bool wallet2::set_ring_database(const std::string &filename) { m_ring_database = filename; MINFO("ringdb path set to " << filename); m_ringdb.reset(); - cryptonote::block b; - generate_genesis(b); if (!m_ring_database.empty()) - m_ringdb.reset(new tools::ringdb(m_ring_database, epee::string_tools::pod_to_hex(get_block_hash(b)))); + { + try + { + cryptonote::block b; + generate_genesis(b); + m_ringdb.reset(new tools::ringdb(m_ring_database, epee::string_tools::pod_to_hex(get_block_hash(b)))); + } + catch (const std::exception &e) + { + MERROR("Failed to initialize ringdb: " << e.what()); + m_ring_database = ""; + return false; + } + } + return true; } bool wallet2::add_rings(const crypto::chacha_key &key, const cryptonote::transaction_prefix &tx) { if (!m_ringdb) return true; - return m_ringdb->add_rings(key, tx); + try { return m_ringdb->add_rings(key, tx); } + catch (const std::exception &e) { return false; } } bool wallet2::add_rings(const cryptonote::transaction_prefix &tx) { crypto::chacha_key key; generate_chacha_key_from_secret_keys(key); - return add_rings(key, tx); + try { return add_rings(key, tx); } + catch (const std::exception &e) { return false; } } bool wallet2::remove_rings(const cryptonote::transaction_prefix &tx) @@ -5498,14 +5545,16 @@ bool wallet2::remove_rings(const cryptonote::transaction_prefix &tx) return true; crypto::chacha_key key; generate_chacha_key_from_secret_keys(key); - return m_ringdb->remove_rings(key, tx); + try { return m_ringdb->remove_rings(key, tx); } + catch (const std::exception &e) { return false; } } bool wallet2::get_ring(const crypto::chacha_key &key, const crypto::key_image &key_image, std::vector<uint64_t> &outs) { if (!m_ringdb) return true; - return m_ringdb->get_ring(key, key_image, outs); + try { return m_ringdb->get_ring(key, key_image, outs); } + catch (const std::exception &e) { return false; } } bool wallet2::get_rings(const crypto::hash &txid, std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> &outs) @@ -5536,7 +5585,8 @@ bool wallet2::get_ring(const crypto::key_image &key_image, std::vector<uint64_t> crypto::chacha_key key; generate_chacha_key_from_secret_keys(key); - return get_ring(key, key_image, outs); + try { return get_ring(key, key_image, outs); } + catch (const std::exception &e) { return false; } } bool wallet2::set_ring(const crypto::key_image &key_image, const std::vector<uint64_t> &outs, bool relative) @@ -5547,7 +5597,8 @@ bool wallet2::set_ring(const crypto::key_image &key_image, const std::vector<uin crypto::chacha_key key; generate_chacha_key_from_secret_keys(key); - return m_ringdb->set_ring(key, key_image, outs, relative); + try { return m_ringdb->set_ring(key, key_image, outs, relative); } + catch (const std::exception &e) { return false; } } bool wallet2::find_and_save_rings(bool force) @@ -5615,33 +5666,40 @@ bool wallet2::blackball_output(const crypto::public_key &output) { if (!m_ringdb) return true; - return m_ringdb->blackball(output); + try { return m_ringdb->blackball(output); } + catch (const std::exception &e) { return false; } } bool wallet2::set_blackballed_outputs(const std::vector<crypto::public_key> &outputs, bool add) { if (!m_ringdb) return true; - bool ret = true; - if (!add) - ret &= m_ringdb->clear_blackballs(); - for (const auto &output: outputs) - ret &= m_ringdb->blackball(output); - return ret; + try + { + bool ret = true; + if (!add) + ret &= m_ringdb->clear_blackballs(); + for (const auto &output: outputs) + ret &= m_ringdb->blackball(output); + return ret; + } + catch (const std::exception &e) { return false; } } bool wallet2::unblackball_output(const crypto::public_key &output) { if (!m_ringdb) return true; - return m_ringdb->unblackball(output); + try { return m_ringdb->unblackball(output); } + catch (const std::exception &e) { return false; } } bool wallet2::is_output_blackballed(const crypto::public_key &output) const { if (!m_ringdb) return true; - return m_ringdb->blackballed(output); + try { return m_ringdb->blackballed(output); } + catch (const std::exception &e) { return false; } } bool wallet2::tx_add_fake_output(std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, uint64_t global_index, const crypto::public_key& output_public_key, const rct::key& mask, uint64_t real_index, bool unlocked) const @@ -5785,6 +5843,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> boost::optional<std::string> result = m_node_rpc_proxy.get_height(height); throw_on_rpc_response_error(result, "get_info"); bool is_shortly_after_segregation_fork = height >= segregation_fork_height && height < segregation_fork_height + SEGREGATION_FORK_VICINITY; + bool is_after_segregation_fork = height >= segregation_fork_height; // get histogram for the amounts we need cryptonote::COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request req_t = AUTO_VAL_INIT(req_t); @@ -5805,7 +5864,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> // if we want to segregate fake outs pre or post fork, get distribution std::unordered_map<uint64_t, std::pair<uint64_t, uint64_t>> segregation_limit; - if (m_segregate_pre_fork_outputs || m_key_reuse_mitigation2) + if (is_after_segregation_fork && (m_segregate_pre_fork_outputs || m_key_reuse_mitigation2)) { cryptonote::COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::request req_t = AUTO_VAL_INIT(req_t); cryptonote::COMMAND_RPC_GET_OUTPUT_DISTRIBUTION::response resp_t = AUTO_VAL_INIT(resp_t); @@ -5814,7 +5873,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> std::sort(req_t.amounts.begin(), req_t.amounts.end()); auto end = std::unique(req_t.amounts.begin(), req_t.amounts.end()); req_t.amounts.resize(std::distance(req_t.amounts.begin(), end)); - req_t.from_height = segregation_fork_height >= RECENT_OUTPUT_ZONE ? height >= (segregation_fork_height ? segregation_fork_height : height) - RECENT_OUTPUT_BLOCKS : 0; + req_t.from_height = std::max<uint64_t>(segregation_fork_height, RECENT_OUTPUT_BLOCKS) - RECENT_OUTPUT_BLOCKS; req_t.cumulative = true; m_daemon_rpc_mutex.lock(); bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_output_distribution", req_t, resp_t, m_http_client, rpc_timeout); @@ -5872,7 +5931,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> float pre_fork_num_out_ratio = 0.0f; float post_fork_num_out_ratio = 0.0f; - if (m_segregate_pre_fork_outputs && output_is_pre_fork) + if (is_after_segregation_fork && m_segregate_pre_fork_outputs && output_is_pre_fork) { num_outs = segregation_limit[amount].first; num_recent_outs = segregation_limit[amount].second; @@ -5892,7 +5951,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> break; } } - if (m_key_reuse_mitigation2) + if (is_after_segregation_fork && m_key_reuse_mitigation2) { if (output_is_pre_fork) { @@ -6107,7 +6166,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> uint64_t num_outs = 0; const uint64_t amount = td.is_rct() ? 0 : td.amount(); const bool output_is_pre_fork = td.m_block_height < segregation_fork_height; - if (m_segregate_pre_fork_outputs && output_is_pre_fork) + if (is_after_segregation_fork && m_segregate_pre_fork_outputs && output_is_pre_fork) num_outs = segregation_limit[amount].first; else for (const auto &he: resp_t.histogram) { @@ -7224,6 +7283,11 @@ bool wallet2::light_wallet_key_image_is_ours(const crypto::key_image& key_image, // usable balance. std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, bool trusted_daemon) { + //ensure device is let in NONE mode in any case + hw::device &hwdev = m_account.get_device(); + boost::unique_lock<hw::device> hwdev_lock (hwdev); + hw::reset_mode rst(hwdev); + if(m_light_wallet) { // Populate m_transfers light_wallet_get_unspent_outs(); @@ -7441,8 +7505,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp unsigned int original_output_index = 0; std::vector<size_t>* unused_transfers_indices = &unused_transfers_indices_per_subaddr[0].second; std::vector<size_t>* unused_dust_indices = &unused_dust_indices_per_subaddr[0].second; - hw::device &hwdev = m_account.get_device(); - hwdev.set_signature_mode(hw::device::SIGNATURE_FAKE); + + hwdev.set_mode(hw::device::TRANSACTION_CREATE_FAKE); while ((!dsts.empty() && dsts[0].amount > 0) || adding_fee || !preferred_inputs.empty() || should_pick_a_second_output(use_rct, txes.back().selected_transfers.size(), *unused_transfers_indices, *unused_dust_indices)) { TX &tx = txes.back(); @@ -7671,7 +7735,7 @@ skip_tx: LOG_PRINT_L1("Done creating " << txes.size() << " transactions, " << print_money(accumulated_fee) << " total fee, " << print_money(accumulated_change) << " total change"); - hwdev.set_signature_mode(hw::device::SIGNATURE_REAL); + hwdev.set_mode(hw::device::TRANSACTION_CREATE_REAL); for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i) { TX &tx = *i; @@ -7802,6 +7866,11 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_single(const crypt std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, bool trusted_daemon) { + //ensure device is let in NONE mode in any case + hw::device &hwdev = m_account.get_device(); + boost::unique_lock<hw::device> hwdev_lock (hwdev); + hw::reset_mode rst(hwdev); + uint64_t accumulated_fee, accumulated_outputs, accumulated_change; struct TX { std::vector<size_t> selected_transfers; @@ -7834,8 +7903,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton needed_fee = 0; // while we have something to send - hw::device &hwdev = m_account.get_device(); - hwdev.set_signature_mode(hw::device::SIGNATURE_FAKE); + hwdev.set_mode(hw::device::TRANSACTION_CREATE_FAKE); while (!unused_dust_indices.empty() || !unused_transfers_indices.empty()) { TX &tx = txes.back(); @@ -7921,7 +7989,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_from(const crypton LOG_PRINT_L1("Done creating " << txes.size() << " transactions, " << print_money(accumulated_fee) << " total fee, " << print_money(accumulated_change) << " total change"); - hwdev.set_signature_mode(hw::device::SIGNATURE_REAL); + hwdev.set_mode(hw::device::TRANSACTION_CREATE_REAL); for (std::vector<TX>::iterator i = txes.begin(); i != txes.end(); ++i) { TX &tx = *i; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index abc7bb538..ca8bee965 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1061,7 +1061,7 @@ namespace tools return epee::net_utils::invoke_http_json_rpc(uri, method_name, req, res, m_http_client, timeout, http_method, req_id); } - void set_ring_database(const std::string &filename); + bool set_ring_database(const std::string &filename); const std::string get_ring_database() const { return m_ring_database; } bool get_ring(const crypto::key_image &key_image, std::vector<uint64_t> &outs); bool get_rings(const crypto::hash &txid, std::vector<std::pair<crypto::key_image, std::vector<uint64_t>>> &outs); |