Changeset View
Changeset View
Standalone View
Standalone View
src/rpc/misc.cpp
Show All 11 Lines | |||||
#include <node/context.h> | #include <node/context.h> | ||||
#include <outputtype.h> | #include <outputtype.h> | ||||
#include <rpc/blockchain.h> | #include <rpc/blockchain.h> | ||||
#include <rpc/server.h> | #include <rpc/server.h> | ||||
#include <rpc/util.h> | #include <rpc/util.h> | ||||
#include <scheduler.h> | #include <scheduler.h> | ||||
#include <script/descriptor.h> | #include <script/descriptor.h> | ||||
#include <util/check.h> | #include <util/check.h> | ||||
#include <util/message.h> // For MessageSign(), MessageVerify() | |||||
#include <util/ref.h> | #include <util/ref.h> | ||||
#include <util/strencodings.h> | #include <util/strencodings.h> | ||||
#include <util/system.h> | #include <util/system.h> | ||||
#include <util/validation.h> | |||||
#include <univalue.h> | #include <univalue.h> | ||||
#include <cstdint> | #include <cstdint> | ||||
#include <tuple> | #include <tuple> | ||||
#ifdef HAVE_MALLOC_INFO | #ifdef HAVE_MALLOC_INFO | ||||
#include <malloc.h> | #include <malloc.h> | ||||
#endif | #endif | ||||
▲ Show 20 Lines • Show All 305 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
.Check(request); | .Check(request); | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
std::string strAddress = request.params[0].get_str(); | std::string strAddress = request.params[0].get_str(); | ||||
std::string strSign = request.params[1].get_str(); | std::string strSign = request.params[1].get_str(); | ||||
std::string strMessage = request.params[2].get_str(); | std::string strMessage = request.params[2].get_str(); | ||||
CTxDestination destination = | switch (MessageVerify(config.GetChainParams(), strAddress, strSign, | ||||
DecodeDestination(strAddress, config.GetChainParams()); | strMessage)) { | ||||
if (!IsValidDestination(destination)) { | case MessageVerificationResult::ERR_INVALID_ADDRESS: | ||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address"); | throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address"); | ||||
} | case MessageVerificationResult::ERR_ADDRESS_NO_KEY: | ||||
const PKHash *pkhash = boost::get<PKHash>(&destination); | |||||
if (!pkhash) { | |||||
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); | throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); | ||||
} | case MessageVerificationResult::ERR_MALFORMED_SIGNATURE: | ||||
bool fInvalid = false; | |||||
std::vector<uint8_t> vchSig = DecodeBase64(strSign.c_str(), &fInvalid); | |||||
if (fInvalid) { | |||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, | ||||
"Malformed base64 encoding"); | "Malformed base64 encoding"); | ||||
} | case MessageVerificationResult::ERR_PUBKEY_NOT_RECOVERED: | ||||
case MessageVerificationResult::ERR_NOT_SIGNED: | |||||
CHashWriter ss(SER_GETHASH, 0); | |||||
ss << strMessageMagic; | |||||
ss << strMessage; | |||||
CPubKey pubkey; | |||||
if (!pubkey.RecoverCompact(ss.GetHash(), vchSig)) { | |||||
return false; | return false; | ||||
case MessageVerificationResult::OK: | |||||
return true; | |||||
} | } | ||||
return (pubkey.GetID() == *pkhash); | return false; | ||||
} | } | ||||
static UniValue signmessagewithprivkey(const Config &config, | static UniValue signmessagewithprivkey(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"signmessagewithprivkey", | "signmessagewithprivkey", | ||||
"Sign a message with the private key of an address\n", | "Sign a message with the private key of an address\n", | ||||
{ | { | ||||
Show All 20 Lines | static UniValue signmessagewithprivkey(const Config &config, | ||||
std::string strPrivkey = request.params[0].get_str(); | std::string strPrivkey = request.params[0].get_str(); | ||||
std::string strMessage = request.params[1].get_str(); | std::string strMessage = request.params[1].get_str(); | ||||
CKey key = DecodeSecret(strPrivkey); | CKey key = DecodeSecret(strPrivkey); | ||||
if (!key.IsValid()) { | if (!key.IsValid()) { | ||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key"); | ||||
} | } | ||||
CHashWriter ss(SER_GETHASH, 0); | std::string signature; | ||||
ss << strMessageMagic; | |||||
ss << strMessage; | |||||
std::vector<uint8_t> vchSig; | if (!MessageSign(key, strMessage, signature)) { | ||||
if (!key.SignCompact(ss.GetHash(), vchSig)) { | |||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed"); | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed"); | ||||
} | } | ||||
return EncodeBase64(vchSig.data(), vchSig.size()); | return signature; | ||||
} | } | ||||
static UniValue setmocktime(const Config &config, | static UniValue setmocktime(const Config &config, | ||||
const JSONRPCRequest &request) { | const JSONRPCRequest &request) { | ||||
RPCHelpMan{ | RPCHelpMan{ | ||||
"setmocktime", | "setmocktime", | ||||
"Set the local time to given timestamp (-regtest only)\n", | "Set the local time to given timestamp (-regtest only)\n", | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 323 Lines • Show Last 20 Lines |