diff options
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 56 |
1 files changed, 47 insertions, 9 deletions
diff --git a/src/main.cpp b/src/main.cpp index 0342650..e149062 100644 --- a/src/main.cpp +++ b/src/main.cpp | |||
| @@ -165,6 +165,9 @@ int MinerThreadCount() | |||
| 165 | return (int)(nCores - 1); | 165 | return (int)(nCores - 1); |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | static void SecureClearBytes(vector<unsigned char>& vch); | ||
| 169 | static void SecureClearKeyingMaterial(CKeyingMaterial& vch); | ||
| 170 | |||
| 168 | bool AddKey(const CKey& key) | 171 | bool AddKey(const CKey& key) |
| 169 | { | 172 | { |
| 170 | if (IsWalletEncrypted()) | 173 | if (IsWalletEncrypted()) |
| @@ -174,9 +177,13 @@ bool AddKey(const CKey& key) | |||
| 174 | vector<unsigned char> vchCryptedSecret; | 177 | vector<unsigned char> vchCryptedSecret; |
| 175 | if (IsWalletLocked()) | 178 | if (IsWalletLocked()) |
| 176 | return error("AddKey() : wallet is locked\n"); | 179 | return error("AddKey() : wallet is locked\n"); |
| 177 | if (!EncryptSecret(vWalletMasterKey, vector<unsigned char>(vchPrivKey.begin(), vchPrivKey.end()), | 180 | vector<unsigned char> vchPlainSecret(vchPrivKey.begin(), vchPrivKey.end()); |
| 178 | WalletKeyIV(key.GetPubKey()), vchCryptedSecret)) | 181 | if (!EncryptSecret(vWalletMasterKey, vchPlainSecret, WalletKeyIV(key.GetPubKey()), vchCryptedSecret)) |
| 182 | { | ||
| 183 | SecureClearBytes(vchPlainSecret); | ||
| 179 | return error("AddKey() : encrypting key failed\n"); | 184 | return error("AddKey() : encrypting key failed\n"); |
| 185 | } | ||
| 186 | SecureClearBytes(vchPlainSecret); | ||
| 180 | if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret)) | 187 | if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret)) |
| 181 | return false; | 188 | return false; |
| 182 | return CWalletDB().WriteCryptedKey(key.GetPubKey(), vchCryptedSecret); | 189 | return CWalletDB().WriteCryptedKey(key.GetPubKey(), vchCryptedSecret); |
| @@ -200,17 +207,31 @@ bool IsWalletLocked() | |||
| 200 | return fWalletEncrypted && fWalletLocked; | 207 | return fWalletEncrypted && fWalletLocked; |
| 201 | } | 208 | } |
| 202 | 209 | ||
| 210 | static void SecureClearBytes(vector<unsigned char>& vch) | ||
| 211 | { | ||
| 212 | if (!vch.empty()) | ||
| 213 | OPENSSL_cleanse(&vch[0], vch.size()); | ||
| 214 | vch.clear(); | ||
| 215 | } | ||
| 216 | |||
| 217 | static void SecureClearKeyingMaterial(CKeyingMaterial& vch) | ||
| 218 | { | ||
| 219 | if (!vch.empty()) | ||
| 220 | OPENSSL_cleanse(&vch[0], vch.size()); | ||
| 221 | vch.clear(); | ||
| 222 | } | ||
| 223 | |||
| 203 | void LockWallet() | 224 | void LockWallet() |
| 204 | { | 225 | { |
| 205 | if (!fWalletEncrypted) | 226 | if (!fWalletEncrypted) |
| 206 | return; | 227 | return; |
| 207 | CRITICAL_BLOCK(cs_mapKeys) | 228 | CRITICAL_BLOCK(cs_mapKeys) |
| 208 | { | 229 | { |
| 209 | vWalletMasterKey.clear(); | 230 | SecureClearKeyingMaterial(vWalletMasterKey); |
| 210 | if (!vchCryptedHDMaster.empty()) | 231 | if (!vchCryptedHDMaster.empty()) |
| 211 | vchHDMaster.clear(); | 232 | SecureClearBytes(vchHDMaster); |
| 212 | if (!vchCryptedHDChainCode.empty()) | 233 | if (!vchCryptedHDChainCode.empty()) |
| 213 | vchHDChainCode.clear(); | 234 | SecureClearBytes(vchHDChainCode); |
| 214 | fWalletLocked = true; | 235 | fWalletLocked = true; |
| 215 | } | 236 | } |
| 216 | } | 237 | } |
| @@ -235,14 +256,14 @@ bool DeriveWalletPassphraseKey(const string& strPassphrase, | |||
| 235 | chKey, chIV); | 256 | chKey, chIV); |
| 236 | if (n != 32) | 257 | if (n != 32) |
| 237 | { | 258 | { |
| 238 | memset(chKey, 0, sizeof(chKey)); | 259 | OPENSSL_cleanse(chKey, sizeof(chKey)); |
| 239 | memset(chIV, 0, sizeof(chIV)); | 260 | OPENSSL_cleanse(chIV, sizeof(chIV)); |
| 240 | return false; | 261 | return false; |
| 241 | } | 262 | } |
| 242 | vchKeyRet.assign(chKey, chKey + sizeof(chKey)); | 263 | vchKeyRet.assign(chKey, chKey + sizeof(chKey)); |
| 243 | vchIVRet.assign(chIV, chIV + sizeof(chIV)); | 264 | vchIVRet.assign(chIV, chIV + sizeof(chIV)); |
| 244 | memset(chKey, 0, sizeof(chKey)); | 265 | OPENSSL_cleanse(chKey, sizeof(chKey)); |
| 245 | memset(chIV, 0, sizeof(chIV)); | 266 | OPENSSL_cleanse(chIV, sizeof(chIV)); |
| 246 | return true; | 267 | return true; |
| 247 | } | 268 | } |
| 248 | 269 | ||
| @@ -303,6 +324,8 @@ bool DecryptSecret(const CKeyingMaterial& vchKey, | |||
| 303 | vchPlaintextRet.swap(vchOut); | 324 | vchPlaintextRet.swap(vchOut); |
| 304 | fOk = true; | 325 | fOk = true; |
| 305 | } | 326 | } |
| 327 | if (!fOk) | ||
| 328 | SecureClearBytes(vchOut); | ||
| 306 | EVP_CIPHER_CTX_free(ctx); | 329 | EVP_CIPHER_CTX_free(ctx); |
| 307 | return fOk; | 330 | return fOk; |
| 308 | } | 331 | } |
| @@ -378,6 +401,7 @@ bool GetWalletPrivKey(const vector<unsigned char>& vchPubKey, | |||
| 378 | } | 401 | } |
| 379 | 402 | ||
| 380 | CPrivKey vchPrivKey(vchPlaintext.begin(), vchPlaintext.end()); | 403 | CPrivKey vchPrivKey(vchPlaintext.begin(), vchPlaintext.end()); |
| 404 | SecureClearBytes(vchPlaintext); | ||
| 381 | CKey key; | 405 | CKey key; |
| 382 | if (!key.SetPrivKey(vchPrivKey) || key.GetPubKey() != vchPubKey) | 406 | if (!key.SetPrivKey(vchPrivKey) || key.GetPubKey() != vchPubKey) |
| 383 | { | 407 | { |
| @@ -412,11 +436,20 @@ bool UnlockWallet(const string& strPassphrase, string& strErrorRet) | |||
| 412 | vector<unsigned char> vchMasterPlain; | 436 | vector<unsigned char> vchMasterPlain; |
| 413 | if (!DecryptSecret(vchPassKey, kMasterKey.vchCryptedKey, | 437 | if (!DecryptSecret(vchPassKey, kMasterKey.vchCryptedKey, |
| 414 | vchPassIV, vchMasterPlain)) | 438 | vchPassIV, vchMasterPlain)) |
| 439 | { | ||
| 440 | SecureClearBytes(vchPassIV); | ||
| 415 | continue; | 441 | continue; |
| 442 | } | ||
| 416 | if (vchMasterPlain.size() != 32) | 443 | if (vchMasterPlain.size() != 32) |
| 444 | { | ||
| 445 | SecureClearBytes(vchMasterPlain); | ||
| 446 | SecureClearBytes(vchPassIV); | ||
| 417 | continue; | 447 | continue; |
| 448 | } | ||
| 418 | 449 | ||
| 419 | CKeyingMaterial vchCandidate(vchMasterPlain.begin(), vchMasterPlain.end()); | 450 | CKeyingMaterial vchCandidate(vchMasterPlain.begin(), vchMasterPlain.end()); |
| 451 | SecureClearBytes(vchMasterPlain); | ||
| 452 | SecureClearBytes(vchPassIV); | ||
| 420 | bool fValid = mapCryptedKeys.empty(); | 453 | bool fValid = mapCryptedKeys.empty(); |
| 421 | for (map<vector<unsigned char>, vector<unsigned char> >::iterator mci = mapCryptedKeys.begin(); | 454 | for (map<vector<unsigned char>, vector<unsigned char> >::iterator mci = mapCryptedKeys.begin(); |
| 422 | mci != mapCryptedKeys.end(); ++mci) | 455 | mci != mapCryptedKeys.end(); ++mci) |
| @@ -425,6 +458,7 @@ bool UnlockWallet(const string& strPassphrase, string& strErrorRet) | |||
| 425 | if (!DecryptSecret(vchCandidate, (*mci).second, WalletKeyIV((*mci).first), vchPlaintext)) | 458 | if (!DecryptSecret(vchCandidate, (*mci).second, WalletKeyIV((*mci).first), vchPlaintext)) |
| 426 | break; | 459 | break; |
| 427 | CPrivKey vchPrivKey(vchPlaintext.begin(), vchPlaintext.end()); | 460 | CPrivKey vchPrivKey(vchPlaintext.begin(), vchPlaintext.end()); |
| 461 | SecureClearBytes(vchPlaintext); | ||
| 428 | CKey key; | 462 | CKey key; |
| 429 | if (key.SetPrivKey(vchPrivKey) && key.GetPubKey() == (*mci).first) | 463 | if (key.SetPrivKey(vchPrivKey) && key.GetPubKey() == (*mci).first) |
| 430 | fValid = true; | 464 | fValid = true; |
| @@ -440,10 +474,12 @@ bool UnlockWallet(const string& strPassphrase, string& strErrorRet) | |||
| 440 | WalletSecretIV("hdmaster"), vchPlainHDMaster) || | 474 | WalletSecretIV("hdmaster"), vchPlainHDMaster) || |
| 441 | vchPlainHDMaster.size() != 32) | 475 | vchPlainHDMaster.size() != 32) |
| 442 | { | 476 | { |
| 477 | SecureClearBytes(vchPlainHDMaster); | ||
| 443 | strErrorRet = "could not decrypt HD master key"; | 478 | strErrorRet = "could not decrypt HD master key"; |
| 444 | return false; | 479 | return false; |
| 445 | } | 480 | } |
| 446 | vchHDMaster = vchPlainHDMaster; | 481 | vchHDMaster = vchPlainHDMaster; |
| 482 | SecureClearBytes(vchPlainHDMaster); | ||
| 447 | } | 483 | } |
| 448 | if (!vchCryptedHDChainCode.empty()) | 484 | if (!vchCryptedHDChainCode.empty()) |
| 449 | { | 485 | { |
| @@ -452,10 +488,12 @@ bool UnlockWallet(const string& strPassphrase, string& strErrorRet) | |||
| 452 | WalletSecretIV("hdchaincode"), vchPlainHDChainCode) || | 488 | WalletSecretIV("hdchaincode"), vchPlainHDChainCode) || |
| 453 | vchPlainHDChainCode.size() != 32) | 489 | vchPlainHDChainCode.size() != 32) |
| 454 | { | 490 | { |
| 491 | SecureClearBytes(vchPlainHDChainCode); | ||
| 455 | strErrorRet = "could not decrypt HD chain code"; | 492 | strErrorRet = "could not decrypt HD chain code"; |
| 456 | return false; | 493 | return false; |
| 457 | } | 494 | } |
| 458 | vchHDChainCode = vchPlainHDChainCode; | 495 | vchHDChainCode = vchPlainHDChainCode; |
| 496 | SecureClearBytes(vchPlainHDChainCode); | ||
| 459 | } | 497 | } |
| 460 | fWalletLocked = false; | 498 | fWalletLocked = false; |
| 461 | return true; | 499 | return true; |