Refactor: CDarkSendSigner (#1410)

* Refactor: CDarkSendSigner -> CMessageSigner + CMasternodeBroadcast::IsVinAssociatedWithPubkey

* move IsVinAssociatedWithPubkey to CMasternode

* static IsVinAssociatedWithPubkey -> no params IsInputAssociatedWithPubkey
This commit is contained in:
UdjinM6 2017-04-12 10:04:06 +03:00 committed by GitHub
parent f3b92a95d9
commit 98990b683a
17 changed files with 175 additions and 131 deletions

View File

@ -124,6 +124,7 @@ BITCOIN_CORE_H = \
masternodeconfig.h \ masternodeconfig.h \
memusage.h \ memusage.h \
merkleblock.h \ merkleblock.h \
messagesigner.h \
miner.h \ miner.h \
net.h \ net.h \
netbase.h \ netbase.h \
@ -211,6 +212,7 @@ libbitcoin_server_a_SOURCES = \
governance-votedb.cpp \ governance-votedb.cpp \
main.cpp \ main.cpp \
merkleblock.cpp \ merkleblock.cpp \
messagesigner.cpp \
miner.cpp \ miner.cpp \
net.cpp \ net.cpp \
netfulfilledman.cpp \ netfulfilledman.cpp \

View File

@ -1,6 +1,6 @@
#include "darksend.h" #include "darksend.h"
#include "darksend-relay.h" #include "darksend-relay.h"
#include "messagesigner.h"
CDarkSendRelay::CDarkSendRelay() CDarkSendRelay::CDarkSendRelay()
{ {
@ -42,17 +42,17 @@ bool CDarkSendRelay::Sign(std::string strSharedKey)
CKey key2; CKey key2;
CPubKey pubkey2; CPubKey pubkey2;
if(!darkSendSigner.GetKeysFromSecret(strSharedKey, key2, pubkey2)) { if(!CMessageSigner::GetKeysFromSecret(strSharedKey, key2, pubkey2)) {
LogPrintf("CDarkSendRelay::Sign -- GetKeysFromSecret() failed, invalid shared key %s\n", strSharedKey); LogPrintf("CDarkSendRelay::Sign -- GetKeysFromSecret() failed, invalid shared key %s\n", strSharedKey);
return false; return false;
} }
if(!darkSendSigner.SignMessage(strMessage, vchSig2, key2)) { if(!CMessageSigner::SignMessage(strMessage, vchSig2, key2)) {
LogPrintf("CDarkSendRelay::Sign -- SignMessage() failed\n"); LogPrintf("CDarkSendRelay::Sign -- SignMessage() failed\n");
return false; return false;
} }
if(!darkSendSigner.VerifyMessage(pubkey2, vchSig2, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(pubkey2, vchSig2, strMessage, strError)) {
LogPrintf("CDarkSendRelay::Sign -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("CDarkSendRelay::Sign -- VerifyMessage() failed, error: %s\n", strError);
return false; return false;
} }
@ -68,12 +68,12 @@ bool CDarkSendRelay::VerifyMessage(std::string strSharedKey)
CKey key2; CKey key2;
CPubKey pubkey2; CPubKey pubkey2;
if(!darkSendSigner.GetKeysFromSecret(strSharedKey, key2, pubkey2)) { if(!CMessageSigner::GetKeysFromSecret(strSharedKey, key2, pubkey2)) {
LogPrintf("CDarkSendRelay::VerifyMessage -- GetKeysFromSecret() failed, invalid shared key %s\n", strSharedKey); LogPrintf("CDarkSendRelay::VerifyMessage -- GetKeysFromSecret() failed, invalid shared key %s\n", strSharedKey);
return false; return false;
} }
if(!darkSendSigner.VerifyMessage(pubkey2, vchSig2, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(pubkey2, vchSig2, strMessage, strError)) {
LogPrintf("CDarkSendRelay::VerifyMessage -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("CDarkSendRelay::VerifyMessage -- VerifyMessage() failed, error: %s\n", strError);
return false; return false;
} }

View File

@ -12,6 +12,7 @@
#include "masternode-payments.h" #include "masternode-payments.h"
#include "masternode-sync.h" #include "masternode-sync.h"
#include "masternodeman.h" #include "masternodeman.h"
#include "messagesigner.h"
#include "script/sign.h" #include "script/sign.h"
#include "txmempool.h" #include "txmempool.h"
#include "util.h" #include "util.h"
@ -26,7 +27,6 @@ bool fEnablePrivateSend = false;
bool fPrivateSendMultiSession = DEFAULT_PRIVATESEND_MULTISESSION; bool fPrivateSendMultiSession = DEFAULT_PRIVATESEND_MULTISESSION;
CDarksendPool darkSendPool; CDarksendPool darkSendPool;
CDarkSendSigner darkSendSigner;
std::map<uint256, CDarksendBroadcastTx> mapDarksendBroadcastTxes; std::map<uint256, CDarksendBroadcastTx> mapDarksendBroadcastTxes;
std::vector<CAmount> vecPrivateSendDenominations; std::vector<CAmount> vecPrivateSendDenominations;
@ -2258,64 +2258,6 @@ std::string CDarksendPool::GetMessageByID(PoolMessage nMessageID)
} }
} }
bool CDarkSendSigner::IsVinAssociatedWithPubkey(const CTxIn& txin, const CPubKey& pubkey)
{
CScript payee;
payee = GetScriptForDestination(pubkey.GetID());
CTransaction tx;
uint256 hash;
if(GetTransaction(txin.prevout.hash, tx, Params().GetConsensus(), hash, true)) {
BOOST_FOREACH(CTxOut out, tx.vout)
if(out.nValue == 1000*COIN && out.scriptPubKey == payee) return true;
}
return false;
}
bool CDarkSendSigner::GetKeysFromSecret(std::string strSecret, CKey& keyRet, CPubKey& pubkeyRet)
{
CBitcoinSecret vchSecret;
if(!vchSecret.SetString(strSecret)) return false;
keyRet = vchSecret.GetKey();
pubkeyRet = keyRet.GetPubKey();
return true;
}
bool CDarkSendSigner::SignMessage(std::string strMessage, std::vector<unsigned char>& vchSigRet, CKey key)
{
CHashWriter ss(SER_GETHASH, 0);
ss << strMessageMagic;
ss << strMessage;
return key.SignCompact(ss.GetHash(), vchSigRet);
}
bool CDarkSendSigner::VerifyMessage(CPubKey pubkey, const std::vector<unsigned char>& vchSig, std::string strMessage, std::string& strErrorRet)
{
CHashWriter ss(SER_GETHASH, 0);
ss << strMessageMagic;
ss << strMessage;
CPubKey pubkeyFromSig;
if(!pubkeyFromSig.RecoverCompact(ss.GetHash(), vchSig)) {
strErrorRet = "Error recovering public key.";
return false;
}
if(pubkeyFromSig.GetID() != pubkey.GetID()) {
strErrorRet = strprintf("Keys don't match: pubkey=%s, pubkeyFromSig=%s, strMessage=%s, vchSig=%s",
pubkey.GetID().ToString(), pubkeyFromSig.GetID().ToString(), strMessage,
EncodeBase64(&vchSig[0], vchSig.size()));
return false;
}
return true;
}
bool CDarkSendEntry::AddScriptSig(const CTxIn& txin) bool CDarkSendEntry::AddScriptSig(const CTxIn& txin)
{ {
BOOST_FOREACH(CTxDSIn& txdsin, vecTxDSIn) { BOOST_FOREACH(CTxDSIn& txdsin, vecTxDSIn) {
@ -2339,7 +2281,7 @@ bool CDarksendQueue::Sign()
std::string strMessage = vin.ToString() + boost::lexical_cast<std::string>(nDenom) + boost::lexical_cast<std::string>(nTime) + boost::lexical_cast<std::string>(fReady); std::string strMessage = vin.ToString() + boost::lexical_cast<std::string>(nDenom) + boost::lexical_cast<std::string>(nTime) + boost::lexical_cast<std::string>(fReady);
if(!darkSendSigner.SignMessage(strMessage, vchSig, activeMasternode.keyMasternode)) { if(!CMessageSigner::SignMessage(strMessage, vchSig, activeMasternode.keyMasternode)) {
LogPrintf("CDarksendQueue::Sign -- SignMessage() failed, %s\n", ToString()); LogPrintf("CDarksendQueue::Sign -- SignMessage() failed, %s\n", ToString());
return false; return false;
} }
@ -2352,7 +2294,7 @@ bool CDarksendQueue::CheckSignature(const CPubKey& pubKeyMasternode)
std::string strMessage = vin.ToString() + boost::lexical_cast<std::string>(nDenom) + boost::lexical_cast<std::string>(nTime) + boost::lexical_cast<std::string>(fReady); std::string strMessage = vin.ToString() + boost::lexical_cast<std::string>(nDenom) + boost::lexical_cast<std::string>(nTime) + boost::lexical_cast<std::string>(fReady);
std::string strError = ""; std::string strError = "";
if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
LogPrintf("CDarksendQueue::CheckSignature -- Got bad Masternode queue signature: %s; error: %s\n", ToString(), strError); LogPrintf("CDarksendQueue::CheckSignature -- Got bad Masternode queue signature: %s; error: %s\n", ToString(), strError);
return false; return false;
} }
@ -2377,7 +2319,7 @@ bool CDarksendBroadcastTx::Sign()
std::string strMessage = tx.GetHash().ToString() + boost::lexical_cast<std::string>(sigTime); std::string strMessage = tx.GetHash().ToString() + boost::lexical_cast<std::string>(sigTime);
if(!darkSendSigner.SignMessage(strMessage, vchSig, activeMasternode.keyMasternode)) { if(!CMessageSigner::SignMessage(strMessage, vchSig, activeMasternode.keyMasternode)) {
LogPrintf("CDarksendBroadcastTx::Sign -- SignMessage() failed\n"); LogPrintf("CDarksendBroadcastTx::Sign -- SignMessage() failed\n");
return false; return false;
} }
@ -2390,7 +2332,7 @@ bool CDarksendBroadcastTx::CheckSignature(const CPubKey& pubKeyMasternode)
std::string strMessage = tx.GetHash().ToString() + boost::lexical_cast<std::string>(sigTime); std::string strMessage = tx.GetHash().ToString() + boost::lexical_cast<std::string>(sigTime);
std::string strError = ""; std::string strError = "";
if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
LogPrintf("CDarksendBroadcastTx::CheckSignature -- Got bad dstx signature, error: %s\n", strError); LogPrintf("CDarksendBroadcastTx::CheckSignature -- Got bad dstx signature, error: %s\n", strError);
return false; return false;
} }

View File

@ -9,7 +9,6 @@
#include "wallet/wallet.h" #include "wallet/wallet.h"
class CDarksendPool; class CDarksendPool;
class CDarkSendSigner;
class CDarksendBroadcastTx; class CDarksendBroadcastTx;
// timeouts // timeouts
@ -44,8 +43,6 @@ extern bool fPrivateSendMultiSession;
// The main object for accessing mixing // The main object for accessing mixing
extern CDarksendPool darkSendPool; extern CDarksendPool darkSendPool;
// A helper object for signing messages from Masternodes
extern CDarkSendSigner darkSendSigner;
extern std::map<uint256, CDarksendBroadcastTx> mapDarksendBroadcastTxes; extern std::map<uint256, CDarksendBroadcastTx> mapDarksendBroadcastTxes;
extern std::vector<CAmount> vecPrivateSendDenominations; extern std::vector<CAmount> vecPrivateSendDenominations;
@ -234,21 +231,6 @@ public:
bool CheckSignature(const CPubKey& pubKeyMasternode); bool CheckSignature(const CPubKey& pubKeyMasternode);
}; };
/** Helper object for signing and checking signatures
*/
class CDarkSendSigner
{
public:
/// Is the input associated with this public key? (and there is 1000 DASH - checking if valid masternode)
bool IsVinAssociatedWithPubkey(const CTxIn& vin, const CPubKey& pubkey);
/// Set the private/public key values, returns true if successful
bool GetKeysFromSecret(std::string strSecret, CKey& keyRet, CPubKey& pubkeyRet);
/// Sign the message, returns true if successful
bool SignMessage(std::string strMessage, std::vector<unsigned char>& vchSigRet, CKey key);
/// Verify the message, returns true if succcessful
bool VerifyMessage(CPubKey pubkey, const std::vector<unsigned char>& vchSig, std::string strMessage, std::string& strErrorRet);
};
/** Used to keep track of current status of mixing pool /** Used to keep track of current status of mixing pool
*/ */
class CDarksendPool class CDarksendPool

