aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cryptonote_config.h3
-rw-r--r--src/cryptonote_core/blockchain.cpp2
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp5
-rw-r--r--src/daemon/command_line_args.h6
-rw-r--r--src/device/device.hpp37
-rw-r--r--src/device/device_default.cpp30
-rw-r--r--src/device/device_default.hpp13
-rw-r--r--src/device/device_ledger.cpp710
-rw-r--r--src/device/device_ledger.hpp47
-rw-r--r--src/device/log.cpp10
-rw-r--r--src/p2p/net_node.cpp2
-rw-r--r--src/p2p/net_node.inl6
-rw-r--r--src/rpc/core_rpc_server.cpp2
-rw-r--r--src/rpc/core_rpc_server.h2
-rw-r--r--src/simplewallet/simplewallet.cpp23
-rw-r--r--src/wallet/api/wallet.cpp2
-rw-r--r--src/wallet/wallet2.cpp140
-rw-r--r--src/wallet/wallet2.h2
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);