Auto merge of #1569 - str4d:1552-disable-wallet-encryption, r=daira
Disable wallet encryption Closes #1552
This commit is contained in:
commit
f90526579b
|
@ -14,6 +14,34 @@ make proving keys generated on 64-bit systems unusable on 32-bit and big-endian
|
||||||
systems. It's unclear if a warning will be issued in this case, or if the
|
systems. It's unclear if a warning will be issued in this case, or if the
|
||||||
proving system will be silently compromised.
|
proving system will be silently compromised.
|
||||||
|
|
||||||
|
Wallet Encryption
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
Wallet encryption is disabled, for several reasons:
|
||||||
|
|
||||||
|
- Encrypted wallets are unable to correctly detect shielded spends (due to the
|
||||||
|
nature of unlinkability of JoinSplits) and can incorrectly show larger
|
||||||
|
available shielded balances until the next time the wallet is unlocked. This
|
||||||
|
problem was not limited to failing to recognize the spend; it was possible for
|
||||||
|
the shown balance to increase by the amount of change from a spend, without
|
||||||
|
deducting the spent amount.
|
||||||
|
|
||||||
|
- While encrypted wallets prevent spending of funds, they do not maintain the
|
||||||
|
shielding properties of JoinSplits (due to the need to detect spends). That
|
||||||
|
is, someone with access to an encrypted wallet.dat has full visibility of
|
||||||
|
your entire transaction graph (other than newly-detected spends, which suffer
|
||||||
|
from the earlier issue).
|
||||||
|
|
||||||
|
- We were concerned about the resistance of the algorithm used to derive wallet
|
||||||
|
encryption keys (inherited from Bitcoin) to dictionary attacks by a powerful
|
||||||
|
attacker. If and when we re-enable wallet encryption, it is likely to be with
|
||||||
|
a modern passphrase-based key derivation algorithm designed for greater
|
||||||
|
resistance to dictionary attack, such as Argon2i.
|
||||||
|
|
||||||
|
You should use full-disk encryption (or encryption of your home directory) to
|
||||||
|
protect your wallet at rest, and should assume (even unprivileged) users who are
|
||||||
|
runnng on your OS can read your wallet.dat file.
|
||||||
|
|
||||||
Side-Channel Attacks
|
Side-Channel Attacks
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ def main():
|
||||||
os.makedirs(options.tmpdir)
|
os.makedirs(options.tmpdir)
|
||||||
initialize_chain(options.tmpdir)
|
initialize_chain(options.tmpdir)
|
||||||
|
|
||||||
nodes = start_nodes(1, options.tmpdir)
|
nodes = start_nodes(1, options.tmpdir, extra_args=[['-developerencryptwallet']])
|
||||||
|
|
||||||
run_test(nodes, options.tmpdir)
|
run_test(nodes, options.tmpdir)
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,10 @@ from time import *
|
||||||
|
|
||||||
class WalletNullifiersTest (BitcoinTestFramework):
|
class WalletNullifiersTest (BitcoinTestFramework):
|
||||||
|
|
||||||
|
def setup_nodes(self):
|
||||||
|
return start_nodes(4, self.options.tmpdir,
|
||||||
|
extra_args=[['-developerencryptwallet']] * 4)
|
||||||
|
|
||||||
def run_test (self):
|
def run_test (self):
|
||||||
# add zaddr to node 0
|
# add zaddr to node 0
|
||||||
myzaddr0 = self.nodes[0].z_getnewaddress()
|
myzaddr0 = self.nodes[0].z_getnewaddress()
|
||||||
|
|
|
@ -1090,6 +1090,9 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_encrypted_wallet_zkeys)
|
||||||
Array arr = retValue.get_array();
|
Array arr = retValue.get_array();
|
||||||
BOOST_CHECK(arr.size() == n);
|
BOOST_CHECK(arr.size() == n);
|
||||||
|
|
||||||
|
// Verify that the wallet encryption RPC is disabled
|
||||||
|
BOOST_CHECK_THROW(CallRPC("encryptwallet passphrase"), runtime_error);
|
||||||
|
|
||||||
// Encrypt the wallet (we can't call RPC encryptwallet as that shuts down node)
|
// Encrypt the wallet (we can't call RPC encryptwallet as that shuts down node)
|
||||||
SecureString strWalletPass;
|
SecureString strWalletPass;
|
||||||
strWalletPass.reserve(100);
|
strWalletPass.reserve(100);
|
||||||
|
|
|
@ -1979,10 +1979,18 @@ Value encryptwallet(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
if (!EnsureWalletIsAvailable(fHelp))
|
if (!EnsureWalletIsAvailable(fHelp))
|
||||||
return Value::null;
|
return Value::null;
|
||||||
|
|
||||||
|
auto fEnableWalletEncryption = GetBoolArg("-developerencryptwallet", false);
|
||||||
|
|
||||||
|
std::string strWalletEncryptionDisabledMsg = "";
|
||||||
|
if (!fEnableWalletEncryption) {
|
||||||
|
strWalletEncryptionDisabledMsg = "\nWARNING: Wallet encryption is DISABLED. This call always fails.\n";
|
||||||
|
}
|
||||||
|
|
||||||
if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1))
|
if (!pwalletMain->IsCrypted() && (fHelp || params.size() != 1))
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
"encryptwallet \"passphrase\"\n"
|
"encryptwallet \"passphrase\"\n"
|
||||||
|
+ strWalletEncryptionDisabledMsg +
|
||||||
"\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n"
|
"\nEncrypts the wallet with 'passphrase'. This is for first time encryption.\n"
|
||||||
"After this, any calls that interact with private keys such as sending or signing \n"
|
"After this, any calls that interact with private keys such as sending or signing \n"
|
||||||
"will require the passphrase to be set prior the making these calls.\n"
|
"will require the passphrase to be set prior the making these calls.\n"
|
||||||
|
@ -2008,6 +2016,9 @@ Value encryptwallet(const Array& params, bool fHelp)
|
||||||
|
|
||||||
if (fHelp)
|
if (fHelp)
|
||||||
return true;
|
return true;
|
||||||
|
if (!fEnableWalletEncryption) {
|
||||||
|
throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: wallet encryption is disabled.");
|
||||||
|
}
|
||||||
if (pwalletMain->IsCrypted())
|
if (pwalletMain->IsCrypted())
|
||||||
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called.");
|
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called.");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue