diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/wallet2.cpp | 68 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 5 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 45 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.h | 4 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server_commands_defs.h | 47 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server_error_codes.h | 1 |
6 files changed, 159 insertions, 11 deletions
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index a153967ce..d18681f36 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -53,6 +53,7 @@ using namespace epee; #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h" #include "common/json_util.h" +#include "common/base58.h" extern "C" { @@ -1435,22 +1436,39 @@ bool wallet2::prepare_file_names(const std::string& file_path) return true; } //---------------------------------------------------------------------------------------------------- -bool wallet2::check_connection() +bool wallet2::check_connection(bool *same_version) { boost::lock_guard<boost::mutex> lock(m_daemon_rpc_mutex); - if(m_http_client.is_connected()) - return true; + if(!m_http_client.is_connected()) + { + net_utils::http::url_content u; + net_utils::parse_url(m_daemon_address, u); - net_utils::http::url_content u; - net_utils::parse_url(m_daemon_address, u); + if(!u.port) + { + u.port = m_testnet ? config::testnet::RPC_DEFAULT_PORT : config::RPC_DEFAULT_PORT; + } - if(!u.port) + if (!m_http_client.connect(u.host, std::to_string(u.port), WALLET_RCP_CONNECTION_TIMEOUT)) + return false; + } + + if (same_version) { - u.port = m_testnet ? config::testnet::RPC_DEFAULT_PORT : config::RPC_DEFAULT_PORT; + epee::json_rpc::request<cryptonote::COMMAND_RPC_GET_VERSION::request> req_t = AUTO_VAL_INIT(req_t); + epee::json_rpc::response<cryptonote::COMMAND_RPC_GET_VERSION::response, std::string> resp_t = AUTO_VAL_INIT(resp_t); + req_t.jsonrpc = "2.0"; + req_t.id = epee::serialization::storage_entry(0); + req_t.method = "get_version"; + bool r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/json_rpc", req_t, resp_t, m_http_client); + if (!r || resp_t.result.status != CORE_RPC_STATUS_OK) + *same_version = false; + else + *same_version = resp_t.result.version == CORE_RPC_VERSION; } - return m_http_client.connect(u.host, std::to_string(u.port), WALLET_RCP_CONNECTION_TIMEOUT); + return true; } //---------------------------------------------------------------------------------------------------- bool wallet2::generate_chacha8_key_from_secret_keys(crypto::chacha8_key &key) const @@ -3106,6 +3124,40 @@ std::string wallet2::get_tx_note(const crypto::hash &txid) const return std::string(); return i->second; } + +std::string wallet2::sign(const std::string &data) const +{ + crypto::hash hash; + crypto::cn_fast_hash(data.data(), data.size(), hash); + const cryptonote::account_keys &keys = m_account.get_keys(); + crypto::signature signature; + crypto::generate_signature(hash, keys.m_account_address.m_spend_public_key, keys.m_spend_secret_key, signature); + return std::string("SigV1") + tools::base58::encode(std::string((const char *)&signature, sizeof(signature))); +} + +bool wallet2::verify(const std::string &data, const cryptonote::account_public_address &address, const std::string &signature) const +{ + const size_t header_len = strlen("SigV1"); + if (signature.size() < header_len || signature.substr(0, header_len) != "SigV1") { + LOG_PRINT_L0("Signature header check error"); + return false; + } + crypto::hash hash; + crypto::cn_fast_hash(data.data(), data.size(), hash); + std::string decoded; + if (!tools::base58::decode(signature.substr(header_len), decoded)) { + LOG_PRINT_L0("Signature decoding error"); + return false; + } + crypto::signature s; + if (sizeof(s) != decoded.size()) { + LOG_PRINT_L0("Signature decoding error"); + return false; + } + memcpy(&s, decoded.data(), sizeof(s)); + return crypto::check_signature(hash, address.m_spend_public_key, s); +} + //---------------------------------------------------------------------------------------------------- void wallet2::generate_genesis(cryptonote::block& b) { if (m_testnet) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index c5149a10c..d004b7da9 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -296,7 +296,7 @@ namespace tools std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint64_t fee_multiplier, const std::vector<uint8_t> extra, bool trusted_daemon); std::vector<wallet2::pending_tx> create_transactions_all(const cryptonote::account_public_address &address, const size_t fake_outs_count, const uint64_t unlock_time, uint64_t fee_multiplier, const std::vector<uint8_t> extra, bool trusted_daemon); std::vector<pending_tx> create_unmixable_sweep_transactions(bool trusted_daemon); - bool check_connection(); + bool check_connection(bool *same_version = NULL); void get_transfers(wallet2::transfer_container& incoming_transfers) const; void get_payments(const crypto::hash& payment_id, std::list<wallet2::payment_details>& payments, uint64_t min_height = 0) const; void get_payments(std::list<std::pair<crypto::hash,wallet2::payment_details>>& payments, uint64_t min_height, uint64_t max_height = (uint64_t)-1) const; @@ -386,6 +386,9 @@ namespace tools void set_tx_note(const crypto::hash &txid, const std::string ¬e); std::string get_tx_note(const crypto::hash &txid) const; + std::string sign(const std::string &data) const; + bool verify(const std::string &data, const cryptonote::account_public_address &address, const std::string &signature) const; + private: /*! * \brief Stores wallet information to wallet file. diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 01ae00fe5..5c42e1c53 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -168,6 +168,13 @@ namespace tools } integrated_payment_id = new_payment_id; cryptonote::set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, integrated_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; + er.message = "Something went wrong with integrated payment_id."; + return false; + } } } @@ -197,7 +204,7 @@ namespace tools /* 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; - er.message = "Something went wront with payment_id. Please check its format: \"" + payment_id_str + "\", expected 64-character string"; + er.message = "Something went wrong with payment_id. Please check its format: \"" + payment_id_str + "\", expected 64-character string"; return false; } @@ -747,6 +754,42 @@ namespace tools return true; } //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_sign(const wallet_rpc::COMMAND_RPC_SIGN::request& req, wallet_rpc::COMMAND_RPC_SIGN::response& res, epee::json_rpc::error& er) + { + if (m_wallet.restricted()) + { + er.code = WALLET_RPC_ERROR_CODE_DENIED; + er.message = "Command unavailable in restricted mode."; + return false; + } + + res.signature = m_wallet.sign(req.data); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_verify(const wallet_rpc::COMMAND_RPC_VERIFY::request& req, wallet_rpc::COMMAND_RPC_VERIFY::response& res, epee::json_rpc::error& er) + { + if (m_wallet.restricted()) + { + er.code = WALLET_RPC_ERROR_CODE_DENIED; + er.message = "Command unavailable in restricted mode."; + return false; + } + + cryptonote::account_public_address address; + bool has_payment_id; + crypto::hash8 payment_id; + if(!get_account_integrated_address_from_str(address, has_payment_id, payment_id, m_wallet.testnet(), req.address)) + { + er.code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS; + er.message = ""; + return false; + } + + res.good = m_wallet.verify(req.data, address, req.signature); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_stop_wallet(const wallet_rpc::COMMAND_RPC_STOP_WALLET::request& req, wallet_rpc::COMMAND_RPC_STOP_WALLET::response& res, epee::json_rpc::error& er) { if (m_wallet.restricted()) diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 8c90aecfe..205896332 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -80,6 +80,8 @@ namespace tools MAP_JON_RPC_WE("set_tx_notes", on_set_tx_notes, wallet_rpc::COMMAND_RPC_SET_TX_NOTES) MAP_JON_RPC_WE("get_tx_notes", on_get_tx_notes, wallet_rpc::COMMAND_RPC_GET_TX_NOTES) MAP_JON_RPC_WE("get_transfers", on_get_transfers, wallet_rpc::COMMAND_RPC_GET_TRANSFERS) + MAP_JON_RPC_WE("sign", on_sign, wallet_rpc::COMMAND_RPC_SIGN) + MAP_JON_RPC_WE("verify", on_verify, wallet_rpc::COMMAND_RPC_VERIFY) END_JSON_RPC_MAP() END_URI_MAP2() @@ -103,6 +105,8 @@ namespace tools bool on_set_tx_notes(const wallet_rpc::COMMAND_RPC_SET_TX_NOTES::request& req, wallet_rpc::COMMAND_RPC_SET_TX_NOTES::response& res, epee::json_rpc::error& er); bool on_get_tx_notes(const wallet_rpc::COMMAND_RPC_GET_TX_NOTES::request& req, wallet_rpc::COMMAND_RPC_GET_TX_NOTES::response& res, epee::json_rpc::error& er); bool on_get_transfers(const wallet_rpc::COMMAND_RPC_GET_TRANSFERS::request& req, wallet_rpc::COMMAND_RPC_GET_TRANSFERS::response& res, epee::json_rpc::error& er); + bool on_sign(const wallet_rpc::COMMAND_RPC_SIGN::request& req, wallet_rpc::COMMAND_RPC_SIGN::response& res, epee::json_rpc::error& er); + bool on_verify(const wallet_rpc::COMMAND_RPC_VERIFY::request& req, wallet_rpc::COMMAND_RPC_VERIFY::response& res, epee::json_rpc::error& er); bool handle_command_line(const boost::program_options::variables_map& vm); diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 3908476d6..1404340da 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -551,6 +551,51 @@ namespace wallet_rpc }; }; + struct COMMAND_RPC_SIGN + { + struct request + { + std::string data; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(data); + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string signature; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(signature); + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_RPC_VERIFY + { + struct request + { + std::string data; + std::string address; + std::string signature; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(data); + KV_SERIALIZE(address); + KV_SERIALIZE(signature); + END_KV_SERIALIZE_MAP() + }; + + struct response + { + bool good; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(good); + END_KV_SERIALIZE_MAP() + }; + }; + } } - diff --git a/src/wallet/wallet_rpc_server_error_codes.h b/src/wallet/wallet_rpc_server_error_codes.h index 968836671..68edfe76e 100644 --- a/src/wallet/wallet_rpc_server_error_codes.h +++ b/src/wallet/wallet_rpc_server_error_codes.h @@ -39,3 +39,4 @@ #define WALLET_RPC_ERROR_CODE_TRANSFER_TYPE -6 #define WALLET_RPC_ERROR_CODE_DENIED -7 #define WALLET_RPC_ERROR_CODE_WRONG_TXID -8 +#define WALLET_RPC_ERROR_CODE_WRONG_SIGNATURE -9 |