Skip to content

Commit fa60169

Browse files
author
MacroFake
committed
rpc: Move signmessage RPC util to new file
Can be reviewed with --color-moved=dimmed-zebra --color-moved-ws=ignore-all-space
1 parent fa94251 commit fa60169

File tree

5 files changed

+121
-91
lines changed

5 files changed

+121
-91
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
@@ -382,6 +382,7 @@ libbitcoin_node_a_SOURCES = \
382382
rpc/rawtransaction.cpp \
383383
rpc/server.cpp \
384384
rpc/server_util.cpp \
385+
rpc/signmessage.cpp \
385386
rpc/txoutproof.cpp \
386387
script/sigcache.cpp \
387388
shutdown.cpp \

src/rpc/misc.cpp

Lines changed: 0 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include <script/descriptor.h>
2222
#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>
@@ -309,93 +308,6 @@ static RPCHelpMan deriveaddresses()
309308
};
310309
}
311310

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