Skip to content

Commit

Permalink
merge bitcoin#25013: Remove cs_main from verifymessage, move msg util…
Browse files Browse the repository at this point in the history
…s to new file
  • Loading branch information
kwvg committed Dec 20, 2024
1 parent 8e42b12 commit ad94a30
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 97 deletions.
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ libbitcoin_server_a_SOURCES = \
rpc/rawtransaction.cpp \
rpc/server.cpp \
rpc/server_util.cpp \
rpc/signmessage.cpp \
rpc/txoutproof.cpp \
script/sigcache.cpp \
shutdown.cpp \
Expand Down
98 changes: 1 addition & 97 deletions src/rpc/misc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,15 @@
#include <key_io.h>
#include <net.h>
#include <node/context.h>
#include <rpc/blockchain.h>
#include <rpc/index_util.h>
#include <rpc/server.h>
#include <rpc/server_util.h>
#include <rpc/util.h>
#include <scheduler.h>
#include <script/descriptor.h>
#include <txmempool.h>
#include <univalue.h>
#include <util/check.h>
#include <util/message.h> // For MessageSign(), MessageVerify()
#include <util/strencodings.h>
#include <util/system.h>
#include <validation.h>
Expand All @@ -42,8 +41,6 @@
#include <malloc.h>
#endif

#include <univalue.h>

static RPCHelpMan debug()
{
return RPCHelpMan{"debug",
Expand Down Expand Up @@ -475,97 +472,6 @@ static RPCHelpMan deriveaddresses()
};
}

