mirror of https://github.com/oxen-io/oxen-core.git
Error when trying to sign using a watch-only wallet
The cli wallet was correctly refusing to sign, but the RPC wallet (and wallet2 internally) allowed it and would sign with the all-0s address, which of course is invalid and fails to verify. This now throws if attempting to do so to get an error returned to the rpc endpoint. Other minor changes here: - make wallet2::verify static (verification doesn't depend on the wallet instance at all). - Add documentation for wallet2 sign/verify - Slight DRY of wallet2::sign
This commit is contained in:
parent
b6a83a49a5
commit
a842e3df74
|
@ -13049,20 +13049,20 @@ void wallet2::set_account_tag_description(const std::string& tag, const std::str
|
|||
|
||||
std::string wallet2::sign(std::string_view data, cryptonote::subaddress_index index) const
|
||||
{
|
||||
if (m_watch_only)
|
||||
throw std::logic_error{"Unable to sign with a watch-only wallet"};
|
||||
|
||||
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::secret_key skey;
|
||||
crypto::secret_key skey = keys.m_spend_secret_key;
|
||||
|
||||
crypto::public_key pkey;
|
||||
if (index.is_zero())
|
||||
{
|
||||
skey = keys.m_spend_secret_key;
|
||||
pkey = keys.m_account_address.m_spend_public_key;
|
||||
}
|
||||
else
|
||||
{
|
||||
skey = keys.m_spend_secret_key;
|
||||
crypto::secret_key m = m_account.get_device().get_subaddress_secret_key(keys.m_view_secret_key, index);
|
||||
sc_add((unsigned char*)&skey, (unsigned char*)&m, (unsigned char*)&skey);
|
||||
secret_key_to_public_key(skey, pkey);
|
||||
|
@ -13073,7 +13073,7 @@ std::string wallet2::sign(std::string_view data, cryptonote::subaddress_index in
|
|||
return result;
|
||||
}
|
||||
|
||||
bool wallet2::verify(std::string_view data, const cryptonote::account_public_address &address, std::string_view signature) const
|
||||
bool wallet2::verify(std::string_view data, const cryptonote::account_public_address &address, std::string_view signature)
|
||||
{
|
||||
if (!tools::starts_with(signature, SIG_MAGIC)) {
|
||||
LOG_PRINT_L0("Signature header check error");
|
||||
|
|
|
@ -1107,8 +1107,28 @@ private:
|
|||
*/
|
||||
void set_account_tag_description(const std::string& tag, const std::string& description);
|
||||
|
||||
/*!
|
||||
* \brief Signs an arbitrary string using the wallet's secret spend key.
|
||||
*
|
||||
* \param data the data to sign
|
||||
* \param index the subaccount/subaddress indices to use (if omitted: use main address)
|
||||
*
|
||||
* \return the signature.
|
||||
*
|
||||
* \throw std::logic_error if called on a view-only wallet.
|
||||
*/
|
||||
std::string sign(std::string_view data, cryptonote::subaddress_index index = {0, 0}) const;
|
||||
bool verify(std::string_view data, const cryptonote::account_public_address &address, std::string_view signature) const;
|
||||
|
||||
/*!
|
||||
* \brief Verifies a signed string.
|
||||
*
|
||||
* \param data - the data that has been signed.
|
||||
* \param address - the public address of the wallet that signed the data.
|
||||
* \param signature - the signature itself.
|
||||
*
|
||||
* \return true if the signature verified successfully, false if verification failed.
|
||||
*/
|
||||
static bool verify(std::string_view data, const cryptonote::account_public_address &address, std::string_view signature);
|
||||
|
||||
/*!
|
||||
* \brief sign_multisig_participant signs given message with the multisig public signer key
|
||||
|
|
|
@ -1695,6 +1695,9 @@ namespace tools
|
|||
SIGN::response wallet_rpc_server::invoke(SIGN::request&& req)
|
||||
{
|
||||
require_open();
|
||||
if (m_wallet->watch_only())
|
||||
throw wallet_rpc_error{error_code::WATCH_ONLY, "Unable to sign a value using a watch-only wallet."};
|
||||
|
||||
SIGN::response res{};
|
||||
|
||||
res.signature = m_wallet->sign(req.data, {req.account_index, req.address_index});
|
||||
|
|
Loading…
Reference in New Issue