diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/wallet2.cpp | 59 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 2 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 49 |
3 files changed, 91 insertions, 19 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 5b7b19520..3d3f1e4de 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -150,6 +150,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_ process_unconfirmed(tx); std::vector<size_t> outs; uint64_t tx_money_got_in_outs = 0; + crypto::public_key tx_pub_key = null_pkey; std::vector<tx_extra_field> tx_extra_fields; if(!parse_tx_extra(tx.extra, tx_extra_fields)) @@ -170,7 +171,7 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_ return; } - crypto::public_key tx_pub_key = pub_key_field.pub_key; + tx_pub_key = pub_key_field.pub_key; bool r = lookup_acc_outs(m_account.get_keys(), tx, tx_pub_key, outs, tx_money_got_in_outs); THROW_WALLET_EXCEPTION_IF(!r, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys()); @@ -236,9 +237,34 @@ void wallet2::process_new_transaction(const cryptonote::transaction& tx, uint64_ crypto::hash payment_id = null_hash; if (find_tx_extra_field_by_type(tx_extra_fields, extra_nonce)) { - if(get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id)) + crypto::hash8 payment_id8 = null_hash8; + if(get_encrypted_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id8)) { // We got a payment ID to go with this tx + LOG_PRINT_L2("Found encrypted payment ID: " << payment_id8); + if (tx_pub_key != null_pkey) + { + if (!decrypt_payment_id(payment_id8, tx_pub_key, m_account.get_keys().m_view_secret_key)) + { + LOG_PRINT_L0("Failed to decrypt payment ID: " << payment_id8); + } + else + { + LOG_PRINT_L2("Decrypted payment ID: " << payment_id8); + // put the 64 bit decrypted payment id in the first 8 bytes + memcpy(payment_id.data, payment_id8.data, 8); + // rest is already 0, but guard against code changes above + memset(payment_id.data + 8, 0, 24); + } + } + else + { + LOG_PRINT_L1("No public key found in tx, unable to decrypt payment id"); + } + } + else if (get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id)) + { + LOG_PRINT_L2("Found unencrypted payment ID: " << payment_id); } } uint64_t received = (tx_money_spent_in_ins < tx_money_got_in_outs) ? tx_money_got_in_outs - tx_money_spent_in_ins : 0; @@ -765,7 +791,7 @@ bool wallet2::wallet_valid_path_format(const std::string& file_path) return !file_path.empty(); } //---------------------------------------------------------------------------------------------------- -bool wallet2::parse_payment_id(const std::string& payment_id_str, crypto::hash& payment_id) +bool wallet2::parse_long_payment_id(const std::string& payment_id_str, crypto::hash& payment_id) { cryptonote::blobdata payment_id_data; if(!epee::string_tools::parse_hexstr_to_binbuff(payment_id_str, payment_id_data)) @@ -778,6 +804,33 @@ bool wallet2::parse_payment_id(const std::string& payment_id_str, crypto::hash& return true; } //---------------------------------------------------------------------------------------------------- +bool wallet2::parse_short_payment_id(const std::string& payment_id_str, crypto::hash8& payment_id) +{ + cryptonote::blobdata payment_id_data; + if(!epee::string_tools::parse_hexstr_to_binbuff(payment_id_str, payment_id_data)) + return false; + + if(sizeof(crypto::hash8) != payment_id_data.size()) + return false; + + payment_id = *reinterpret_cast<const crypto::hash8*>(payment_id_data.data()); + return true; +} +//---------------------------------------------------------------------------------------------------- +bool wallet2::parse_payment_id(const std::string& payment_id_str, crypto::hash& payment_id) +{ + if (parse_long_payment_id(payment_id_str, payment_id)) + return true; + crypto::hash8 payment_id8; + if (parse_short_payment_id(payment_id_str, payment_id8)) + { + memcpy(payment_id.data, payment_id8.data, 8); + memset(payment_id.data + 8, 0, 24); + return true; + } + return false; +} +//---------------------------------------------------------------------------------------------------- bool wallet2::prepare_file_names(const std::string& file_path) { do_prepare_file_names(file_path, m_keys_file, m_wallet_file); diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 93119cd0b..eee6aa58c 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -266,6 +266,8 @@ namespace tools */ static bool wallet_valid_path_format(const std::string& file_path); + static bool parse_long_payment_id(const std::string& payment_id_str, crypto::hash& payment_id); + static bool parse_short_payment_id(const std::string& payment_id_str, crypto::hash8& payment_id); static bool parse_payment_id(const std::string& payment_id_str, crypto::hash& payment_id); static std::vector<std::string> addresses_from_url(const std::string& url, bool& dnssec_valid); diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 1d38695ae..7dfd64eef 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -119,12 +119,13 @@ namespace tools //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::validate_transfer(const std::list<wallet_rpc::transfer_destination> destinations, std::string payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, epee::json_rpc::error& er) { - crypto::hash integrated_payment_id = cryptonote::null_hash; + crypto::hash8 integrated_payment_id = cryptonote::null_hash8; + std::string extra_nonce; for (auto it = destinations.begin(); it != destinations.end(); it++) { cryptonote::tx_destination_entry de; bool has_payment_id; - crypto::hash new_payment_id; + crypto::hash8 new_payment_id; if(!get_account_integrated_address_from_str(de.addr, has_payment_id, new_payment_id, m_wallet.testnet(), it->address)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; @@ -136,13 +137,14 @@ namespace tools if (has_payment_id) { - if (!payment_id.empty() || integrated_payment_id != cryptonote::null_hash) + if (!payment_id.empty() || integrated_payment_id != cryptonote::null_hash8) { er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; er.message = "A single payment id is allowed per transaction"; return false; } integrated_payment_id = new_payment_id; + cryptonote::set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, integrated_payment_id); } } @@ -152,17 +154,23 @@ namespace tools /* Just to clarify */ const std::string& payment_id_str = payment_id; - crypto::hash payment_id; + crypto::hash long_payment_id; + crypto::hash8 short_payment_id; + /* Parse payment ID */ - if (!wallet2::parse_payment_id(payment_id_str, payment_id)) { + if (wallet2::parse_long_payment_id(payment_id_str, long_payment_id)) { + cryptonote::set_payment_id_to_tx_extra_nonce(extra_nonce, long_payment_id); + } + /* or short payment ID */ + else if (!wallet2::parse_short_payment_id(payment_id_str, short_payment_id)) { + cryptonote::set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, short_payment_id); + } + else { er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; - er.message = "Payment id has invalid format: \"" + payment_id_str + "\", expected 64-character string"; + er.message = "Payment id has invalid format: \"" + payment_id_str + "\", expected 16 or 64 character string"; return false; } - std::string extra_nonce; - cryptonote::set_payment_id_to_tx_extra_nonce(extra_nonce, payment_id); - /* Append Payment ID data into extra */ if (!cryptonote::add_extra_nonce_to_tx_extra(extra, extra_nonce)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; @@ -339,14 +347,14 @@ namespace tools { try { - crypto::hash payment_id; + crypto::hash8 payment_id; if (req.payment_id.empty()) { - crypto::generate_random_bytes(32, payment_id.data); + crypto::generate_random_bytes(8, payment_id.data); } else { - if (!tools::wallet2::parse_payment_id(req.payment_id,payment_id)) + if (!tools::wallet2::parse_short_payment_id(req.payment_id,payment_id)) { er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; er.message = "Invalid payment ID"; @@ -371,7 +379,7 @@ namespace tools try { cryptonote::account_public_address address; - crypto::hash payment_id; + crypto::hash8 payment_id; bool has_payment_id; if(!get_account_integrated_address_from_str(address, has_payment_id, payment_id, m_wallet.testnet(), req.integrated_address)) @@ -485,6 +493,7 @@ namespace tools for (auto & payment_id_str : req.payment_ids) { crypto::hash payment_id; + crypto::hash8 payment_id8; cryptonote::blobdata payment_id_blob; // TODO - should the whole thing fail because of one bad id? @@ -496,15 +505,23 @@ namespace tools return false; } - if(sizeof(payment_id) != payment_id_blob.size()) + if(sizeof(payment_id) == payment_id_blob.size()) + { + payment_id = *reinterpret_cast<const crypto::hash*>(payment_id_blob.data()); + } + else if(sizeof(payment_id8) == payment_id_blob.size()) + { + payment_id8 = *reinterpret_cast<const crypto::hash8*>(payment_id_blob.data()); + memcpy(payment_id.data, payment_id8.data, 8); + memset(payment_id.data + 8, 0, 24); + } + else { er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID; er.message = "Payment ID has invalid size: " + payment_id_str; return false; } - payment_id = *reinterpret_cast<const crypto::hash*>(payment_id_blob.data()); - std::list<wallet2::payment_details> payment_list; m_wallet.get_payments(payment_id, payment_list, req.min_block_height); |