View File

@ -3,12 +3,12 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "core_io.h" #include "core_io.h"
#include "darksend.h"
#include "governance.h" #include "governance.h"
#include "governance-classes.h" #include "governance-classes.h"
#include "governance-object.h" #include "governance-object.h"
#include "governance-vote.h" #include "governance-vote.h"
#include "masternodeman.h" #include "masternodeman.h"
#include "messagesigner.h"
#include "util.h" #include "util.h"
#include <univalue.h> #include <univalue.h>
@ -260,12 +260,12 @@ bool CGovernanceObject::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode)
LOCK(cs); LOCK(cs);
if(!darkSendSigner.SignMessage(strMessage, vchSig, keyMasternode)) { if(!CMessageSigner::SignMessage(strMessage, vchSig, keyMasternode)) {
LogPrintf("CGovernanceObject::Sign -- SignMessage() failed\n"); LogPrintf("CGovernanceObject::Sign -- SignMessage() failed\n");
return false; return false;
} }
if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
LogPrintf("CGovernanceObject::Sign -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("CGovernanceObject::Sign -- VerifyMessage() failed, error: %s\n", strError);
return false; return false;
} }
@ -284,7 +284,7 @@ bool CGovernanceObject::CheckSignature(CPubKey& pubKeyMasternode)
std::string strMessage = GetSignatureMessage(); std::string strMessage = GetSignatureMessage();
LOCK(cs); LOCK(cs);
if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
LogPrintf("CGovernance::CheckSignature -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("CGovernance::CheckSignature -- VerifyMessage() failed, error: %s\n", strError);
return false; return false;
} }

