Projects : bitcoin : bitcoin_db_shutdown_checkpoint_calming

bitcoin/src/keystore.cpp

Dir - Raw

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