| 824 | } |
| 825 | |
| 826 | bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) |
| 827 | { |
| 828 | // Only descriptor wallets can be encrypted |
| 829 | Assert(IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)); |
| 830 | |
| 831 | if (HasEncryptionKeys()) |
| 832 | return false; |
| 833 | |
| 834 | CKeyingMaterial plain_master_key; |
| 835 | |
| 836 | plain_master_key.resize(WALLET_CRYPTO_KEY_SIZE); |
| 837 | GetStrongRandBytes(plain_master_key); |
| 838 | |
| 839 | CMasterKey master_key; |
| 840 | |
| 841 | master_key.vchSalt.resize(WALLET_CRYPTO_SALT_SIZE); |
| 842 | GetStrongRandBytes(master_key.vchSalt); |
| 843 | |
| 844 | if (!EncryptMasterKey(strWalletPassphrase, plain_master_key, master_key)) { |
| 845 | return false; |
| 846 | } |
| 847 | WalletLogPrintf("Encrypting Wallet with an nDeriveIterations of %i\n", master_key.nDeriveIterations); |
| 848 | |
| 849 | { |
| 850 | LOCK2(m_relock_mutex, cs_wallet); |
| 851 | mapMasterKeys[++nMasterKeyMaxID] = master_key; |
| 852 | WalletBatch* encrypted_batch = new WalletBatch(GetDatabase()); |
| 853 | if (!encrypted_batch->TxnBegin()) { |
| 854 | delete encrypted_batch; |
| 855 | encrypted_batch = nullptr; |
| 856 | return false; |
| 857 | } |
| 858 | encrypted_batch->WriteMasterKey(nMasterKeyMaxID, master_key); |
| 859 | |
| 860 | for (const auto& spk_man_pair : m_spk_managers) { |
| 861 | auto spk_man = spk_man_pair.second.get(); |
| 862 | if (!spk_man->Encrypt(plain_master_key, encrypted_batch)) { |
| 863 | encrypted_batch->TxnAbort(); |
| 864 | delete encrypted_batch; |
| 865 | encrypted_batch = nullptr; |
| 866 | // We now probably have half of our keys encrypted in memory, and half not... |
| 867 | // die and let the user reload the unencrypted wallet. |
| 868 | assert(false); |
| 869 | } |
| 870 | } |
| 871 | |
| 872 | if (!encrypted_batch->TxnCommit()) { |
| 873 | delete encrypted_batch; |
| 874 | encrypted_batch = nullptr; |
| 875 | // We now have keys encrypted in memory, but not on disk... |
| 876 | // die to avoid confusion and let the user reload the unencrypted wallet. |
| 877 | assert(false); |
| 878 | } |
| 879 | |
| 880 | delete encrypted_batch; |
| 881 | encrypted_batch = nullptr; |
| 882 | |
| 883 | Lock(); |
no test coverage detected