Skip to content

Commit 91ac12b

Browse files
committed
Merge bitcoin/bitcoin#25013: Remove cs_main from verifymessage, move msg utils to new file
fa60169 rpc: Move signmessage RPC util to new file (MacroFake) fa94251 Remove cs_main from verifymessage (MacroFake) Pull request description: The `verifymessage` RPC has several issues: * It takes `cs_main` for no reason, blocking progress on removing the `cs_main` global mutex. * It is located in a file called `misc`, which is not a very helpful name. Fix all issues. ACKs for top commit: vincenzopalazzo: ACK bitcoin/bitcoin@fa60169 Tree-SHA512: c71a1f481b828e0a544405fecbbc7ca44e66ea46b498d7aed1f1c584d6a99724deb13e89d90b9d5cdeecbce293e6a41e9f7ae299543f6d761bf9e7a839b6c7f3
2 parents 91a6736 + fa60169 commit 91ac12b

File tree

5 files changed

+122
-96
lines changed

5 files changed

+122
-96
lines changed

ci/test/06_script_b.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,11 @@ if [ "${RUN_TIDY}" = "true" ]; then
3838
export P_CI_DIR="${BASE_BUILD_DIR}/bitcoin-$HOST/src/"
3939
CI_EXEC run-clang-tidy "${MAKEJOBS}"
4040
export P_CI_DIR="${BASE_BUILD_DIR}/bitcoin-$HOST/"
41-
CI_EXEC "python3 ${BASE_SCRATCH_DIR}/iwyu/include-what-you-use/iwyu_tool.py src/compat src/init -p . ${MAKEJOBS} -- -Xiwyu --cxx17ns -Xiwyu --mapping_file=${BASE_BUILD_DIR}/bitcoin-$HOST/contrib/devtools/iwyu/bitcoin.core.imp"
41+
CI_EXEC "python3 ${BASE_SCRATCH_DIR}/iwyu/include-what-you-use/iwyu_tool.py"\
42+
" src/compat"\
43+
" src/init"\
44+
" src/rpc/signmessage.cpp"\
45+
" -p . ${MAKEJOBS} -- -Xiwyu --cxx17ns -Xiwyu --mapping_file=${BASE_BUILD_DIR}/bitcoin-$HOST/contrib/devtools/iwyu/bitcoin.core.imp"
4246
fi
4347

4448
if [ "$RUN_SECURITY_TESTS" = "true" ]; then

src/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@ libbitcoin_node_a_SOURCES = \
386386
rpc/rawtransaction.cpp \
387387
rpc/server.cpp \
388388
rpc/server_util.cpp \
389+
rpc/signmessage.cpp \
389390
rpc/txoutproof.cpp \
390391
script/sigcache.cpp \
391392
shutdown.cpp \

src/rpc/misc.cpp

Lines changed: 1 addition & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,13 @@
1414
#include <key_io.h>
1515
#include <node/context.h>
1616
#include <outputtype.h>
17-
#include <rpc/blockchain.h>
1817
#include <rpc/server.h>
1918
#include <rpc/server_util.h>
2019
#include <rpc/util.h>
2120
#include <scheduler.h>
2221
#include <script/descriptor.h>
22+
#include <univalue.h>
2323
#include <util/check.h>
24-
#include <util/message.h> // For MessageSign(), MessageVerify()
2524
#include <util/strencodings.h>
2625
#include <util/syscall_sandbox.h>
2726
#include <util/system.h>
@@ -33,8 +32,6 @@
3332
#include <malloc.h>
3433
#endif
3534

36-
#include <univalue.h>
37-
3835
using node::NodeContext;
3936

4037
static RPCHelpMan validateaddress()
@@ -311,95 +308,6 @@ static RPCHelpMan deriveaddresses()
311308
};
312309
}
313310

