[tests] Add bitcoin_cli.py test script
[bitcoinplatinum.git] / src / wallet / crypter.h
blob1dc44e424f631f4cd419443a0b338fc68b9f9f47
1 // Copyright (c) 2009-2016 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #ifndef BITCOIN_WALLET_CRYPTER_H
6 #define BITCOIN_WALLET_CRYPTER_H
8 #include "keystore.h"
9 #include "serialize.h"
10 #include "support/allocators/secure.h"
12 const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
13 const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
14 const unsigned int WALLET_CRYPTO_IV_SIZE = 16;
16 /**
17 * Private key encryption is done based on a CMasterKey,
18 * which holds a salt and random encryption key.
20 * CMasterKeys are encrypted using AES-256-CBC using a key
21 * derived using derivation method nDerivationMethod
22 * (0 == EVP_sha512()) and derivation iterations nDeriveIterations.
23 * vchOtherDerivationParameters is provided for alternative algorithms
24 * which may require more parameters (such as scrypt).
26 * Wallet Private Keys are then encrypted using AES-256-CBC
27 * with the double-sha256 of the public key as the IV, and the
28 * master key's key as the encryption key (see keystore.[ch]).
31 /** Master key for wallet encryption */
32 class CMasterKey
34 public:
35 std::vector<unsigned char> vchCryptedKey;
36 std::vector<unsigned char> vchSalt;
37 //! 0 = EVP_sha512()
38 //! 1 = scrypt()
39 unsigned int nDerivationMethod;
40 unsigned int nDeriveIterations;
41 //! Use this for more parameters to key derivation,
42 //! such as the various parameters to scrypt
43 std::vector<unsigned char> vchOtherDerivationParameters;
45 ADD_SERIALIZE_METHODS;
47 template <typename Stream, typename Operation>
48 inline void SerializationOp(Stream& s, Operation ser_action) {
49 READWRITE(vchCryptedKey);
50 READWRITE(vchSalt);
51 READWRITE(nDerivationMethod);
52 READWRITE(nDeriveIterations);
53 READWRITE(vchOtherDerivationParameters);
56 CMasterKey()
58 // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M
59 // ie slightly lower than the lowest hardware we need bother supporting
60 nDeriveIterations = 25000;
61 nDerivationMethod = 0;
62 vchOtherDerivationParameters = std::vector<unsigned char>(0);
66 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
68 namespace wallet_crypto
70 class TestCrypter;
73 /** Encryption/decryption context with key information */
74 class CCrypter
76 friend class wallet_crypto::TestCrypter; // for test access to chKey/chIV
77 private:
78 std::vector<unsigned char, secure_allocator<unsigned char>> vchKey;
79 std::vector<unsigned char, secure_allocator<unsigned char>> vchIV;
80 bool fKeySet;
82 int BytesToKeySHA512AES(const std::vector<unsigned char>& chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const;
84 public:
85 bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
86 bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext) const;
87 bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext) const;
88 bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV);
90 void CleanKey()
92 memory_cleanse(vchKey.data(), vchKey.size());
93 memory_cleanse(vchIV.data(), vchIV.size());
94 fKeySet = false;
97 CCrypter()
99 fKeySet = false;
100 vchKey.resize(WALLET_CRYPTO_KEY_SIZE);
101 vchIV.resize(WALLET_CRYPTO_IV_SIZE);
104 ~CCrypter()
106 CleanKey();
110 /** Keystore which keeps the private keys encrypted.
111 * It derives from the basic key store, which is used if no encryption is active.
113 class CCryptoKeyStore : public CBasicKeyStore
115 private:
116 CryptedKeyMap mapCryptedKeys;
118 CKeyingMaterial vMasterKey;
120 //! if fUseCrypto is true, mapKeys must be empty
121 //! if fUseCrypto is false, vMasterKey must be empty
122 bool fUseCrypto;
124 //! keeps track of whether Unlock has run a thorough check before
125 bool fDecryptionThoroughlyChecked;
127 protected:
128 bool SetCrypted();
130 //! will encrypt previously unencrypted keys
131 bool EncryptKeys(CKeyingMaterial& vMasterKeyIn);
133 bool Unlock(const CKeyingMaterial& vMasterKeyIn);
135 public:
136 CCryptoKeyStore() : fUseCrypto(false), fDecryptionThoroughlyChecked(false)
140 bool IsCrypted() const
142 return fUseCrypto;
145 bool IsLocked() const
147 if (!IsCrypted())
148 return false;
149 bool result;
151 LOCK(cs_KeyStore);
152 result = vMasterKey.empty();
154 return result;
157 bool Lock();
159 virtual bool AddCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigned char> &vchCryptedSecret);
160 bool AddKeyPubKey(const CKey& key, const CPubKey &pubkey) override;
161 bool HaveKey(const CKeyID &address) const override
164 LOCK(cs_KeyStore);
165 if (!IsCrypted())
166 return CBasicKeyStore::HaveKey(address);
167 return mapCryptedKeys.count(address) > 0;
169 return false;
171 bool GetKey(const CKeyID &address, CKey& keyOut) const override;
172 bool GetPubKey(const CKeyID &address, CPubKey& vchPubKeyOut) const override;
173 void GetKeys(std::set<CKeyID> &setAddress) const override
175 if (!IsCrypted())
177 CBasicKeyStore::GetKeys(setAddress);
178 return;
180 setAddress.clear();
181 CryptedKeyMap::const_iterator mi = mapCryptedKeys.begin();
182 while (mi != mapCryptedKeys.end())
184 setAddress.insert((*mi).first);
185 mi++;
190 * Wallet status (encrypted, locked) changed.
191 * Note: Called without locks held.
193 boost::signals2::signal<void (CCryptoKeyStore* wallet)> NotifyStatusChanged;
196 #endif // BITCOIN_WALLET_CRYPTER_H