Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 6 additions & 19 deletions src/rpcmisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "net.h"
#include "netbase.h"
#include "rpcserver.h"
#include "script/generic.hpp"
#include "timedata.h"
#include "util.h"
#ifdef ENABLE_WALLET
Expand Down Expand Up @@ -347,31 +348,17 @@ Value verifymessage(const Array& params, bool fHelp)

string strAddress = params[0].get_str();
string strSign = params[1].get_str();
string strMessage = params[2].get_str();
string strMessage = strMessageMagic + params[2].get_str();

CBitcoinAddress addr(strAddress);
if (!addr.IsValid())
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");

CKeyID keyID;
if (!addr.GetKeyID(keyID))
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
std::vector<unsigned char> vchSig;
vchSig = DecodeBase64(strSign.c_str());
CScript sig(vchSig.begin(), vchSig.end());

bool fInvalid = false;
vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);

if (fInvalid)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");

CHashWriter ss(SER_GETHASH, 0);
ss << strMessageMagic;
ss << strMessage;

CPubKey pubkey;
if (!pubkey.RecoverCompact(ss.GetHash(), vchSig))
return false;

return (pubkey.GetID() == keyID);
return GenericVerifyScript(sig, GetScriptForDestination(addr.Get()), SCRIPT_VERIFY_P2SH, strMessage);
}

Value setmocktime(const Array& params, bool fHelp)
Expand Down
41 changes: 22 additions & 19 deletions src/rpcwallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "net.h"
#include "netbase.h"
#include "timedata.h"
#include "script/generic.hpp"
#include "util.h"
#include "utilmoneystr.h"
#include "wallet.h"
Expand Down Expand Up @@ -443,9 +444,9 @@ Value listaddressgroupings(const Array& params, bool fHelp)

Value signmessage(const Array& params, bool fHelp)
{
if (fHelp || params.size() != 2)
if (fHelp || params.size() < 2 || params.size() > 3)
throw runtime_error(
"signmessage \"bitcoinaddress\" \"message\"\n"
"signmessage \"bitcoinaddress\" \"message\" ( [\"sig1\", \"sig2\", ...] )\n"
"\nSign a message with the private key of an address"
+ HelpRequiringPassphrase() + "\n"
"\nArguments:\n"
Expand All @@ -467,29 +468,31 @@ Value signmessage(const Array& params, bool fHelp)
EnsureWalletIsUnlocked();

string strAddress = params[0].get_str();
string strMessage = params[1].get_str();
string strMessage = strMessageMagic + params[1].get_str();

CBitcoinAddress addr(strAddress);
if (!addr.IsValid())
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
CScript pubkey = GetScriptForDestination(addr.Get());

vector<CScript> vchSigs;
if (params.size() > 2) {
Array arr = params[2].get_array();
BOOST_FOREACH(const Value &o, arr) {
std::vector<unsigned char> vch = ParseHex(o.get_str());
vchSigs.push_back(CScript(vch.begin(), vch.end()));
}
}
if (vchSigs.size() == 0) {
vchSigs.push_back(CScript());
}

CKeyID keyID;
if (!addr.GetKeyID(keyID))
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");

CKey key;
if (!pwalletMain->GetKey(keyID, key))
throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");

CHashWriter ss(SER_GETHASH, 0);
ss << strMessageMagic;
ss << strMessage;

vector<unsigned char> vchSig;
if (!key.SignCompact(ss.GetHash(), vchSig))
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
GenericSignScript(*pwalletMain, strMessage, pubkey, vchSigs[0]);
for (size_t i = 1; i < vchSigs.size(); i++) {
vchSigs[0] = GenericCombineSignatures(pubkey, strMessage, vchSigs[0], vchSigs[i]);
}

return EncodeBase64(&vchSig[0], vchSig.size());
return EncodeBase64(&vchSigs[0][0], vchSigs[0].size());
}

Value getreceivedbyaddress(const Array& params, bool fHelp)
Expand Down
1 change: 1 addition & 0 deletions src/script/generic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define H_BITCOIN_SCRIPT_GENERIC

#include "hash.h"
#include "keystore.h"
#include "script/interpreter.h"
#include "script/sign.h"

Expand Down
2 changes: 1 addition & 1 deletion src/test/rpc_wallet_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
BOOST_CHECK_NO_THROW(retValue = CallRPC("signmessage " + demoAddress.ToString() + " mymessage"));
BOOST_CHECK_THROW(CallRPC("signmessage"), runtime_error);
/* Should throw error because this address is not loaded in the wallet */
BOOST_CHECK_THROW(CallRPC("signmessage 1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ mymessage"), runtime_error);
BOOST_CHECK_NO_THROW(CallRPC("signmessage 1QFqqMUD55ZV3PJEJZtaKCsQmjLT6JkjvJ mymessage"));

/* missing arguments */
BOOST_CHECK_THROW(CallRPC("verifymessage " + demoAddress.ToString()), runtime_error);
Expand Down