You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

keystore.cpp 5.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // Copyright (c) 2009-2010 Satoshi Nakamoto
  2. // Copyright (c) 2009-2013 The Bitcoin developers
  3. // Distributed under the MIT/X11 software license, see the accompanying
  4. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  5. #include "keystore.h"
  6. #include "crypter.h"
  7. #include "key.h"
  8. #include "script.h"
  9. #include <boost/foreach.hpp>
  10. bool CKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
  11. {
  12. CKey key;
  13. if (!GetKey(address, key))
  14. return false;
  15. vchPubKeyOut = key.GetPubKey();
  16. return true;
  17. }
  18. bool CKeyStore::AddKey(const CKey &key) {
  19. return AddKeyPubKey(key, key.GetPubKey());
  20. }
  21. bool CBasicKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
  22. {
  23. LOCK(cs_KeyStore);
  24. mapKeys[pubkey.GetID()] = key;
  25. return true;
  26. }
  27. bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
  28. {
  29. LOCK(cs_KeyStore);
  30. mapScripts[redeemScript.GetID()] = redeemScript;
  31. return true;
  32. }
  33. bool CBasicKeyStore::HaveCScript(const CScriptID& hash) const
  34. {
  35. LOCK(cs_KeyStore);
  36. return mapScripts.count(hash) > 0;
  37. }
  38. bool CBasicKeyStore::GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const
  39. {
  40. LOCK(cs_KeyStore);
  41. ScriptMap::const_iterator mi = mapScripts.find(hash);
  42. if (mi != mapScripts.end())
  43. {
  44. redeemScriptOut = (*mi).second;
  45. return true;
  46. }
  47. return false;
  48. }
  49. bool CCryptoKeyStore::SetCrypted()
  50. {
  51. LOCK(cs_KeyStore);
  52. if (fUseCrypto)
  53. return true;
  54. if (!mapKeys.empty())
  55. return false;
  56. fUseCrypto = true;
  57. return true;
  58. }
  59. bool CCryptoKeyStore::Lock()
  60. {
  61. if (!SetCrypted())
  62. return false;
  63. {
  64. LOCK(cs_KeyStore);
  65. vMasterKey.clear();
  66. }
  67. NotifyStatusChanged(this);
  68. return true;
  69. }
  70. bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
  71. {
  72. {
  73. LOCK(cs_KeyStore);
  74. if (!SetCrypted())
  75. return false;
  76. CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
  77. for (; mi != mapCryptedKeys.end(); ++mi)
  78. {
  79. const CPubKey &vchPubKey = (*mi).second.first;
  80. const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
  81. CKeyingMaterial vchSecret;
  82. if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
  83. return false;
  84. if (vchSecret.size() != 32)
  85. return false;
  86. CKey key;
  87. key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
  88. if (key.GetPubKey() == vchPubKey)
  89. break;
  90. return false;
  91. }
  92. vMasterKey = vMasterKeyIn;
  93. }
  94. NotifyStatusChanged(this);
  95. return true;
  96. }
  97. bool CCryptoKeyStore::AddKeyPubKey(const CKey& key, const CPubKey &pubkey)
  98. {
  99. {
  100. LOCK(cs_KeyStore);
  101. if (!IsCrypted())
  102. return CBasicKeyStore::AddKeyPubKey(key, pubkey);
  103. if (IsLocked())
  104. return false;
  105. std::vector<unsigned char> vchCryptedSecret;
  106. CKeyingMaterial vchSecret(key.begin(), key.end());
  107. if (!EncryptSecret(vMasterKey, vchSecret, pubkey.GetHash(), vchCryptedSecret))
  108. return false;
  109. if (!AddCryptedKey(pubkey, vchCryptedSecret))
  110. return false;
  111. }
  112. return true;
  113. }
  114. bool CCryptoKeyStore::AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret)
  115. {
  116. {
  117. LOCK(cs_KeyStore);
  118. if (!SetCrypted())
  119. return false;
  120. mapCryptedKeys[vchPubKey.GetID()] = make_pair(vchPubKey, vchCryptedSecret);
  121. }
  122. return true;
  123. }
  124. bool CCryptoKeyStore::GetKey(const CKeyID &address, CKey& keyOut) const
  125. {
  126. {
  127. LOCK(cs_KeyStore);
  128. if (!IsCrypted())
  129. return CBasicKeyStore::GetKey(address, keyOut);
  130. CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
  131. if (mi != mapCryptedKeys.end())
  132. {
  133. const CPubKey &vchPubKey = (*mi).second.first;
  134. const std::vector<unsigned char> &vchCryptedSecret = (*mi).second.second;
  135. CKeyingMaterial vchSecret;
  136. if (!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
  137. return false;
  138. if (vchSecret.size() != 32)
  139. return false;
  140. keyOut.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
  141. return true;
  142. }
  143. }
  144. return false;
  145. }
  146. bool CCryptoKeyStore::GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const
  147. {
  148. {
  149. LOCK(cs_KeyStore);
  150. if (!IsCrypted())
  151. return CKeyStore::GetPubKey(address, vchPubKeyOut);
  152. CryptedKeyMap::const_iterator mi = mapCryptedKeys.find(address);
  153. if (mi != mapCryptedKeys.end())
  154. {
  155. vchPubKeyOut = (*mi).second.first;
  156. return true;
  157. }
  158. }
  159. return false;
  160. }
  161. bool CCryptoKeyStore::EncryptKeys(CKeyingMaterial& vMasterKeyIn)
  162. {
  163. {
  164. LOCK(cs_KeyStore);
  165. if (!mapCryptedKeys.empty() || IsCrypted())
  166. return false;
  167. fUseCrypto = true;
  168. BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
  169. {
  170. const CKey &key = mKey.second;
  171. CPubKey vchPubKey = key.GetPubKey();
  172. CKeyingMaterial vchSecret(key.begin(), key.end());
  173. std::vector<unsigned char> vchCryptedSecret;
  174. if (!EncryptSecret(vMasterKeyIn, vchSecret, vchPubKey.GetHash(), vchCryptedSecret))
  175. return false;
  176. if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
  177. return false;
  178. }
  179. mapKeys.clear();
  180. }
  181. return true;
  182. }