From: 0xDEADFACE Date: Sat, 13 Feb 2016 22:52:49 +0000 (+0300) Subject: Merge pull request #273 from svost/includes X-Git-Tag: nvc-v0.5.6~81^2~1 X-Git-Url: https://git.novaco.in/?p=novacoin.git;a=commitdiff_plain;h=39d23056c0cf13b3e59648c159f2d4aff190992b;hp=6db849791e675fa14d1222f86011ec6c08c84183 Merge pull request #273 from svost/includes Reorganize includes a bit. --- diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 719aef0..92042d0 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -319,6 +319,7 @@ static const CRPCCommand vRPCCommands[] = { "newmalleablekey", &newmalleablekey, false, false}, { "adjustmalleablekey", &adjustmalleablekey, false, false}, { "adjustmalleablepubkey", &adjustmalleablepubkey, false, false}, + { "listmalleablepubkeys", &listmalleablepubkeys, false, false}, { "sendalert", &sendalert, false, false}, }; diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 3b0e199..226007b 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -209,6 +209,7 @@ extern json_spirit::Value mergecoins(const json_spirit::Array& params, bool fHel extern json_spirit::Value newmalleablekey(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value adjustmalleablekey(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value adjustmalleablepubkey(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value listmalleablepubkeys(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp); diff --git a/src/key.cpp b/src/key.cpp index 39a7ebb..fe8573e 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -589,6 +589,12 @@ bool CPoint::setBytes(const std::vector &vchBytes) return true; } +// Initialize from octets stream +bool CPoint::setPubKey(const CPubKey &vchPubKey) +{ + return setBytes(vchPubKey.Raw()); +} + // Serialize to octets stream bool CPoint::getBytes(std::vector &vchBytes) { @@ -663,7 +669,7 @@ void CMalleablePubKey::GetVariant(CPubKey &R, CPubKey &vchPubKeyVariant) EC_KEY_free(eckey); CPoint point; - if (!point.setBytes(pubKeyL.Raw())) { + if (!point.setPubKey(pubKeyL)) { throw key_error("CMalleablePubKey::GetVariant() : Unable to decode L value"); } @@ -680,7 +686,7 @@ void CMalleablePubKey::GetVariant(CPubKey &R, CPubKey &vchPubKeyVariant) bnHash.setuint160(Hash160(vchLr)); CPoint pointH; - pointH.setBytes(pubKeyH.Raw()); + pointH.setPubKey(pubKeyH); CPoint P; // Calculate P = Hash(L*r)*G + H @@ -696,7 +702,7 @@ void CMalleablePubKey::GetVariant(CPubKey &R, CPubKey &vchPubKeyVariant) vchPubKeyVariant = CPubKey(vchResult); } -std::string CMalleablePubKey::ToString() +std::string CMalleablePubKey::ToString() const { CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION); ssKey << *this; @@ -786,7 +792,7 @@ bool CMalleableKey::SetSecrets(const CSecret &pvchSecretL, const CSecret &pvchSe Reset(); CKey L, H; - if (!L.SetSecret(pvchSecretL, true) || !H.SetSecret(pvchSecretH, true)) + if (pvchSecretL.size() != 32 || !pvchSecretH.size() != 32 || !L.SetSecret(pvchSecretL, true) || !H.SetSecret(pvchSecretH, true)) { nVersion = 0; return false; @@ -818,7 +824,7 @@ CMalleablePubKey CMalleableKey::GetMalleablePubKey() const } // Check ownership -bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) +bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const { if (IsNull()) { throw key_error("CMalleableKey::CheckKeyVariant() : Attempting to run on NULL key object."); @@ -833,7 +839,7 @@ bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVa } CPoint point_R; - if (!point_R.setBytes(R.Raw())) { + if (!point_R.setPubKey(R)) { throw key_error("CMalleableKey::CheckKeyVariant() : Unable to decode R value"); } @@ -842,12 +848,12 @@ bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVa std::vector vchPubKeyH = H.GetPubKey().Raw(); CPoint point_H; - if (!point_H.setBytes(vchPubKeyH)) { + if (!point_H.setPubKey(vchPubKeyH)) { throw key_error("CMalleableKey::CheckKeyVariant() : Unable to decode H value"); } CPoint point_P; - if (!point_P.setBytes(vchPubKeyVariant.Raw())) { + if (!point_P.setPubKey(vchPubKeyVariant)) { throw key_error("CMalleableKey::CheckKeyVariant() : Unable to decode P value"); } @@ -888,7 +894,7 @@ bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVa } // Check ownership and restore private key -bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant, CKey &privKeyVariant) +bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant, CKey &privKeyVariant) const { if (IsNull()) { throw key_error("CMalleableKey::CheckKeyVariant() : Attempting to run on NULL key object."); @@ -903,7 +909,7 @@ bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVa } CPoint point_R; - if (!point_R.setBytes(R.Raw())) { + if (!point_R.setPubKey(R)) { throw key_error("CMalleableKey::CheckKeyVariant() : Unable to decode R value"); } @@ -912,12 +918,12 @@ bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVa std::vector vchPubKeyH = H.GetPubKey().Raw(); CPoint point_H; - if (!point_H.setBytes(vchPubKeyH)) { + if (!point_H.setPubKey(vchPubKeyH)) { throw key_error("CMalleableKey::CheckKeyVariant() : Unable to decode H value"); } CPoint point_P; - if (!point_P.setBytes(vchPubKeyVariant.Raw())) { + if (!point_P.setPubKey(vchPubKeyVariant)) { throw key_error("CMalleableKey::CheckKeyVariant() : Unable to decode P value"); } @@ -967,7 +973,7 @@ bool CMalleableKey::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVa return true; } -std::string CMalleableKey::ToString() +std::string CMalleableKey::ToString() const { CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION); ssKey << *this; @@ -993,28 +999,43 @@ bool CMalleableKey::SetString(const std::string& strMutableKey) CMalleableKeyView::CMalleableKeyView(const CMalleableKey &b) { - assert(b.nVersion == CURRENT_VERSION); + if (b.vchSecretL.size() != 32) + throw key_error("CMalleableKeyView::CMalleableKeyView() : L size must be 32 bytes"); + + if (b.vchSecretH.size() != 32) + throw key_error("CMalleableKeyView::CMalleableKeyView() : L size must be 32 bytes"); + vchSecretL = b.vchSecretL; CKey H; H.SetSecret(b.vchSecretH, true); + vchPubKeyH = H.GetPubKey().Raw(); + nVersion = b.nVersion; +} + +CMalleableKeyView::CMalleableKeyView(const CMalleableKeyView &b) +{ + vchSecretL = b.vchSecretL; + vchPubKeyH = b.vchPubKeyH; + nVersion = CURRENT_VERSION; } CMalleableKeyView::CMalleableKeyView(const CSecret &L, const CPubKey &pvchPubKeyH) { vchSecretL = L; vchPubKeyH = pvchPubKeyH.Raw(); + nVersion = CURRENT_VERSION; } CMalleableKeyView& CMalleableKeyView::operator=(const CMalleableKey &b) { - assert(b.nVersion == CURRENT_VERSION); vchSecretL = b.vchSecretL; CKey H; H.SetSecret(b.vchSecretH, true); vchPubKeyH = H.GetPubKey().Raw(); + nVersion = b.nVersion; return (*this); } @@ -1031,7 +1052,7 @@ CMalleablePubKey CMalleableKeyView::GetMalleablePubKey() const } // Check ownership -bool CMalleableKeyView::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) +bool CMalleableKeyView::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const { if (!R.IsValid()) { throw key_error("CMalleableKeyView::CheckKeyVariant() : R is invalid"); @@ -1042,17 +1063,17 @@ bool CMalleableKeyView::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubK } CPoint point_R; - if (!point_R.setBytes(R.Raw())) { + if (!point_R.setPubKey(R)) { throw key_error("CMalleableKeyView::CheckKeyVariant() : Unable to decode R value"); } CPoint point_H; - if (!point_H.setBytes(vchPubKeyH)) { + if (!point_H.setPubKey(vchPubKeyH)) { throw key_error("CMalleableKeyView::CheckKeyVariant() : Unable to decode H value"); } CPoint point_P; - if (!point_P.setBytes(vchPubKeyVariant.Raw())) { + if (!point_P.setPubKey(vchPubKeyVariant)) { throw key_error("CMalleableKeyView::CheckKeyVariant() : Unable to decode P value"); } @@ -1092,6 +1113,33 @@ bool CMalleableKeyView::CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubK return true; } +std::string CMalleableKeyView::ToString() const +{ + CDataStream ssKey(SER_NETWORK, PROTOCOL_VERSION); + ssKey << *this; + std::vector vch(ssKey.begin(), ssKey.end()); + + return EncodeBase58Check(vch); +} + +bool CMalleableKeyView::SetString(const std::string& strMutableKey) +{ + std::vector vchTemp; + if (!DecodeBase58Check(strMutableKey, vchTemp)) { + throw key_error("CMalleableKeyView::SetString() : Provided key data seems corrupted."); + } + + CDataStream ssKey(vchTemp, SER_NETWORK, PROTOCOL_VERSION); + ssKey >> *this; + + return IsNull(); +} + +bool CMalleableKeyView::IsNull() const +{ + return nVersion != CURRENT_VERSION; +} + //// Asymmetric encryption void CPubKey::EncryptData(const std::vector& data, std::vector& encrypted) diff --git a/src/key.h b/src/key.h index f8404db..a829834 100644 --- a/src/key.h +++ b/src/key.h @@ -191,6 +191,9 @@ public: // Initialize from octets stream bool setBytes(const std::vector &vchBytes); + // Initialize from pubkey + bool setPubKey(const CPubKey &vchPubKey); + // Serialize to octets stream bool getBytes(std::vector &vchBytes); @@ -233,7 +236,7 @@ public: bool operator==(const CMalleablePubKey &b); bool operator!=(const CMalleablePubKey &b) { return !(*this == b); } - std::string ToString(); + std::string ToString() const; bool SetString(const std::string& strMalleablePubKey); uint256 GetID() const; @@ -267,7 +270,7 @@ public: READWRITE(vchSecretH); ) - std::string ToString(); + std::string ToString() const; bool SetString(const std::string& strMalleablePubKey); void Reset(); @@ -277,23 +280,21 @@ public: void GetSecrets(CSecret &pvchSecretL, CSecret &pvchSecretH) const; CMalleablePubKey GetMalleablePubKey() const; - - bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant); - bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant, CKey &privKeyVariant); + bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const; + bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant, CKey &privKeyVariant) const; }; class CMalleableKeyView { private: + unsigned char nVersion; CSecret vchSecretL; - std::vector vchPubKeyH; - - // disabled constructor - CMalleableKeyView() { }; + CPubKey vchPubKeyH; static const unsigned char CURRENT_VERSION = 1; public: + CMalleableKeyView() { nVersion = 0; }; CMalleableKeyView(const CMalleableKey &b); CMalleableKeyView(const CSecret &L, const CPubKey &pvchPubKeyH); @@ -301,9 +302,22 @@ public: CMalleableKeyView& operator=(const CMalleableKey &b); ~CMalleableKeyView(); + + IMPLEMENT_SERIALIZE( + READWRITE(this->nVersion); + nVersion = this->nVersion; + READWRITE(vchSecretL); + READWRITE(vchPubKeyH); + ) + + bool IsNull() const; + std::string ToString() const; + bool SetString(const std::string& strMalleablePubKey); + CMalleablePubKey GetMalleablePubKey() const; + bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant) const; - bool CheckKeyVariant(const CPubKey &R, const CPubKey &vchPubKeyVariant); + bool operator <(const CMalleableKeyView& kv) const { return vchPubKeyH.GetID() < kv.vchPubKeyH.GetID(); } }; #endif diff --git a/src/keystore.cpp b/src/keystore.cpp index ef61748..fdba291 100644 --- a/src/keystore.cpp +++ b/src/keystore.cpp @@ -102,6 +102,19 @@ bool CBasicKeyStore::HaveWatchOnly() const return (!setWatchOnly.empty()); } +CCryptoKeyStore::CCryptoKeyStore() : fUseCrypto(false) +{ + std::string strMalleableKey = GetArg("-masterkey", ""); + CMalleableKey malleableKey; + if (strMalleableKey != "") + malleableKey.SetString(strMalleableKey); + else + malleableKey.MakeNewKeys(); + + const CMalleableKeyView& keyView(malleableKey); + mapMalleableKeys[keyView] = malleableKey; +} + bool CCryptoKeyStore::SetCrypted() { { @@ -154,6 +167,7 @@ bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn) break; return false; } + vMasterKey = vMasterKeyIn; } NotifyStatusChanged(this); diff --git a/src/keystore.h b/src/keystore.h index 96285fb..7d49735 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -64,17 +64,24 @@ public: vchSecret = key.GetSecret(fCompressed); return true; } + + virtual bool CheckOwnership(const CPubKey &pubKeyVariant, const CPubKey &R) const =0; + virtual bool CreatePrivKey(const CPubKey &pubKeyVariant, const CPubKey &R, CKey &privKey) const =0; + virtual void ListMalleablePubKeys(std::list &malleablePubKeyList) const =0; }; typedef std::map > KeyMap; typedef std::map ScriptMap; typedef std::set WatchOnlySet; +typedef std::map MalleableKeyMap; /** Basic key store, that keeps keys in an address->secret map */ class CBasicKeyStore : public CKeyStore { protected: KeyMap mapKeys; + MalleableKeyMap mapMalleableKeys; + ScriptMap mapScripts; WatchOnlySet setWatchOnly; @@ -124,6 +131,43 @@ public: virtual bool RemoveWatchOnly(const CScript &dest); virtual bool HaveWatchOnly(const CScript &dest) const; virtual bool HaveWatchOnly() const; + + bool CheckOwnership(const CPubKey &pubKeyVariant, const CPubKey &R) const + { + { + LOCK(cs_KeyStore); + for (MalleableKeyMap::const_iterator mi = mapMalleableKeys.begin(); mi != mapMalleableKeys.end(); mi++) + { + if (mi->first.CheckKeyVariant(R, pubKeyVariant)) + return true; + } + } + return false; + } + + bool CreatePrivKey(const CPubKey &pubKeyVariant, const CPubKey &R, CKey &privKey) const + { + { + LOCK(cs_KeyStore); + for (MalleableKeyMap::const_iterator mi = mapMalleableKeys.begin(); mi != mapMalleableKeys.end(); mi++) + { + if (mi->second.CheckKeyVariant(R, pubKeyVariant, privKey)) + return true; + } + } + return false; + } + + void ListMalleablePubKeys(std::list &malleablePubKeyList) const + { + malleablePubKeyList.clear(); + + { + LOCK(cs_KeyStore); + for (MalleableKeyMap::const_iterator mi = mapMalleableKeys.begin(); mi != mapMalleableKeys.end(); mi++) + malleablePubKeyList.push_back(mi->first.GetMalleablePubKey()); + } + } }; typedef std::map > > CryptedKeyMap; @@ -152,9 +196,7 @@ protected: bool Unlock(const CKeyingMaterial& vMasterKeyIn); public: - CCryptoKeyStore() : fUseCrypto(false) - { - } + CCryptoKeyStore(); bool IsCrypted() const { diff --git a/src/main.cpp b/src/main.cpp index befcfaa..3291054 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2137,7 +2137,7 @@ bool CBlock::AddToBlockIndex(unsigned int nFile, unsigned int nBlockPos) return error("AddToBlockIndex() : %s already exists", hash.ToString().substr(0,20).c_str()); // Construct new block index object - CBlockIndex* pindexNew = new CBlockIndex(nFile, nBlockPos, *this); + CBlockIndex* pindexNew = new(nothrow) CBlockIndex(nFile, nBlockPos, *this); if (!pindexNew) return error("AddToBlockIndex() : new CBlockIndex failed"); pindexNew->phashBlock = &hash; diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index c2b43c7..6a7a3b1 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1936,3 +1936,22 @@ Value adjustmalleablepubkey(const Array& params, bool fHelp) return result; } + +Value listmalleablepubkeys(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "listmalleablepubkeys\n" + "Get list of malleable public keys.\n"); + + std::list keyList; + pwalletMain->ListMalleablePubKeys(keyList); + + Array result; + BOOST_FOREACH(const CMalleablePubKey &key, keyList) + { + result.push_back(key.ToString()); + } + + return result; +} diff --git a/src/script.cpp b/src/script.cpp index 9079102..26b7c94 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -1328,6 +1328,21 @@ bool Sign1(const CKeyID& address, const CKeyStore& keystore, const uint256& hash return true; } +bool SignR(const CPubKey& pubKey, const CPubKey& R, const CKeyStore& keystore, const uint256& hash, int nHashType, CScript& scriptSigRet) +{ + CKey key; + if (!keystore.CreatePrivKey(pubKey, R, key)) + return false; + + vector vchSig; + if (!key.Sign(hash, vchSig)) + return false; + vchSig.push_back((unsigned char)nHashType); + scriptSigRet << vchSig; + + return true; +} + bool SignN(const vector& multisigdata, const CKeyStore& keystore, const uint256& hash, int nHashType, CScript& scriptSigRet) { int nSigned = 0; @@ -1364,9 +1379,14 @@ bool Solver(const CKeyStore& keystore, const CScript& scriptPubKey, const uint25 case TX_NULL_DATA: return false; case TX_PUBKEY: - case TX_PUBKEY_DROP: keyID = CPubKey(vSolutions[0]).GetID(); return Sign1(keyID, keystore, hash, nHashType, scriptSigRet); + case TX_PUBKEY_DROP: + { + CPubKey key = CPubKey(vSolutions[0]); + CPubKey R = CPubKey(vSolutions[1]); + return SignR(key, R, keystore, hash, nHashType, scriptSigRet); + } case TX_PUBKEYHASH: keyID = CKeyID(uint160(vSolutions[0])); if (!Sign1(keyID, keystore, hash, nHashType, scriptSigRet)) @@ -1480,11 +1500,23 @@ isminetype IsMine(const CKeyStore &keystore, const CScript& scriptPubKey) case TX_NULL_DATA: break; case TX_PUBKEY: - case TX_PUBKEY_DROP: keyID = CPubKey(vSolutions[0]).GetID(); if (keystore.HaveKey(keyID)) return MINE_SPENDABLE; break; + case TX_PUBKEY_DROP: + { + CPubKey key = CPubKey(vSolutions[0]); + if (keystore.HaveKey(key.GetID())) + return MINE_SPENDABLE; + else + { + CPubKey R = CPubKey(vSolutions[1]); + if (keystore.CheckOwnership(key, R)) + return MINE_SPENDABLE; + } + } + break; case TX_PUBKEYHASH: keyID = CKeyID(uint160(vSolutions[0])); if (keystore.HaveKey(keyID)) @@ -1527,7 +1559,7 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet) if (!Solver(scriptPubKey, whichType, vSolutions)) return false; - if (whichType == TX_PUBKEY) + if (whichType == TX_PUBKEY || whichType == TX_PUBKEY_DROP) { addressRet = CPubKey(vSolutions[0]).GetID(); return true; diff --git a/src/txdb-bdb.cpp b/src/txdb-bdb.cpp index bbfb656..5ce59b5 100644 --- a/src/txdb-bdb.cpp +++ b/src/txdb-bdb.cpp @@ -160,7 +160,7 @@ CBlockIndex static * InsertBlockIndex(uint256 hash) return (*mi).second; // Create new - CBlockIndex* pindexNew = new CBlockIndex(); + CBlockIndex* pindexNew = new(nothrow) CBlockIndex(); if (!pindexNew) throw runtime_error("LoadBlockIndex() : new CBlockIndex failed"); mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; diff --git a/src/txdb-leveldb.cpp b/src/txdb-leveldb.cpp index 4a7a3cf..97bf88c 100644 --- a/src/txdb-leveldb.cpp +++ b/src/txdb-leveldb.cpp @@ -325,7 +325,7 @@ static CBlockIndex *InsertBlockIndex(uint256 hash) return (*mi).second; // Create new - CBlockIndex* pindexNew = new CBlockIndex(); + CBlockIndex* pindexNew = new(nothrow) CBlockIndex(); if (!pindexNew) throw runtime_error("LoadBlockIndex() : new CBlockIndex failed"); mi = mapBlockIndex.insert(make_pair(hash, pindexNew)).first; diff --git a/src/util.cpp b/src/util.cpp index f6d80f7..7fb43bc 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -331,7 +331,7 @@ string vstrprintf(const char *format, va_list ap) if (p != buffer) delete[] p; limit *= 2; - p = new char[limit]; + p = new(nothrow) char[limit]; if (p == NULL) throw std::bad_alloc(); }