314-
static RPCHelpMan verifymessage()
315-
{
316-
return RPCHelpMan{"verifymessage",
317-
"Verify a signed message.",
318-
{
319-
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the signature."},
320-
{"signature", RPCArg::Type::STR, RPCArg::Optional::NO, "The signature provided by the signer in base 64 encoding (see signmessage)."},
321-
{"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message that was signed."},
322-
},
323-
RPCResult{
324-
RPCResult::Type::BOOL, "", "If the signature is verified or not."
325-
},
326-
RPCExamples{
327-
"\nUnlock the wallet for 30 seconds\n"
328-
+ HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
329-
"\nCreate the signature\n"
330-
+ HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
331-
"\nVerify the signature\n"
332-
+ HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
333-
"\nAs a JSON-RPC call\n"
334-
+ HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"signature\", \"my message\"")
335-
},
336-
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
337-
{
338-
LOCK(cs_main);
339-
340-
std::string strAddress = request.params[0].get_str();
341-
std::string strSign = request.params[1].get_str();
342-
std::string strMessage = request.params[2].get_str();
343-
344-
switch (MessageVerify(strAddress, strSign, strMessage)) {
345-
case MessageVerificationResult::ERR_INVALID_ADDRESS:
346-
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
347-
case MessageVerificationResult::ERR_ADDRESS_NO_KEY:
348-
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
349-
case MessageVerificationResult::ERR_MALFORMED_SIGNATURE:
350-
throw JSONRPCError(RPC_TYPE_ERROR, "Malformed base64 encoding");
351-
case MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED:
352-
case MessageVerificationResult::ERR_NOT_SIGNED:
353-
return false;
354-
case MessageVerificationResult::OK:
355-
return true;
356-
}
357-
358-
return false;
359-
},
360-
};
361-
}
362-
363-
static RPCHelpMan signmessagewithprivkey()
364-
{
365-
return RPCHelpMan{"signmessagewithprivkey",
366-
"\nSign a message with the private key of an address\n",
367-
{
368-
{"privkey", RPCArg::Type::STR, RPCArg::Optional::NO, "The private key to sign the message with."},
369-
{"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."},
370-
},
371-
RPCResult{
372-
RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64"
373-
},
374-
RPCExamples{
375-
"\nCreate the signature\n"
376-
+ HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") +
377-
"\nVerify the signature\n"
378-
+ HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
379-
"\nAs a JSON-RPC call\n"
380-
+ HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"")
381-
},
382-
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
383-
{
384-
std::string strPrivkey = request.params[0].get_str();
385-
std::string strMessage = request.params[1].get_str();
386-
387-
CKey key = DecodeSecret(strPrivkey);
388-
if (!key.IsValid()) {
389-
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
390-
}
391-
392-
std::string signature;
393-
394-
if (!MessageSign(key, strMessage, signature)) {
395-
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
396-
}
397-
398-
return signature;
399-
},
400-
};
401-
}
402-
403311
static RPCHelpMan setmocktime()
404312
{
405313
return RPCHelpMan{"setmocktime",
@@ -799,8 +707,6 @@ void RegisterMiscRPCCommands(CRPCTable& t)
799707
{"util", &createmultisig},
800708
{"util", &deriveaddresses},
801709
{"util", &getdescriptorinfo},
802-
{"util", &verifymessage},
803-
{"util", &signmessagewithprivkey},
804710
{"util", &getindexinfo},
805711
{"hidden", &setmocktime},
806712
{"hidden", &mockscheduler},

src/rpc/register.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ void RegisterNetRPCCommands(CRPCTable &tableRPC);
1616
void RegisterMiscRPCCommands(CRPCTable &tableRPC);
1717
void RegisterMiningRPCCommands(CRPCTable &tableRPC);
1818
void RegisterRawTransactionRPCCommands(CRPCTable &tableRPC);
19+
void RegisterSignMessageRPCCommands(CRPCTable&);
1920
void RegisterSignerRPCCommands(CRPCTable &tableRPC);
2021

2122
static inline void RegisterAllCoreRPCCommands(CRPCTable &t)
@@ -27,6 +28,7 @@ static inline void RegisterAllCoreRPCCommands(CRPCTable &t)
2728
RegisterMiscRPCCommands(t);
2829
RegisterMiningRPCCommands(t);
2930
RegisterRawTransactionRPCCommands(t);
31+
RegisterSignMessageRPCCommands(t);
3032
#ifdef ENABLE_EXTERNAL_SIGNER
3133
RegisterSignerRPCCommands(t);
3234
#endif // ENABLE_EXTERNAL_SIGNER

src/rpc/signmessage.cpp

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
// Copyright (c) 2010 Satoshi Nakamoto
2+
// Copyright (c) 2009-2022 The Bitcoin Core developers
3+
// Distributed under the MIT software license, see the accompanying
4+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
6+
#include <key.h>
7+
#include <key_io.h>
8+
#include <rpc/protocol.h>
9+
#include <rpc/request.h>
10+
#include <rpc/server.h>
11+
#include <rpc/util.h>
12+
#include <univalue.h>
13+
#include <util/message.h>
14+
15+
#include <string>
16+
17+
static RPCHelpMan verifymessage()
18+
{
19+
return RPCHelpMan{"verifymessage",
20+
"Verify a signed message.",
21+
{
22+
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the signature."},
23+
{"signature", RPCArg::Type::STR, RPCArg::Optional::NO, "The signature provided by the signer in base 64 encoding (see signmessage)."},
24+
{"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message that was signed."},
25+
},
26+
RPCResult{
27+
RPCResult::Type::BOOL, "", "If the signature is verified or not."
28+
},
29+
RPCExamples{
30+
"\nUnlock the wallet for 30 seconds\n"
31+
+ HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
32+
"\nCreate the signature\n"
33+
+ HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
34+
"\nVerify the signature\n"
35+
+ HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
36+
"\nAs a JSON-RPC call\n"
37+
+ HelpExampleRpc("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"signature\", \"my message\"")
38+
},
39+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
40+
{
41+
std::string strAddress = request.params[0].get_str();
42+
std::string strSign = request.params[1].get_str();
43+
std::string strMessage = request.params[2].get_str();
44+
45+
switch (MessageVerify(strAddress, strSign, strMessage)) {
46+
case MessageVerificationResult::ERR_INVALID_ADDRESS:
47+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
48+
case MessageVerificationResult::ERR_ADDRESS_NO_KEY:
49+
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
50+
case MessageVerificationResult::ERR_MALFORMED_SIGNATURE:
51+
throw JSONRPCError(RPC_TYPE_ERROR, "Malformed base64 encoding");
52+
case MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED:
53+
case MessageVerificationResult::ERR_NOT_SIGNED:
54+
return false;
55+
case MessageVerificationResult::OK:
56+
return true;
57+
}
58+
59+
return false;
60+
},
61+
};
62+
}
63+
64+
static RPCHelpMan signmessagewithprivkey()
65+
{
66+
return RPCHelpMan{"signmessagewithprivkey",
67+
"\nSign a message with the private key of an address\n",
68+
{
69+
{"privkey", RPCArg::Type::STR, RPCArg::Optional::NO, "The private key to sign the message with."},
70+
{"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."},
71+
},
72+
RPCResult{
73+
RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64"
74+
},
75+
RPCExamples{
76+
"\nCreate the signature\n"
77+
+ HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") +
78+
"\nVerify the signature\n"
79+
+ HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
80+
"\nAs a JSON-RPC call\n"
81+
+ HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"")
82+
},
83+
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
84+
{
85+
std::string strPrivkey = request.params[0].get_str();
86+
std::string strMessage = request.params[1].get_str();
87+
88+
CKey key = DecodeSecret(strPrivkey);
89+
if (!key.IsValid()) {
90+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
91+
}
92+
93+
std::string signature;
94+
95+
if (!MessageSign(key, strMessage, signature)) {
96+
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
97+
}
98+
99+
return signature;
100+
},
101+
};
102+
}
103+
104+
void RegisterSignMessageRPCCommands(CRPCTable& t)
105+
{
106+
static const CRPCCommand commands[]{
107+
{"util", &verifymessage},
108+
{"util", &signmessagewithprivkey},
109+
};
110+
for (const auto& c : commands) {
111+
t.appendCommand(c.name, &c);
112+
}
113+
}

0 commit comments

Comments
 (0)