View File

@ -2,9 +2,9 @@
// Distributed under the MIT/X11 software license, see the accompanying // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "darksend.h"
#include "governance-vote.h" #include "governance-vote.h"
#include "masternodeman.h" #include "masternodeman.h"
#include "messagesigner.h"
#include "util.h" #include "util.h"
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
@ -239,12 +239,12 @@ bool CGovernanceVote::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode)
std::string strMessage = vinMasternode.prevout.ToStringShort() + "|" + nParentHash.ToString() + "|" + std::string strMessage = vinMasternode.prevout.ToStringShort() + "|" + nParentHash.ToString() + "|" +
boost::lexical_cast<std::string>(nVoteSignal) + "|" + boost::lexical_cast<std::string>(nVoteOutcome) + "|" + boost::lexical_cast<std::string>(nTime); boost::lexical_cast<std::string>(nVoteSignal) + "|" + boost::lexical_cast<std::string>(nVoteOutcome) + "|" + boost::lexical_cast<std::string>(nTime);
if(!darkSendSigner.SignMessage(strMessage, vchSig, keyMasternode)) { if(!CMessageSigner::SignMessage(strMessage, vchSig, keyMasternode)) {
LogPrintf("CGovernanceVote::Sign -- SignMessage() failed\n"); LogPrintf("CGovernanceVote::Sign -- SignMessage() failed\n");
return false; return false;
} }
if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
LogPrintf("CGovernanceVote::Sign -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("CGovernanceVote::Sign -- VerifyMessage() failed, error: %s\n", strError);
return false; return false;
} }
@ -285,7 +285,7 @@ bool CGovernanceVote::IsValid(bool fSignatureCheck) const
std::string strMessage = vinMasternode.prevout.ToStringShort() + "|" + nParentHash.ToString() + "|" + std::string strMessage = vinMasternode.prevout.ToStringShort() + "|" + nParentHash.ToString() + "|" +
boost::lexical_cast<std::string>(nVoteSignal) + "|" + boost::lexical_cast<std::string>(nVoteOutcome) + "|" + boost::lexical_cast<std::string>(nTime); boost::lexical_cast<std::string>(nVoteSignal) + "|" + boost::lexical_cast<std::string>(nVoteOutcome) + "|" + boost::lexical_cast<std::string>(nTime);
if(!darkSendSigner.VerifyMessage(infoMn.pubKeyMasternode, vchSig, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(infoMn.pubKeyMasternode, vchSig, strMessage, strError)) {
LogPrintf("CGovernanceVote::IsValid -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("CGovernanceVote::IsValid -- VerifyMessage() failed, error: %s\n", strError);
return false; return false;
} }

View File

@ -2,7 +2,6 @@
// Distributed under the MIT/X11 software license, see the accompanying // Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "darksend.h"
#include "governance.h" #include "governance.h"
#include "governance-object.h" #include "governance-object.h"
#include "governance-vote.h" #include "governance-vote.h"
@ -11,6 +10,7 @@
#include "masternode.h" #include "masternode.h"
#include "masternode-sync.h" #include "masternode-sync.h"
#include "masternodeman.h" #include "masternodeman.h"
#include "messagesigner.h"
#include "netfulfilledman.h" #include "netfulfilledman.h"
#include "util.h" #include "util.h"

View File

@ -56,6 +56,7 @@
#include "masternode-sync.h" #include "masternode-sync.h"
#include "masternodeman.h" #include "masternodeman.h"
#include "masternodeconfig.h" #include "masternodeconfig.h"
#include "messagesigner.h"
#include "netfulfilledman.h" #include "netfulfilledman.h"
#include "spork.h" #include "spork.h"
@ -1807,7 +1808,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
std::string strMasterNodePrivKey = GetArg("-masternodeprivkey", ""); std::string strMasterNodePrivKey = GetArg("-masternodeprivkey", "");
if(!strMasterNodePrivKey.empty()) { if(!strMasterNodePrivKey.empty()) {
if(!darkSendSigner.GetKeysFromSecret(strMasterNodePrivKey, activeMasternode.keyMasternode, activeMasternode.pubKeyMasternode)) if(!CMessageSigner::GetKeysFromSecret(strMasterNodePrivKey, activeMasternode.keyMasternode, activeMasternode.pubKeyMasternode))
return InitError(_("Invalid masternodeprivkey. Please see documenation.")); return InitError(_("Invalid masternodeprivkey. Please see documenation."));
LogPrintf(" pubKeyMasternode: %s\n", CBitcoinAddress(activeMasternode.pubKeyMasternode.GetID()).ToString()); LogPrintf(" pubKeyMasternode: %s\n", CBitcoinAddress(activeMasternode.pubKeyMasternode.GetID()).ToString());

View File

@ -3,12 +3,12 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "activemasternode.h" #include "activemasternode.h"
#include "darksend.h"
#include "instantx.h" #include "instantx.h"
#include "key.h" #include "key.h"
#include "main.h" #include "main.h"
#include "masternode-sync.h" #include "masternode-sync.h"
#include "masternodeman.h" #include "masternodeman.h"
#include "messagesigner.h"
#include "net.h" #include "net.h"
#include "protocol.h" #include "protocol.h"
#include "spork.h" #include "spork.h"
@ -1031,7 +1031,7 @@ bool CTxLockVote::CheckSignature() const
return false; return false;
} }
if(!darkSendSigner.VerifyMessage(infoMn.pubKeyMasternode, vchMasternodeSignature, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(infoMn.pubKeyMasternode, vchMasternodeSignature, strMessage, strError)) {
LogPrintf("CTxLockVote::CheckSignature -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("CTxLockVote::CheckSignature -- VerifyMessage() failed, error: %s\n", strError);
return false; return false;
} }
@ -1044,12 +1044,12 @@ bool CTxLockVote::Sign()
std::string strError; std::string strError;
std::string strMessage = txHash.ToString() + outpoint.ToStringShort(); std::string strMessage = txHash.ToString() + outpoint.ToStringShort();
if(!darkSendSigner.SignMessage(strMessage, vchMasternodeSignature, activeMasternode.keyMasternode)) { if(!CMessageSigner::SignMessage(strMessage, vchMasternodeSignature, activeMasternode.keyMasternode)) {
LogPrintf("CTxLockVote::Sign -- SignMessage() failed\n"); LogPrintf("CTxLockVote::Sign -- SignMessage() failed\n");
return false; return false;
} }
if(!darkSendSigner.VerifyMessage(activeMasternode.pubKeyMasternode, vchMasternodeSignature, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(activeMasternode.pubKeyMasternode, vchMasternodeSignature, strMessage, strError)) {
LogPrintf("CTxLockVote::Sign -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("CTxLockVote::Sign -- VerifyMessage() failed, error: %s\n", strError);
return false; return false;
} }

View File

@ -3,11 +3,11 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "activemasternode.h" #include "activemasternode.h"
#include "darksend.h"
#include "governance-classes.h" #include "governance-classes.h"
#include "masternode-payments.h" #include "masternode-payments.h"
#include "masternode-sync.h" #include "masternode-sync.h"
#include "masternodeman.h" #include "masternodeman.h"
#include "messagesigner.h"
#include "netfulfilledman.h" #include "netfulfilledman.h"
#include "spork.h" #include "spork.h"
#include "util.h" #include "util.h"
@ -421,12 +421,12 @@ bool CMasternodePaymentVote::Sign()
boost::lexical_cast<std::string>(nBlockHeight) + boost::lexical_cast<std::string>(nBlockHeight) +
ScriptToAsmStr(payee); ScriptToAsmStr(payee);
if(!darkSendSigner.SignMessage(strMessage, vchSig, activeMasternode.keyMasternode)) { if(!CMessageSigner::SignMessage(strMessage, vchSig, activeMasternode.keyMasternode)) {
LogPrintf("CMasternodePaymentVote::Sign -- SignMessage() failed\n"); LogPrintf("CMasternodePaymentVote::Sign -- SignMessage() failed\n");
return false; return false;
} }
if(!darkSendSigner.VerifyMessage(activeMasternode.pubKeyMasternode, vchSig, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(activeMasternode.pubKeyMasternode, vchSig, strMessage, strError)) {
LogPrintf("CMasternodePaymentVote::Sign -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("CMasternodePaymentVote::Sign -- VerifyMessage() failed, error: %s\n", strError);
return false; return false;
} }
@ -793,7 +793,7 @@ bool CMasternodePaymentVote::CheckSignature(const CPubKey& pubKeyMasternode, int
ScriptToAsmStr(payee); ScriptToAsmStr(payee);
std::string strError = ""; std::string strError = "";
if (!darkSendSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) { if (!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
// Only ban for future block vote when we are already synced. // Only ban for future block vote when we are already synced.
// Otherwise it could be the case when MN which signed this vote is using another key now // Otherwise it could be the case when MN which signed this vote is using another key now
// and we have no idea about the old one. // and we have no idea about the old one.

View File

@ -4,13 +4,13 @@
#include "activemasternode.h" #include "activemasternode.h"
#include "consensus/validation.h" #include "consensus/validation.h"
#include "darksend.h"
#include "init.h" #include "init.h"
#include "governance.h" #include "governance.h"
#include "masternode.h" #include "masternode.h"
#include "masternode-payments.h" #include "masternode-payments.h"
#include "masternode-sync.h" #include "masternode-sync.h"
#include "masternodeman.h" #include "masternodeman.h"
#include "messagesigner.h"
#include "util.h" #include "util.h"
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
@ -282,6 +282,21 @@ void CMasternode::Check(bool fForce)
} }
} }
bool CMasternode::IsInputAssociatedWithPubkey()
{
CScript payee;
payee = GetScriptForDestination(pubKeyCollateralAddress.GetID());
CTransaction tx;
uint256 hash;
if(GetTransaction(vin.prevout.hash, tx, Params().GetConsensus(), hash, true)) {
BOOST_FOREACH(CTxOut out, tx.vout)
if(out.nValue == 1000*COIN && out.scriptPubKey == payee) return true;
}
return false;
}
bool CMasternode::IsValidNetAddr() bool CMasternode::IsValidNetAddr()
{ {
return IsValidNetAddr(addr); return IsValidNetAddr(addr);
@ -415,7 +430,7 @@ bool CMasternodeBroadcast::Create(std::string strService, std::string strKeyMast
return false; return false;
} }
if(!darkSendSigner.GetKeysFromSecret(strKeyMasternode, keyMasternodeNew, pubKeyMasternodeNew)) { if(!CMessageSigner::GetKeysFromSecret(strKeyMasternode, keyMasternodeNew, pubKeyMasternodeNew)) {
strErrorRet = strprintf("Invalid masternode key %s", strKeyMasternode); strErrorRet = strprintf("Invalid masternode key %s", strKeyMasternode);
LogPrintf("CMasternodeBroadcast::Create -- %s\n", strErrorRet); LogPrintf("CMasternodeBroadcast::Create -- %s\n", strErrorRet);
return false; return false;
@ -639,9 +654,9 @@ bool CMasternodeBroadcast::CheckOutpoint(int& nDos)
LogPrint("masternode", "CMasternodeBroadcast::CheckOutpoint -- Masternode UTXO verified\n"); LogPrint("masternode", "CMasternodeBroadcast::CheckOutpoint -- Masternode UTXO verified\n");
// make sure the vout that was signed is related to the transaction that spawned the Masternode // make sure the input that was signed in masternode broadcast message is related to the transaction
// - this is expensive, so it's only done once per Masternode // that spawned the Masternode - this is expensive, so it's only done once per Masternode
if(!darkSendSigner.IsVinAssociatedWithPubkey(vin, pubKeyCollateralAddress)) { if(!IsInputAssociatedWithPubkey()) {
LogPrintf("CMasternodeMan::CheckOutpoint -- Got mismatched pubKeyCollateralAddress and vin\n"); LogPrintf("CMasternodeMan::CheckOutpoint -- Got mismatched pubKeyCollateralAddress and vin\n");
nDos = 33; nDos = 33;
return false; return false;
@ -680,12 +695,12 @@ bool CMasternodeBroadcast::Sign(CKey& keyCollateralAddress)
pubKeyCollateralAddress.GetID().ToString() + pubKeyMasternode.GetID().ToString() + pubKeyCollateralAddress.GetID().ToString() + pubKeyMasternode.GetID().ToString() +
boost::lexical_cast<std::string>(nProtocolVersion); boost::lexical_cast<std::string>(nProtocolVersion);
if(!darkSendSigner.SignMessage(strMessage, vchSig, keyCollateralAddress)) { if(!CMessageSigner::SignMessage(strMessage, vchSig, keyCollateralAddress)) {
LogPrintf("CMasternodeBroadcast::Sign -- SignMessage() failed\n"); LogPrintf("CMasternodeBroadcast::Sign -- SignMessage() failed\n");
return false; return false;
} }
if(!darkSendSigner.VerifyMessage(pubKeyCollateralAddress, vchSig, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(pubKeyCollateralAddress, vchSig, strMessage, strError)) {
LogPrintf("CMasternodeBroadcast::Sign -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("CMasternodeBroadcast::Sign -- VerifyMessage() failed, error: %s\n", strError);
return false; return false;
} }
@ -705,7 +720,7 @@ bool CMasternodeBroadcast::CheckSignature(int& nDos)
LogPrint("masternode", "CMasternodeBroadcast::CheckSignature -- strMessage: %s pubKeyCollateralAddress address: %s sig: %s\n", strMessage, CBitcoinAddress(pubKeyCollateralAddress.GetID()).ToString(), EncodeBase64(&vchSig[0], vchSig.size())); LogPrint("masternode", "CMasternodeBroadcast::CheckSignature -- strMessage: %s pubKeyCollateralAddress address: %s sig: %s\n", strMessage, CBitcoinAddress(pubKeyCollateralAddress.GetID()).ToString(), EncodeBase64(&vchSig[0], vchSig.size()));
if(!darkSendSigner.VerifyMessage(pubKeyCollateralAddress, vchSig, strMessage, strError)){ if(!CMessageSigner::VerifyMessage(pubKeyCollateralAddress, vchSig, strMessage, strError)){
LogPrintf("CMasternodeBroadcast::CheckSignature -- Got bad Masternode announce signature, error: %s\n", strError); LogPrintf("CMasternodeBroadcast::CheckSignature -- Got bad Masternode announce signature, error: %s\n", strError);
nDos = 100; nDos = 100;
return false; return false;
@ -739,12 +754,12 @@ bool CMasternodePing::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode)
sigTime = GetAdjustedTime(); sigTime = GetAdjustedTime();
std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast<std::string>(sigTime); std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast<std::string>(sigTime);
if(!darkSendSigner.SignMessage(strMessage, vchSig, keyMasternode)) { if(!CMessageSigner::SignMessage(strMessage, vchSig, keyMasternode)) {
LogPrintf("CMasternodePing::Sign -- SignMessage() failed\n"); LogPrintf("CMasternodePing::Sign -- SignMessage() failed\n");
return false; return false;
} }
if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
LogPrintf("CMasternodePing::Sign -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("CMasternodePing::Sign -- VerifyMessage() failed, error: %s\n", strError);
return false; return false;
} }
@ -758,7 +773,7 @@ bool CMasternodePing::CheckSignature(CPubKey& pubKeyMasternode, int &nDos)
std::string strError = ""; std::string strError = "";
nDos = 0; nDos = 0;
if(!darkSendSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(pubKeyMasternode, vchSig, strMessage, strError)) {
LogPrintf("CMasternodePing::CheckSignature -- Got bad Masternode ping signature, masternode=%s, error: %s\n", vin.prevout.ToStringShort(), strError); LogPrintf("CMasternodePing::CheckSignature -- Got bad Masternode ping signature, masternode=%s, error: %s\n", vin.prevout.ToStringShort(), strError);
nDos = 33; nDos = 33;
return false; return false;

View File

@ -290,6 +290,9 @@ public:
return false; return false;
} }
/// Is the input associated with collateral public key? (and there is 1000 DASH - checking if valid masternode)
bool IsInputAssociatedWithPubkey();
bool IsValidNetAddr(); bool IsValidNetAddr();
static bool IsValidNetAddr(CService addrIn); static bool IsValidNetAddr(CService addrIn);

View File

@ -9,6 +9,7 @@
#include "masternode-payments.h" #include "masternode-payments.h"
#include "masternode-sync.h" #include "masternode-sync.h"
#include "masternodeman.h" #include "masternodeman.h"
#include "messagesigner.h"
#include "netfulfilledman.h" #include "netfulfilledman.h"
#include "util.h" #include "util.h"
@ -1134,14 +1135,14 @@ void CMasternodeMan::SendVerifyReply(CNode* pnode, CMasternodeVerification& mnv)
std::string strMessage = strprintf("%s%d%s", activeMasternode.service.ToString(false), mnv.nonce, blockHash.ToString()); std::string strMessage = strprintf("%s%d%s", activeMasternode.service.ToString(false), mnv.nonce, blockHash.ToString());
if(!darkSendSigner.SignMessage(strMessage, mnv.vchSig1, activeMasternode.keyMasternode)) { if(!CMessageSigner::SignMessage(strMessage, mnv.vchSig1, activeMasternode.keyMasternode)) {
LogPrintf("MasternodeMan::SendVerifyReply -- SignMessage() failed\n"); LogPrintf("MasternodeMan::SendVerifyReply -- SignMessage() failed\n");
return; return;
} }
std::string strError; std::string strError;
if(!darkSendSigner.VerifyMessage(activeMasternode.pubKeyMasternode, mnv.vchSig1, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(activeMasternode.pubKeyMasternode, mnv.vchSig1, strMessage, strError)) {
LogPrintf("MasternodeMan::SendVerifyReply -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("MasternodeMan::SendVerifyReply -- VerifyMessage() failed, error: %s\n", strError);
return; return;
} }
@ -1200,7 +1201,7 @@ void CMasternodeMan::ProcessVerifyReply(CNode* pnode, CMasternodeVerification& m
std::string strMessage1 = strprintf("%s%d%s", pnode->addr.ToString(false), mnv.nonce, blockHash.ToString()); std::string strMessage1 = strprintf("%s%d%s", pnode->addr.ToString(false), mnv.nonce, blockHash.ToString());
while(it != vMasternodes.end()) { while(it != vMasternodes.end()) {
if((CAddress)it->addr == pnode->addr) { if((CAddress)it->addr == pnode->addr) {
if(darkSendSigner.VerifyMessage(it->pubKeyMasternode, mnv.vchSig1, strMessage1, strError)) { if(CMessageSigner::VerifyMessage(it->pubKeyMasternode, mnv.vchSig1, strMessage1, strError)) {
// found it! // found it!
prealMasternode = &(*it); prealMasternode = &(*it);
if(!it->IsPoSeVerified()) { if(!it->IsPoSeVerified()) {
@ -1217,14 +1218,14 @@ void CMasternodeMan::ProcessVerifyReply(CNode* pnode, CMasternodeVerification& m
std::string strMessage2 = strprintf("%s%d%s%s%s", mnv.addr.ToString(false), mnv.nonce, blockHash.ToString(), std::string strMessage2 = strprintf("%s%d%s%s%s", mnv.addr.ToString(false), mnv.nonce, blockHash.ToString(),
mnv.vin1.prevout.ToStringShort(), mnv.vin2.prevout.ToStringShort()); mnv.vin1.prevout.ToStringShort(), mnv.vin2.prevout.ToStringShort());
// ... and sign it // ... and sign it
if(!darkSendSigner.SignMessage(strMessage2, mnv.vchSig2, activeMasternode.keyMasternode)) { if(!CMessageSigner::SignMessage(strMessage2, mnv.vchSig2, activeMasternode.keyMasternode)) {
LogPrintf("MasternodeMan::ProcessVerifyReply -- SignMessage() failed\n"); LogPrintf("MasternodeMan::ProcessVerifyReply -- SignMessage() failed\n");
return; return;
} }
std::string strError; std::string strError;
if(!darkSendSigner.VerifyMessage(activeMasternode.pubKeyMasternode, mnv.vchSig2, strMessage2, strError)) { if(!CMessageSigner::VerifyMessage(activeMasternode.pubKeyMasternode, mnv.vchSig2, strMessage2, strError)) {
LogPrintf("MasternodeMan::ProcessVerifyReply -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("MasternodeMan::ProcessVerifyReply -- VerifyMessage() failed, error: %s\n", strError);
return; return;
} }
@ -1330,12 +1331,12 @@ void CMasternodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerif
return; return;
} }
if(darkSendSigner.VerifyMessage(pmn1->pubKeyMasternode, mnv.vchSig1, strMessage1, strError)) { if(CMessageSigner::VerifyMessage(pmn1->pubKeyMasternode, mnv.vchSig1, strMessage1, strError)) {
LogPrintf("MasternodeMan::ProcessVerifyBroadcast -- VerifyMessage() for masternode1 failed, error: %s\n", strError); LogPrintf("MasternodeMan::ProcessVerifyBroadcast -- VerifyMessage() for masternode1 failed, error: %s\n", strError);
return; return;
} }
if(darkSendSigner.VerifyMessage(pmn2->pubKeyMasternode, mnv.vchSig2, strMessage2, strError)) { if(CMessageSigner::VerifyMessage(pmn2->pubKeyMasternode, mnv.vchSig2, strMessage2, strError)) {
LogPrintf("MasternodeMan::ProcessVerifyBroadcast -- VerifyMessage() for masternode2 failed, error: %s\n", strError); LogPrintf("MasternodeMan::ProcessVerifyBroadcast -- VerifyMessage() for masternode2 failed, error: %s\n", strError);
return; return;
} }

63
src/messagesigner.cpp Normal file
View File

@ -0,0 +1,63 @@
// Copyright (c) 2014-2017 The Dash Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "base58.h"
#include "hash.h"
#include "main.h" // For strMessageMagic
#include "messagesigner.h"
#include "tinyformat.h"
#include "utilstrencodings.h"
bool CMessageSigner::GetKeysFromSecret(const std::string strSecret, CKey& keyRet, CPubKey& pubkeyRet)
{
CBitcoinSecret vchSecret;
if(!vchSecret.SetString(strSecret)) return false;
keyRet = vchSecret.GetKey();
pubkeyRet = keyRet.GetPubKey();
return true;
}
bool CMessageSigner::SignMessage(const std::string strMessage, std::vector<unsigned char>& vchSigRet, const CKey key)
{
CHashWriter ss(SER_GETHASH, 0);
ss << strMessageMagic;
ss << strMessage;
return CHashSigner::SignHash(ss.GetHash(), key, vchSigRet);
}
bool CMessageSigner::VerifyMessage(const CPubKey pubkey, const std::vector<unsigned char>& vchSig, const std::string strMessage, std::string& strErrorRet)
{
CHashWriter ss(SER_GETHASH, 0);
ss << strMessageMagic;
ss << strMessage;
return CHashSigner::VerifyHash(ss.GetHash(), pubkey, vchSig, strErrorRet);
}
bool CHashSigner::SignHash(const uint256& hash, const CKey key, std::vector<unsigned char>& vchSigRet)
{
return key.SignCompact(hash, vchSigRet);
}
bool CHashSigner::VerifyHash(const uint256& hash, const CPubKey pubkey, const std::vector<unsigned char>& vchSig, std::string& strErrorRet)
{
CPubKey pubkeyFromSig;
if(!pubkeyFromSig.RecoverCompact(hash, vchSig)) {
strErrorRet = "Error recovering public key.";
return false;
}
if(pubkeyFromSig.GetID() != pubkey.GetID()) {
strErrorRet = strprintf("Keys don't match: pubkey=%s, pubkeyFromSig=%s, hash=%s, vchSig=%s",
pubkey.GetID().ToString(), pubkeyFromSig.GetID().ToString(), hash.ToString(),
EncodeBase64(&vchSig[0], vchSig.size()));
return false;
}
return true;
}

34
src/messagesigner.h Normal file
View File

@ -0,0 +1,34 @@
// Copyright (c) 2014-2017 The Dash Core developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef MESSAGESIGNER_H
#define MESSAGESIGNER_H
#include "key.h"
/** Helper class for signing messages and checking their signatures
*/
class CMessageSigner
{
public:
/// Set the private/public key values, returns true if successful
static bool GetKeysFromSecret(const std::string strSecret, CKey& keyRet, CPubKey& pubkeyRet);
/// Sign the message, returns true if successful
static bool SignMessage(const std::string strMessage, std::vector<unsigned char>& vchSigRet, const CKey key);
/// Verify the message signature, returns true if succcessful
static bool VerifyMessage(const CPubKey pubkey, const std::vector<unsigned char>& vchSig, const std::string strMessage, std::string& strErrorRet);
};
/** Helper class for signing hashes and checking their signatures
*/
class CHashSigner
{
public:
/// Sign the hash, returns true if successful
static bool SignHash(const uint256& hash, const CKey key, std::vector<unsigned char>& vchSigRet);
/// Verify the hash signature, returns true if succcessful
static bool VerifyHash(const uint256& hash, const CPubKey pubkey, const std::vector<unsigned char>& vchSig, std::string& strErrorRet);
};
#endif

View File

@ -5,7 +5,6 @@
//#define ENABLE_DASH_DEBUG //#define ENABLE_DASH_DEBUG
#include "activemasternode.h" #include "activemasternode.h"
#include "darksend.h"
#include "governance.h" #include "governance.h"
#include "governance-vote.h" #include "governance-vote.h"
#include "governance-classes.h" #include "governance-classes.h"
@ -15,6 +14,7 @@
#include "masternode-sync.h" #include "masternode-sync.h"
#include "masternodeconfig.h" #include "masternodeconfig.h"
#include "masternodeman.h" #include "masternodeman.h"
#include "messagesigner.h"
#include "rpcserver.h" #include "rpcserver.h"
#include "util.h" #include "util.h"
#include "utilmoneystr.h" #include "utilmoneystr.h"
@ -350,7 +350,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
UniValue statusObj(UniValue::VOBJ); UniValue statusObj(UniValue::VOBJ);
if(!darkSendSigner.GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)){ if(!CMessageSigner::GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)){
nFailed++; nFailed++;
statusObj.push_back(Pair("result", "failed")); statusObj.push_back(Pair("result", "failed"));
statusObj.push_back(Pair("errorMessage", "Masternode signing error, could not set key correctly")); statusObj.push_back(Pair("errorMessage", "Masternode signing error, could not set key correctly"));
@ -469,7 +469,7 @@ UniValue gobject(const UniValue& params, bool fHelp)
UniValue statusObj(UniValue::VOBJ); UniValue statusObj(UniValue::VOBJ);
if(!darkSendSigner.GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)) { if(!CMessageSigner::GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)) {
nFailed++; nFailed++;
statusObj.push_back(Pair("result", "failed")); statusObj.push_back(Pair("result", "failed"));
statusObj.push_back(Pair("errorMessage", strprintf("Invalid masternode key %s.", mne.getPrivKey()))); statusObj.push_back(Pair("errorMessage", strprintf("Invalid masternode key %s.", mne.getPrivKey())));

View File

@ -2,8 +2,9 @@
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "darksend.h" #include "chainparams.h"
#include "main.h" #include "main.h"
#include "messagesigner.h"
#include "spork.h" #include "spork.h"
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
@ -223,17 +224,17 @@ bool CSporkMessage::Sign(std::string strSignKey)
std::string strError = ""; std::string strError = "";
std::string strMessage = boost::lexical_cast<std::string>(nSporkID) + boost::lexical_cast<std::string>(nValue) + boost::lexical_cast<std::string>(nTimeSigned); std::string strMessage = boost::lexical_cast<std::string>(nSporkID) + boost::lexical_cast<std::string>(nValue) + boost::lexical_cast<std::string>(nTimeSigned);
if(!darkSendSigner.GetKeysFromSecret(strSignKey, key, pubkey)) { if(!CMessageSigner::GetKeysFromSecret(strSignKey, key, pubkey)) {
LogPrintf("CSporkMessage::Sign -- GetKeysFromSecret() failed, invalid spork key %s\n", strSignKey); LogPrintf("CSporkMessage::Sign -- GetKeysFromSecret() failed, invalid spork key %s\n", strSignKey);
return false; return false;
} }
if(!darkSendSigner.SignMessage(strMessage, vchSig, key)) { if(!CMessageSigner::SignMessage(strMessage, vchSig, key)) {
LogPrintf("CSporkMessage::Sign -- SignMessage() failed\n"); LogPrintf("CSporkMessage::Sign -- SignMessage() failed\n");
return false; return false;
} }
if(!darkSendSigner.VerifyMessage(pubkey, vchSig, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(pubkey, vchSig, strMessage, strError)) {
LogPrintf("CSporkMessage::Sign -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("CSporkMessage::Sign -- VerifyMessage() failed, error: %s\n", strError);
return false; return false;
} }
@ -248,7 +249,7 @@ bool CSporkMessage::CheckSignature()
std::string strMessage = boost::lexical_cast<std::string>(nSporkID) + boost::lexical_cast<std::string>(nValue) + boost::lexical_cast<std::string>(nTimeSigned); std::string strMessage = boost::lexical_cast<std::string>(nSporkID) + boost::lexical_cast<std::string>(nValue) + boost::lexical_cast<std::string>(nTimeSigned);
CPubKey pubkey(ParseHex(Params().SporkPubKey())); CPubKey pubkey(ParseHex(Params().SporkPubKey()));
if(!darkSendSigner.VerifyMessage(pubkey, vchSig, strMessage, strError)) { if(!CMessageSigner::VerifyMessage(pubkey, vchSig, strMessage, strError)) {
LogPrintf("CSporkMessage::CheckSignature -- VerifyMessage() failed, error: %s\n", strError); LogPrintf("CSporkMessage::CheckSignature -- VerifyMessage() failed, error: %s\n", strError);
return false; return false;
} }