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.h 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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. #ifndef BITCOIN_KEYSTORE_H
  6. #define BITCOIN_KEYSTORE_H
  7. #include "key.h"
  8. #include "sync.h"
  9. #include <boost/signals2/signal.hpp>
  10. class CScript;
  11. /** A virtual base class for key stores */
  12. class CKeyStore
  13. {
  14. protected:
  15. mutable CCriticalSection cs_KeyStore;
  16. public:
  17. virtual ~CKeyStore() {}
  18. // Add a key to the store.
  19. virtual bool AddKeyPubKey(const CKey &key, const CPubKey &pubkey) =0;
  20. virtual bool AddKey(const CKey &key);
  21. // Check whether a key corresponding to a given address is present in the store.
  22. virtual bool HaveKey(const CKeyID &address) const =0;
  23. virtual bool GetKey(const CKeyID &address, CKey& keyOut) const =0;
  24. virtual void GetKeys(std::set<CKeyID> &setAddress) const =0;
  25. virtual bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
  26. // Support for BIP 0013 : see https://en.bitcoin.it/wiki/BIP_0013
  27. virtual bool AddCScript(const CScript& redeemScript) =0;
  28. virtual bool HaveCScript(const CScriptID &hash) const =0;
  29. virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const =0;
  30. };
  31. typedef std::map<CKeyID, CKey> KeyMap;
  32. typedef std::map<CScriptID, CScript > ScriptMap;
  33. /** Basic key store, that keeps keys in an address->secret map */
  34. class CBasicKeyStore : public CKeyStore
  35. {
  36. protected:
  37. KeyMap mapKeys;
  38. ScriptMap mapScripts;
  39. public:
  40. bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
  41. bool HaveKey(const CKeyID &address) const
  42. {
  43. bool result;
  44. {
  45. LOCK(cs_KeyStore);
  46. result = (mapKeys.count(address) > 0);
  47. }
  48. return result;
  49. }
  50. void GetKeys(std::set<CKeyID> &setAddress) const
  51. {
  52. setAddress.clear();
  53. {
  54. LOCK(cs_KeyStore);
  55. KeyMap::const_iterator mi = mapKeys.begin();
  56. while (mi != mapKeys.end())
  57. {
  58. setAddress.insert((*mi).first);
  59. mi++;
  60. }
  61. }
  62. }
  63. bool GetKey(const CKeyID &address, CKey &keyOut) const
  64. {
  65. {
  66. LOCK(cs_KeyStore);
  67. KeyMap::const_iterator mi = mapKeys.find(address);
  68. if (mi != mapKeys.end())
  69. {
  70. keyOut = mi->second;
  71. return true;
  72. }
  73. }
  74. return false;
  75. }
  76. virtual bool AddCScript(const CScript& redeemScript);
  77. virtual bool HaveCScript(const CScriptID &hash) const;
  78. virtual bool GetCScript(const CScriptID &hash, CScript& redeemScriptOut) const;
  79. };
  80. typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
  81. typedef std::map<CKeyID, std::pair<CPubKey, std::vector<unsigned char> > > CryptedKeyMap;
  82. /** Keystore which keeps the private keys encrypted.
  83. * It derives from the basic key store, which is used if no encryption is active.
  84. */
  85. class CCryptoKeyStore : public CBasicKeyStore
  86. {
  87. private:
  88. CryptedKeyMap mapCryptedKeys;
  89. CKeyingMaterial vMasterKey;
  90. // if fUseCrypto is true, mapKeys must be empty
  91. // if fUseCrypto is false, vMasterKey must be empty
  92. bool fUseCrypto;
  93. protected:
  94. bool SetCrypted();
  95. // will encrypt previously unencrypted keys
  96. bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
  97. bool Unlock(const CKeyingMaterial& vMasterKeyIn);
  98. public:
  99. CCryptoKeyStore() : fUseCrypto(false)
  100. {
  101. }
  102. bool IsCrypted() const
  103. {
  104. return fUseCrypto;
  105. }
  106. bool IsLocked() const
  107. {
  108. if (!IsCrypted())
  109. return false;
  110. bool result;
  111. {
  112. LOCK(cs_KeyStore);
  113. result = vMasterKey.empty();
  114. }
  115. return result;
  116. }
  117. bool Lock();
  118. virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
  119. bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey);
  120. bool HaveKey(const CKeyID &address) const
  121. {
  122. {
  123. LOCK(cs_KeyStore);
  124. if (!IsCrypted())
  125. return CBasicKeyStore::HaveKey(address);
  126. return mapCryptedKeys.count(address) > 0;
  127. }
  128. return false;
  129. }
  130. bool GetKey(const CKeyID &address, CKey& keyOut) const;
  131. bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const;
  132. void GetKeys(std::set<CKeyID> &setAddress) const
  133. {
  134. if (!IsCrypted())
  135. {
  136. CBasicKeyStore::GetKeys(setAddress);
  137. return;
  138. }
  139. setAddress.clear();
  140. CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
  141. while (mi != mapCryptedKeys.end())
  142. {
  143. setAddress.insert((*mi).first);
  144. mi++;
  145. }
  146. }
  147. /* Wallet status (encrypted, locked) changed.
  148. * Note: Called without locks held.
  149. */
  150. boost::signals2::signal<void (CCryptoKeyStore* wallet)> NotifyStatusChanged;
  151. };
  152. #endif