signmessage.cpp raw
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-present 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 <common/signmessage.h>
7 #include <key.h>
8 #include <key_io.h>
9 #include <rpc/protocol.h>
10 #include <rpc/request.h>
11 #include <rpc/server.h>
12 #include <rpc/util.h>
13 #include <univalue.h>
14
15 #include <string>
16
17 static RPCMethod verifymessage()
18 {
19 return RPCMethod{"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 RPCMethod& self, const JSONRPCRequest& request) -> UniValue
40 {
41 switch (MessageVerify(std::string{self.Arg<std::string_view>("address")},
42 std::string{self.Arg<std::string_view>("signature")},
43 std::string{self.Arg<std::string_view>("message")})) {
44 case MessageVerificationResult::ERR_INVALID_ADDRESS:
45 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
46 case MessageVerificationResult::ERR_ADDRESS_NO_KEY:
47 throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
48 case MessageVerificationResult::ERR_MALFORMED_SIGNATURE:
49 throw JSONRPCError(RPC_TYPE_ERROR, "Malformed base64 encoding");
50 case MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED:
51 case MessageVerificationResult::ERR_NOT_SIGNED:
52 return false;
53 case MessageVerificationResult::OK:
54 return true;
55 }
56
57 return false;
58 },
59 };
60 }
61
62 static RPCMethod signmessagewithprivkey()
63 {
64 return RPCMethod{
65 "signmessagewithprivkey",
66 "Sign a message with the private key of an address\n",
67 {
68 {"privkey", RPCArg::Type::STR, RPCArg::Optional::NO, "The private key to sign the message with."},
69 {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."},
70 },
71 RPCResult{
72 RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64"
73 },
74 RPCExamples{
75 "\nCreate the signature\n"
76 + HelpExampleCli("signmessagewithprivkey", "\"privkey\" \"my message\"") +
77 "\nVerify the signature\n"
78 + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
79 "\nAs a JSON-RPC call\n"
80 + HelpExampleRpc("signmessagewithprivkey", "\"privkey\", \"my message\"")
81 },
82 [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
83 {
84 std::string strPrivkey = request.params[0].get_str();
85 std::string strMessage = request.params[1].get_str();
86
87 CKey key = DecodeSecret(strPrivkey);
88 if (!key.IsValid()) {
89 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
90 }
91
92 std::string signature;
93
94 if (!MessageSign(key, strMessage, signature)) {
95 throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
96 }
97
98 return signature;
99 },
100 };
101 }
102
103 void RegisterSignMessageRPCCommands(CRPCTable& t)
104 {
105 static const CRPCCommand commands[]{
106 {"util", &verifymessage},
107 {"util", &signmessagewithprivkey},
108 };
109 for (const auto& c : commands) {
110 t.appendCommand(c.name, &c);
111 }
112 }
113