static RPCHelpMan verifymessage()
{
return RPCHelpMan{"verifymessage",
"\nVerify a signed message\n",
{
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The Dash address to use for the signature."},
{"signature", RPCArg::Type::STR, RPCArg::Optional::NO, "The signature provided by the signer in base 64 encoding (see signmessage)."},
{"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message that was signed."},
},
RPCResult{
RPCResult::Type::BOOL, "", "If the signature is verified or not."
},
RPCExamples{
"\nUnlock the wallet for 30 seconds\n"
+ HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
"\nCreate the signature\n"
+ HelpExampleCli("signmessage", "\"" + EXAMPLE_ADDRESS[0] + "\" \"my message\"") +
"\nVerify the signature\n"
+ HelpExampleCli("verifymessage", "\"" + EXAMPLE_ADDRESS[0] + "\" \"signature\" \"my message\"") +
"\nAs a JSON-RPC call\n"
+ HelpExampleRpc("verifymessage", "\"" + EXAMPLE_ADDRESS[0] + "\", \"signature\", \"my message\"")
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{

LOCK(cs_main);

std::string strAddress = request.params[0].get_str();
std::string strSign = request.params[1].get_str();
std::string strMessage = request.params[2].get_str();

switch (MessageVerify(strAddress, strSign, strMessage)) {
case MessageVerificationResult::ERR_INVALID_ADDRESS:
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
case MessageVerificationResult::ERR_ADDRESS_NO_KEY:
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
case MessageVerificationResult::ERR_MALFORMED_SIGNATURE:
throw JSONRPCError(RPC_TYPE_ERROR, "Malformed base64 encoding");
case MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED:
case MessageVerificationResult::ERR_NOT_SIGNED:
return false;
case MessageVerificationResult::OK:
return true;
}

return false;
},
};
}

static RPCHelpMan signmessagewithprivkey()
{
return RPCHelpMan{"signmessagewithprivkey",
"\nSign a message with the private key of an address\n",
{
{"privkey", RPCArg::Type::STR, RPCArg::Optional::NO, "The private key to sign the message with."},
{"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."},
},
RPCResult{
RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64"
},
RPCExamples{
"\nCreate the signature\n"
+ HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") +
"\nVerify the signature\n"
+ HelpExampleCli("verifymessage", "\"" + EXAMPLE_ADDRESS[0] + "\" \"signature\" \"my message\"") +
"\nAs a JSON-RPC call\n"
+ HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"")
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{

std::string strPrivkey = request.params[0].get_str();
std::string strMessage = request.params[1].get_str();

CKey key = DecodeSecret(strPrivkey);
if (!key.IsValid()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
}

std::string signature;

if (!MessageSign(key, strMessage, signature)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
}

return signature;
},
};
}

static RPCHelpMan setmocktime()
{
return RPCHelpMan{"setmocktime",
Expand Down Expand Up @@ -1512,8 +1418,6 @@ static const CRPCCommand commands[] =
{ "util", &createmultisig, },
{ "util", &deriveaddresses, },
{ "util", &getdescriptorinfo, },
{ "util", &verifymessage, },
{ "util", &signmessagewithprivkey, },
{ "util", &getindexinfo, },
{ "blockchain", &getspentinfo, },

Expand Down
2 changes: 2 additions & 0 deletions src/rpc/register.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ void RegisterNetRPCCommands(CRPCTable &tableRPC);
void RegisterMiscRPCCommands(CRPCTable &tableRPC);
void RegisterMiningRPCCommands(CRPCTable &tableRPC);
void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC);
void RegisterSignMessageRPCCommands(CRPCTable&);
void RegisterMasternodeRPCCommands(CRPCTable &tableRPC);
void RegisterCoinJoinRPCCommands(CRPCTable &tableRPC);
void RegisterGovernanceRPCCommands(CRPCTable &tableRPC);
Expand All @@ -31,6 +32,7 @@ static inline void RegisterAllCoreRPCCommands(CRPCTable &t)
RegisterMiscRPCCommands(t);
RegisterMiningRPCCommands(t);
RegisterRawTransactionRPCCommands(t);
RegisterSignMessageRPCCommands(t);
RegisterMasternodeRPCCommands(t);
RegisterCoinJoinRPCCommands(t);
RegisterGovernanceRPCCommands(t);
Expand Down
114 changes: 114 additions & 0 deletions src/rpc/signmessage.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2022 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <key.h>
#include <key_io.h>
#include <rpc/protocol.h>
#include <rpc/request.h>
#include <rpc/server.h>
#include <rpc/util.h>
#include <univalue.h>
#include <util/message.h>

#include <string>

static RPCHelpMan verifymessage()
{
return RPCHelpMan{"verifymessage",
"\nVerify a signed message\n",
{
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The Dash address to use for the signature."},
{"signature", RPCArg::Type::STR, RPCArg::Optional::NO, "The signature provided by the signer in base 64 encoding (see signmessage)."},
{"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message that was signed."},
},
RPCResult{
RPCResult::Type::BOOL, "", "If the signature is verified or not."
},
RPCExamples{
"\nUnlock the wallet for 30 seconds\n"
+ HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
"\nCreate the signature\n"
+ HelpExampleCli("signmessage", "\"" + EXAMPLE_ADDRESS[0] + "\" \"my message\"") +
"\nVerify the signature\n"
+ HelpExampleCli("verifymessage", "\"" + EXAMPLE_ADDRESS[0] + "\" \"signature\" \"my message\"") +
"\nAs a JSON-RPC call\n"
+ HelpExampleRpc("verifymessage", "\"" + EXAMPLE_ADDRESS[0] + "\", \"signature\", \"my message\"")
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{
std::string strAddress = request.params[0].get_str();
std::string strSign = request.params[1].get_str();
std::string strMessage = request.params[2].get_str();

switch (MessageVerify(strAddress, strSign, strMessage)) {
case MessageVerificationResult::ERR_INVALID_ADDRESS:
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
case MessageVerificationResult::ERR_ADDRESS_NO_KEY:
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
case MessageVerificationResult::ERR_MALFORMED_SIGNATURE:
throw JSONRPCError(RPC_TYPE_ERROR, "Malformed base64 encoding");
case MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED:
case MessageVerificationResult::ERR_NOT_SIGNED:
return false;
case MessageVerificationResult::OK:
return true;
}

return false;
},
};
}

static RPCHelpMan signmessagewithprivkey()
{
return RPCHelpMan{"signmessagewithprivkey",
"\nSign a message with the private key of an address\n",
{
{"privkey", RPCArg::Type::STR, RPCArg::Optional::NO, "The private key to sign the message with."},
{"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."},
},
RPCResult{
RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64"
},
RPCExamples{
"\nCreate the signature\n"
+ HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") +
"\nVerify the signature\n"
+ HelpExampleCli("verifymessage", "\"" + EXAMPLE_ADDRESS[0] + "\" \"signature\" \"my message\"") +
"\nAs a JSON-RPC call\n"
+ HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"")
},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
{

std::string strPrivkey = request.params[0].get_str();
std::string strMessage = request.params[1].get_str();

CKey key = DecodeSecret(strPrivkey);
if (!key.IsValid()) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
}

std::string signature;

if (!MessageSign(key, strMessage, signature)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
}

return signature;
},
};
}

void RegisterSignMessageRPCCommands(CRPCTable& t)
{
static const CRPCCommand commands[]{
{"util", &verifymessage},
{"util", &signmessagewithprivkey},
};
for (const auto& c : commands) {
t.appendCommand(c.name, &c);
}
}

0 comments on commit ad94a30

Please sign in to comment.