mirror of
https://github.com/oxen-io/oxen-core.git
synced 2023-12-14 02:22:56 +01:00
Add tx secret key via device layer
We add the tx secret key to the tx_extra in staking transactions so that values can be decoded, but the tx secret key value that we have on hand is encrypted and so we can't access it. This moves the call that adds the secret key into the device code so that devices can provide this. It also adds the tx version/type earlier in the process (into `open_tx`) so that the device can know early on that this is a stake transaction and therefore that leaking the tx secret key is okay (and can also apply other stake-specific behaviour).
This commit is contained in:
parent
052d012745
commit
ff26b83b45
7 changed files with 42 additions and 9 deletions
|
@ -637,8 +637,10 @@ namespace cryptonote
|
|||
tx.extra = extra;
|
||||
crypto::public_key txkey_pub;
|
||||
|
||||
if (tx.type == txtype::stake)
|
||||
add_tx_secret_key_to_tx_extra(tx.extra, tx_key);
|
||||
if (tx.type == txtype::stake) {
|
||||
bool added = hwdev.add_tx_secret_key_to_tx_extra(tx.extra, tx_key);
|
||||
CHECK_AND_NO_ASSERT_MES(added, false, "Failed to add tx secret key to stake transaction");
|
||||
}
|
||||
|
||||
// if we have a stealth payment id, find it and encrypt it with the tx key now
|
||||
std::vector<tx_extra_field> tx_extra_fields;
|
||||
|
@ -1002,7 +1004,9 @@ namespace cryptonote
|
|||
bool construct_tx_and_get_tx_key(const account_keys& sender_account_keys, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, std::vector<tx_source_entry>& sources, std::vector<tx_destination_entry>& destinations, const std::optional<cryptonote::tx_destination_entry>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time, crypto::secret_key &tx_key, std::vector<crypto::secret_key> &additional_tx_keys, const rct::RCTConfig &rct_config, rct::multisig_out *msout, loki_construct_tx_params const &tx_params)
|
||||
{
|
||||
hw::device &hwdev = sender_account_keys.get_device();
|
||||
hwdev.open_tx(tx_key);
|
||||
auto txversion = static_cast<uint8_t>(transaction::get_max_version_for_hf(tx_params.hf_version));
|
||||
auto txtype = static_cast<uint8_t>(tx_params.tx_type);
|
||||
hwdev.open_tx(tx_key, txversion, txtype);
|
||||
try {
|
||||
// figure out if we need to make additional tx pubkeys
|
||||
size_t num_stdaddresses = 0;
|
||||
|
|
|
@ -204,7 +204,7 @@ namespace hw {
|
|||
const crypto::public_key &R, const crypto::public_key &A, const std::optional<crypto::public_key> &B, const crypto::public_key &D, const crypto::secret_key &r,
|
||||
crypto::signature &sig) = 0;
|
||||
|
||||
virtual bool open_tx(crypto::secret_key &tx_key) = 0;
|
||||
virtual bool open_tx(crypto::secret_key &tx_key, uint8_t txversion, uint8_t txtype) = 0;
|
||||
|
||||
virtual void get_transaction_prefix_hash(const cryptonote::transaction_prefix& tx, crypto::hash& h) = 0;
|
||||
|
||||
|
@ -240,6 +240,10 @@ namespace hw {
|
|||
virtual bool clsag_hash(const rct::keyV &data, rct::key &hash) = 0;
|
||||
virtual bool clsag_sign(const rct::key &c, const rct::key &a, const rct::key &p, const rct::key &z, const rct::key &mu_P, const rct::key &mu_C, rct::key &s) = 0;
|
||||
|
||||
// Retrieves the tx secret key from the device. `key` will be whatever we got back from the
|
||||
// device, but for hardware devices that value may be encrypted or null.
|
||||
virtual bool add_tx_secret_key_to_tx_extra(std::vector<uint8_t>& tx_extra, const crypto::secret_key& key) = 0;
|
||||
|
||||
virtual bool close_tx(void) = 0;
|
||||
|
||||
virtual bool has_ki_cold_sync(void) const { return false; }
|
||||
|
|
|
@ -281,7 +281,7 @@ namespace hw {
|
|||
crypto::generate_tx_proof(prefix_hash, R, A, B, D, r, sig);
|
||||
}
|
||||
|
||||
bool device_default::open_tx(crypto::secret_key &tx_key) {
|
||||
bool device_default::open_tx(crypto::secret_key &tx_key, uint8_t /*version*/, uint8_t /*type*/) {
|
||||
cryptonote::keypair txkey = cryptonote::keypair::generate(*this);
|
||||
tx_key = txkey.sec;
|
||||
return true;
|
||||
|
@ -411,6 +411,12 @@ namespace hw {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool device_default::add_tx_secret_key_to_tx_extra(std::vector<uint8_t>& tx_extra, const crypto::secret_key& key) {
|
||||
cryptonote::add_tx_secret_key_to_tx_extra(tx_extra, key);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool device_default::close_tx() {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ namespace hw {
|
|||
const crypto::public_key &R, const crypto::public_key &A, const std::optional<crypto::public_key> &B, const crypto::public_key &D, const crypto::secret_key &r,
|
||||
crypto::signature &sig) override;
|
||||
|
||||
bool open_tx(crypto::secret_key &tx_key) override;
|
||||
bool open_tx(crypto::secret_key &tx_key, uint8_t txversion, uint8_t txtype) override;
|
||||
void get_transaction_prefix_hash(const cryptonote::transaction_prefix& tx, crypto::hash& h) override;
|
||||
|
||||
bool encrypt_payment_id(crypto::hash8 &payment_id, const crypto::public_key &public_key, const crypto::secret_key &secret_key) override;
|
||||
|
@ -142,6 +142,8 @@ namespace hw {
|
|||
bool clsag_hash(const rct::keyV &data, rct::key &hash) override;
|
||||
bool clsag_sign(const rct::key &c, const rct::key &a, const rct::key &p, const rct::key &z, const rct::key &mu_P, const rct::key &mu_C, rct::key &s) override;
|
||||
|
||||
bool add_tx_secret_key_to_tx_extra(std::vector<uint8_t>& tx_extra, const crypto::secret_key& key) override;
|
||||
|
||||
bool close_tx(void) override;
|
||||
};
|
||||
|
||||
|
|
|
@ -281,6 +281,7 @@ namespace hw {
|
|||
LEDGER_INS(OPEN_TX, 0x70);
|
||||
LEDGER_INS(SET_SIGNATURE_MODE, 0x72);
|
||||
LEDGER_INS(GET_ADDITIONAL_KEY, 0x74);
|
||||
LEDGER_INS(GET_TX_SECRET_KEY, 0x75);
|
||||
LEDGER_INS(STEALTH, 0x76);
|
||||
LEDGER_INS(GEN_COMMITMENT_MASK, 0x77);
|
||||
LEDGER_INS(BLIND, 0x78);
|
||||
|
@ -1324,7 +1325,7 @@ namespace hw {
|
|||
#endif
|
||||
}
|
||||
|
||||
bool device_ledger::open_tx(crypto::secret_key &tx_key) {
|
||||
bool device_ledger::open_tx(crypto::secret_key &tx_key, uint8_t txversion, uint8_t txtype) {
|
||||
auto locks = tools::unique_locks(device_locker, command_locker, *this);
|
||||
|
||||
key_map.clear();
|
||||
|
@ -1334,6 +1335,8 @@ namespace hw {
|
|||
|
||||
//account
|
||||
send_u32(0, offset);
|
||||
send_bytes(&txversion, 1, offset);
|
||||
send_bytes(&txtype, 1, offset);
|
||||
|
||||
finish_and_exchange(offset);
|
||||
|
||||
|
@ -1900,6 +1903,18 @@ namespace hw {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::add_tx_secret_key_to_tx_extra(std::vector<uint8_t>& tx_extra, const crypto::secret_key&) {
|
||||
auto locks = tools::unique_locks(device_locker, command_locker);
|
||||
|
||||
// This will fail if this isn't an open stake tx.
|
||||
send_simple(INS_GET_TX_SECRET_KEY);
|
||||
crypto::secret_key key; // Don't need to use the one passed in, the ledger has it stored already in internal state
|
||||
receive_bytes(key.data, 32);
|
||||
|
||||
cryptonote::add_tx_secret_key_to_tx_extra(tx_extra, key);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::close_tx() {
|
||||
auto locks = tools::unique_locks(device_locker, command_locker);
|
||||
|
|
|
@ -290,7 +290,7 @@ namespace hw {
|
|||
const crypto::public_key &R, const crypto::public_key &A, const std::optional<crypto::public_key> &B, const crypto::public_key &D, const crypto::secret_key &r,
|
||||
crypto::signature &sig) override;
|
||||
|
||||
bool open_tx(crypto::secret_key &tx_key) override;
|
||||
bool open_tx(crypto::secret_key &tx_key, uint8_t tx_version, uint8_t tx_type) override;
|
||||
|
||||
void get_transaction_prefix_hash(const cryptonote::transaction_prefix& tx, crypto::hash& h) override;
|
||||
|
||||
|
@ -321,6 +321,7 @@ namespace hw {
|
|||
bool clsag_hash(const rct::keyV &data, rct::key &hash) override;
|
||||
bool clsag_sign(const rct::key &c, const rct::key &a, const rct::key &p, const rct::key &z, const rct::key &mu_P, const rct::key &mu_C, rct::key &s) override;
|
||||
|
||||
bool add_tx_secret_key_to_tx_extra(std::vector<uint8_t>& tx_extra, const crypto::secret_key& key) override;
|
||||
|
||||
bool close_tx() override;
|
||||
|
||||
|
|
|
@ -58,7 +58,8 @@ TEST(device, open_close)
|
|||
{
|
||||
hw::core::device_default dev;
|
||||
crypto::secret_key key;
|
||||
ASSERT_TRUE(dev.open_tx(key));
|
||||
uint8_t version = 0, type = 0; // These get ignored for the default device so don't worry about them
|
||||
ASSERT_TRUE(dev.open_tx(key, version, type));
|
||||
ASSERT_TRUE(dev.close_tx());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue