From 98990b683a2bd2756c8880a24eac1ffc8dc9046c Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 12 Apr 2017 10:04:06 +0300 Subject: [PATCH] Refactor: CDarkSendSigner (#1410) * Refactor: CDarkSendSigner -> CMessageSigner + CMasternodeBroadcast::IsVinAssociatedWithPubkey * move IsVinAssociatedWithPubkey to CMasternode * static IsVinAssociatedWithPubkey -> no params IsInputAssociatedWithPubkey --- src/Makefile.am | 2 ++ src/darksend-relay.cpp | 12 +++---- src/darksend.cpp | 68 +++---------------------------------- src/darksend.h | 18 ---------- src/governance-object.cpp | 8 ++--- src/governance-vote.cpp | 8 ++--- src/governance.cpp | 2 +- src/init.cpp | 3 +- src/instantx.cpp | 8 ++--- src/masternode-payments.cpp | 8 ++--- src/masternode.cpp | 37 ++++++++++++++------ src/masternode.h | 3 ++ src/masternodeman.cpp | 15 ++++---- src/messagesigner.cpp | 63 ++++++++++++++++++++++++++++++++++ src/messagesigner.h | 34 +++++++++++++++++++ src/rpcgovernance.cpp | 6 ++-- src/spork.cpp | 11 +++--- 17 files changed, 175 insertions(+), 131 deletions(-) create mode 100644 src/messagesigner.cpp create mode 100644 src/messagesigner.h diff --git a/src/Makefile.am b/src/Makefile.am index 07e18957f..e11c4c096 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -124,6 +124,7 @@ BITCOIN_CORE_H = \ masternodeconfig.h \ memusage.h \ merkleblock.h \ + messagesigner.h \ miner.h \ net.h \ netbase.h \ @@ -211,6 +212,7 @@ libbitcoin_server_a_SOURCES = \ governance-votedb.cpp \ main.cpp \ merkleblock.cpp \ + messagesigner.cpp \ miner.cpp \ net.cpp \ netfulfilledman.cpp \ diff --git a/src/darksend-relay.cpp b/src/darksend-relay.cpp index 66535cda3..3847ca743 100644 --- a/src/darksend-relay.cpp +++ b/src/darksend-relay.cpp @@ -1,6 +1,6 @@ #include "darksend.h" #include "darksend-relay.h" - +#include "messagesigner.h" CDarkSendRelay::CDarkSendRelay() { @@ -42,17 +42,17 @@ bool CDarkSendRelay::Sign(std::string strSharedKey) CKey key2; 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); return false; } - if(!darkSendSigner.SignMessage(strMessage, vchSig2, key2)) { + if(!CMessageSigner::SignMessage(strMessage, vchSig2, key2)) { LogPrintf("CDarkSendRelay::Sign -- SignMessage() failed\n"); 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); return false; } @@ -68,12 +68,12 @@ bool CDarkSendRelay::VerifyMessage(std::string strSharedKey) CKey key2; 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); 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); return false; } diff --git a/src/darksend.cpp b/src/darksend.cpp index 9c76df5da..2fd5b86bd 100644 --- a/src/darksend.cpp +++ b/src/darksend.cpp @@ -12,6 +12,7 @@ #include "masternode-payments.h" #include "masternode-sync.h" #include "masternodeman.h" +#include "messagesigner.h" #include "script/sign.h" #include "txmempool.h" #include "util.h" @@ -26,7 +27,6 @@ bool fEnablePrivateSend = false; bool fPrivateSendMultiSession = DEFAULT_PRIVATESEND_MULTISESSION; CDarksendPool darkSendPool; -CDarkSendSigner darkSendSigner; std::map mapDarksendBroadcastTxes; std::vector 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& 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& 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) { BOOST_FOREACH(CTxDSIn& txdsin, vecTxDSIn) { @@ -2339,7 +2281,7 @@ bool CDarksendQueue::Sign() std::string strMessage = vin.ToString() + boost::lexical_cast(nDenom) + boost::lexical_cast(nTime) + boost::lexical_cast(fReady); - if(!darkSendSigner.SignMessage(strMessage, vchSig, activeMasternode.keyMasternode)) { + if(!CMessageSigner::SignMessage(strMessage, vchSig, activeMasternode.keyMasternode)) { LogPrintf("CDarksendQueue::Sign -- SignMessage() failed, %s\n", ToString()); return false; } @@ -2352,7 +2294,7 @@ bool CDarksendQueue::CheckSignature(const CPubKey& pubKeyMasternode) std::string strMessage = vin.ToString() + boost::lexical_cast(nDenom) + boost::lexical_cast(nTime) + boost::lexical_cast(fReady); 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); return false; } @@ -2377,7 +2319,7 @@ bool CDarksendBroadcastTx::Sign() std::string strMessage = tx.GetHash().ToString() + boost::lexical_cast(sigTime); - if(!darkSendSigner.SignMessage(strMessage, vchSig, activeMasternode.keyMasternode)) { + if(!CMessageSigner::SignMessage(strMessage, vchSig, activeMasternode.keyMasternode)) { LogPrintf("CDarksendBroadcastTx::Sign -- SignMessage() failed\n"); return false; } @@ -2390,7 +2332,7 @@ bool CDarksendBroadcastTx::CheckSignature(const CPubKey& pubKeyMasternode) std::string strMessage = tx.GetHash().ToString() + boost::lexical_cast(sigTime); 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); return false; } diff --git a/src/darksend.h b/src/darksend.h index 8444a760c..04e7cbdb4 100644 --- a/src/darksend.h +++ b/src/darksend.h @@ -9,7 +9,6 @@ #include "wallet/wallet.h" class CDarksendPool; -class CDarkSendSigner; class CDarksendBroadcastTx; // timeouts @@ -44,8 +43,6 @@ extern bool fPrivateSendMultiSession; // The main object for accessing mixing extern CDarksendPool darkSendPool; -// A helper object for signing messages from Masternodes -extern CDarkSendSigner darkSendSigner; extern std::map mapDarksendBroadcastTxes; extern std::vector vecPrivateSendDenominations; @@ -234,21 +231,6 @@ public: 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& vchSigRet, CKey key); - /// Verify the message, returns true if succcessful - bool VerifyMessage(CPubKey pubkey, const std::vector& vchSig, std::string strMessage, std::string& strErrorRet); -}; - /** Used to keep track of current status of mixing pool */ class CDarksendPool diff --git a/src/governance-object.cpp b/src/governance-object.cpp index 1b9c63160..62b90a9f3 100644 --- a/src/governance-object.cpp +++ b/src/governance-object.cpp @@ -3,12 +3,12 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "core_io.h" -#include "darksend.h" #include "governance.h" #include "governance-classes.h" #include "governance-object.h" #include "governance-vote.h" #include "masternodeman.h" +#include "messagesigner.h" #include "util.h" #include @@ -260,12 +260,12 @@ bool CGovernanceObject::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode) LOCK(cs); - if(!darkSendSigner.SignMessage(strMessage, vchSig, keyMasternode)) { + if(!CMessageSigner::SignMessage(strMessage, vchSig, keyMasternode)) { LogPrintf("CGovernanceObject::Sign -- SignMessage() failed\n"); 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); return false; } @@ -284,7 +284,7 @@ bool CGovernanceObject::CheckSignature(CPubKey& pubKeyMasternode) std::string strMessage = GetSignatureMessage(); 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); return false; } diff --git a/src/governance-vote.cpp b/src/governance-vote.cpp index 7bacedc69..d6fab26cb 100644 --- a/src/governance-vote.cpp +++ b/src/governance-vote.cpp @@ -2,9 +2,9 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "darksend.h" #include "governance-vote.h" #include "masternodeman.h" +#include "messagesigner.h" #include "util.h" #include @@ -239,12 +239,12 @@ bool CGovernanceVote::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode) std::string strMessage = vinMasternode.prevout.ToStringShort() + "|" + nParentHash.ToString() + "|" + boost::lexical_cast(nVoteSignal) + "|" + boost::lexical_cast(nVoteOutcome) + "|" + boost::lexical_cast(nTime); - if(!darkSendSigner.SignMessage(strMessage, vchSig, keyMasternode)) { + if(!CMessageSigner::SignMessage(strMessage, vchSig, keyMasternode)) { LogPrintf("CGovernanceVote::Sign -- SignMessage() failed\n"); 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); return false; } @@ -285,7 +285,7 @@ bool CGovernanceVote::IsValid(bool fSignatureCheck) const std::string strMessage = vinMasternode.prevout.ToStringShort() + "|" + nParentHash.ToString() + "|" + boost::lexical_cast(nVoteSignal) + "|" + boost::lexical_cast(nVoteOutcome) + "|" + boost::lexical_cast(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); return false; } diff --git a/src/governance.cpp b/src/governance.cpp index ace46ef17..5c640518a 100644 --- a/src/governance.cpp +++ b/src/governance.cpp @@ -2,7 +2,6 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "darksend.h" #include "governance.h" #include "governance-object.h" #include "governance-vote.h" @@ -11,6 +10,7 @@ #include "masternode.h" #include "masternode-sync.h" #include "masternodeman.h" +#include "messagesigner.h" #include "netfulfilledman.h" #include "util.h" diff --git a/src/init.cpp b/src/init.cpp index bbc917603..c847ddca7 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -56,6 +56,7 @@ #include "masternode-sync.h" #include "masternodeman.h" #include "masternodeconfig.h" +#include "messagesigner.h" #include "netfulfilledman.h" #include "spork.h" @@ -1807,7 +1808,7 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) std::string strMasterNodePrivKey = GetArg("-masternodeprivkey", ""); 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.")); LogPrintf(" pubKeyMasternode: %s\n", CBitcoinAddress(activeMasternode.pubKeyMasternode.GetID()).ToString()); diff --git a/src/instantx.cpp b/src/instantx.cpp index 94799ff31..7c4694de7 100644 --- a/src/instantx.cpp +++ b/src/instantx.cpp @@ -3,12 +3,12 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "activemasternode.h" -#include "darksend.h" #include "instantx.h" #include "key.h" #include "main.h" #include "masternode-sync.h" #include "masternodeman.h" +#include "messagesigner.h" #include "net.h" #include "protocol.h" #include "spork.h" @@ -1031,7 +1031,7 @@ bool CTxLockVote::CheckSignature() const 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); return false; } @@ -1044,12 +1044,12 @@ bool CTxLockVote::Sign() std::string strError; 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"); 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); return false; } diff --git a/src/masternode-payments.cpp b/src/masternode-payments.cpp index 6b6c1b6a3..743c7c397 100644 --- a/src/masternode-payments.cpp +++ b/src/masternode-payments.cpp @@ -3,11 +3,11 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "activemasternode.h" -#include "darksend.h" #include "governance-classes.h" #include "masternode-payments.h" #include "masternode-sync.h" #include "masternodeman.h" +#include "messagesigner.h" #include "netfulfilledman.h" #include "spork.h" #include "util.h" @@ -421,12 +421,12 @@ bool CMasternodePaymentVote::Sign() boost::lexical_cast(nBlockHeight) + ScriptToAsmStr(payee); - if(!darkSendSigner.SignMessage(strMessage, vchSig, activeMasternode.keyMasternode)) { + if(!CMessageSigner::SignMessage(strMessage, vchSig, activeMasternode.keyMasternode)) { LogPrintf("CMasternodePaymentVote::Sign -- SignMessage() failed\n"); 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); return false; } @@ -793,7 +793,7 @@ bool CMasternodePaymentVote::CheckSignature(const CPubKey& pubKeyMasternode, int ScriptToAsmStr(payee); 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. // 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. diff --git a/src/masternode.cpp b/src/masternode.cpp index 365e603d3..c2a9ef661 100644 --- a/src/masternode.cpp +++ b/src/masternode.cpp @@ -4,13 +4,13 @@ #include "activemasternode.h" #include "consensus/validation.h" -#include "darksend.h" #include "init.h" #include "governance.h" #include "masternode.h" #include "masternode-payments.h" #include "masternode-sync.h" #include "masternodeman.h" +#include "messagesigner.h" #include "util.h" #include @@ -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() { return IsValidNetAddr(addr); @@ -415,7 +430,7 @@ bool CMasternodeBroadcast::Create(std::string strService, std::string strKeyMast return false; } - if(!darkSendSigner.GetKeysFromSecret(strKeyMasternode, keyMasternodeNew, pubKeyMasternodeNew)) { + if(!CMessageSigner::GetKeysFromSecret(strKeyMasternode, keyMasternodeNew, pubKeyMasternodeNew)) { strErrorRet = strprintf("Invalid masternode key %s", strKeyMasternode); LogPrintf("CMasternodeBroadcast::Create -- %s\n", strErrorRet); return false; @@ -639,9 +654,9 @@ bool CMasternodeBroadcast::CheckOutpoint(int& nDos) LogPrint("masternode", "CMasternodeBroadcast::CheckOutpoint -- Masternode UTXO verified\n"); - // make sure the vout that was signed is related to the transaction that spawned the Masternode - // - this is expensive, so it's only done once per Masternode - if(!darkSendSigner.IsVinAssociatedWithPubkey(vin, pubKeyCollateralAddress)) { + // make sure the input that was signed in masternode broadcast message is related to the transaction + // that spawned the Masternode - this is expensive, so it's only done once per Masternode + if(!IsInputAssociatedWithPubkey()) { LogPrintf("CMasternodeMan::CheckOutpoint -- Got mismatched pubKeyCollateralAddress and vin\n"); nDos = 33; return false; @@ -680,12 +695,12 @@ bool CMasternodeBroadcast::Sign(CKey& keyCollateralAddress) pubKeyCollateralAddress.GetID().ToString() + pubKeyMasternode.GetID().ToString() + boost::lexical_cast(nProtocolVersion); - if(!darkSendSigner.SignMessage(strMessage, vchSig, keyCollateralAddress)) { + if(!CMessageSigner::SignMessage(strMessage, vchSig, keyCollateralAddress)) { LogPrintf("CMasternodeBroadcast::Sign -- SignMessage() failed\n"); 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); 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())); - 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); nDos = 100; return false; @@ -739,12 +754,12 @@ bool CMasternodePing::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode) sigTime = GetAdjustedTime(); std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast(sigTime); - if(!darkSendSigner.SignMessage(strMessage, vchSig, keyMasternode)) { + if(!CMessageSigner::SignMessage(strMessage, vchSig, keyMasternode)) { LogPrintf("CMasternodePing::Sign -- SignMessage() failed\n"); 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); return false; } @@ -758,7 +773,7 @@ bool CMasternodePing::CheckSignature(CPubKey& pubKeyMasternode, int &nDos) std::string strError = ""; 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); nDos = 33; return false; diff --git a/src/masternode.h b/src/masternode.h index 92edc9fcf..bd7cbde6f 100644 --- a/src/masternode.h +++ b/src/masternode.h @@ -290,6 +290,9 @@ public: return false; } + /// Is the input associated with collateral public key? (and there is 1000 DASH - checking if valid masternode) + bool IsInputAssociatedWithPubkey(); + bool IsValidNetAddr(); static bool IsValidNetAddr(CService addrIn); diff --git a/src/masternodeman.cpp b/src/masternodeman.cpp index a67b06965..3da3ddb68 100644 --- a/src/masternodeman.cpp +++ b/src/masternodeman.cpp @@ -9,6 +9,7 @@ #include "masternode-payments.h" #include "masternode-sync.h" #include "masternodeman.h" +#include "messagesigner.h" #include "netfulfilledman.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()); - if(!darkSendSigner.SignMessage(strMessage, mnv.vchSig1, activeMasternode.keyMasternode)) { + if(!CMessageSigner::SignMessage(strMessage, mnv.vchSig1, activeMasternode.keyMasternode)) { LogPrintf("MasternodeMan::SendVerifyReply -- SignMessage() failed\n"); return; } 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); 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()); while(it != vMasternodes.end()) { 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! prealMasternode = &(*it); 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(), mnv.vin1.prevout.ToStringShort(), mnv.vin2.prevout.ToStringShort()); // ... 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"); return; } 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); return; } @@ -1330,12 +1331,12 @@ void CMasternodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerif 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); 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); return; } diff --git a/src/messagesigner.cpp b/src/messagesigner.cpp new file mode 100644 index 000000000..bb390e91f --- /dev/null +++ b/src/messagesigner.cpp @@ -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& 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& 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& vchSigRet) +{ + return key.SignCompact(hash, vchSigRet); +} + +bool CHashSigner::VerifyHash(const uint256& hash, const CPubKey pubkey, const std::vector& 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; +} diff --git a/src/messagesigner.h b/src/messagesigner.h new file mode 100644 index 000000000..e445e5a7e --- /dev/null +++ b/src/messagesigner.h @@ -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& vchSigRet, const CKey key); + /// Verify the message signature, returns true if succcessful + static bool VerifyMessage(const CPubKey pubkey, const std::vector& 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& vchSigRet); + /// Verify the hash signature, returns true if succcessful + static bool VerifyHash(const uint256& hash, const CPubKey pubkey, const std::vector& vchSig, std::string& strErrorRet); +}; + +#endif diff --git a/src/rpcgovernance.cpp b/src/rpcgovernance.cpp index a5ebda63c..77ccedea0 100644 --- a/src/rpcgovernance.cpp +++ b/src/rpcgovernance.cpp @@ -5,7 +5,6 @@ //#define ENABLE_DASH_DEBUG #include "activemasternode.h" -#include "darksend.h" #include "governance.h" #include "governance-vote.h" #include "governance-classes.h" @@ -15,6 +14,7 @@ #include "masternode-sync.h" #include "masternodeconfig.h" #include "masternodeman.h" +#include "messagesigner.h" #include "rpcserver.h" #include "util.h" #include "utilmoneystr.h" @@ -350,7 +350,7 @@ UniValue gobject(const UniValue& params, bool fHelp) UniValue statusObj(UniValue::VOBJ); - if(!darkSendSigner.GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)){ + if(!CMessageSigner::GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)){ nFailed++; statusObj.push_back(Pair("result", "failed")); 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); - if(!darkSendSigner.GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)) { + if(!CMessageSigner::GetKeysFromSecret(mne.getPrivKey(), keyMasternode, pubKeyMasternode)) { nFailed++; statusObj.push_back(Pair("result", "failed")); statusObj.push_back(Pair("errorMessage", strprintf("Invalid masternode key %s.", mne.getPrivKey()))); diff --git a/src/spork.cpp b/src/spork.cpp index b16152702..ec90a167e 100644 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -2,8 +2,9 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "darksend.h" +#include "chainparams.h" #include "main.h" +#include "messagesigner.h" #include "spork.h" #include @@ -223,17 +224,17 @@ bool CSporkMessage::Sign(std::string strSignKey) std::string strError = ""; std::string strMessage = boost::lexical_cast(nSporkID) + boost::lexical_cast(nValue) + boost::lexical_cast(nTimeSigned); - if(!darkSendSigner.GetKeysFromSecret(strSignKey, key, pubkey)) { + if(!CMessageSigner::GetKeysFromSecret(strSignKey, key, pubkey)) { LogPrintf("CSporkMessage::Sign -- GetKeysFromSecret() failed, invalid spork key %s\n", strSignKey); return false; } - if(!darkSendSigner.SignMessage(strMessage, vchSig, key)) { + if(!CMessageSigner::SignMessage(strMessage, vchSig, key)) { LogPrintf("CSporkMessage::Sign -- SignMessage() failed\n"); 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); return false; } @@ -248,7 +249,7 @@ bool CSporkMessage::CheckSignature() std::string strMessage = boost::lexical_cast(nSporkID) + boost::lexical_cast(nValue) + boost::lexical_cast(nTimeSigned); 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); return false; }