Projects : bitcoin : bitcoin_db_shutdown_checkpoint_calming
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 | |
10 | std::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 | |
20 | bool 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 | |
29 | bool CBasicKeyStore::AddKey(const CKey& key) |
30 | { |
31 | CRITICAL_BLOCK(cs_KeyStore) |
32 | mapKeys[CBitcoinAddress(key.GetPubKey())] = key.GetSecret(); |
33 | return true; |
34 | } |
35 | |
36 | bool 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 | |
49 | std::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 | |
59 | bool 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 | |
85 | bool 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 | |
107 | bool 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 | |
119 | bool 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 | |
141 | bool 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 | |
158 | bool 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 | } |