Skip to content

Commit

Permalink
Do not import private keys to wallets with private keys disabled
Browse files Browse the repository at this point in the history
  • Loading branch information
achow101 committed Jan 24, 2019
1 parent 2541dae commit bc3d735
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/wallet/rpcdump.cpp
Expand Up @@ -133,6 +133,9 @@ UniValue importprivkey(const JSONRPCRequest& request)
+ HelpExampleRpc("importprivkey", "\"mykey\", \"testing\", false")
);

if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Cannot import private keys to a wallet with private keys disabled");
}

WalletRescanReserver reserver(pwallet);
bool fRescan = true;
Expand Down Expand Up @@ -549,6 +552,11 @@ UniValue importwallet(const JSONRPCRequest& request)
+ HelpExampleRpc("importwallet", "\"test\"")
);

// TODO: We should let people import wallet dumps that don't have privkeys.
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Importing wallets is disabled when private keys are disabled");
}

if (fPruneMode)
throw JSONRPCError(RPC_WALLET_ERROR, "Importing wallets is disabled in pruned mode");

Expand Down Expand Up @@ -946,6 +954,11 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
const bool watchOnly = data.exists("watchonly") ? data["watchonly"].get_bool() : false;
const std::string& label = data.exists("label") ? data["label"].get_str() : "";

// If private keys are disabled, abort if private keys are being imported
if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !keys.isNull()) {
throw JSONRPCError(RPC_WALLET_ERROR, "Cannot import private keys to a wallet with private keys disabled");
}

// Generate the script and destination for the scriptPubKey provided
CScript script;
CTxDestination dest;
Expand Down
4 changes: 4 additions & 0 deletions src/wallet/rpcwallet.cpp
Expand Up @@ -3830,6 +3830,10 @@ UniValue sethdseed(const JSONRPCRequest& request)
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Cannot set a new HD seed while still in Initial Block Download");
}

if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
throw JSONRPCError(RPC_WALLET_ERROR, "Cannot set a HD seed to a wallet with private keys disabled");
}

auto locked_chain = pwallet->chain().lock();
LOCK(pwallet->cs_wallet);

Expand Down
3 changes: 3 additions & 0 deletions src/wallet/wallet.cpp
Expand Up @@ -251,6 +251,9 @@ bool CWallet::AddKeyPubKeyWithDB(WalletBatch &batch, const CKey& secret, const C
{
AssertLockHeld(cs_wallet); // mapKeyMetadata

// Make sure we aren't adding private keys to private key disabled wallets
assert(!IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));

// CCryptoKeyStore has no concept of wallet databases, but calls AddCryptedKey
// which is overridden below. To avoid flushes, the database handle is
// tunneled through to it.
Expand Down
11 changes: 11 additions & 0 deletions test/functional/wallet_disableprivatekeys.py
Expand Up @@ -7,6 +7,7 @@

from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
assert_raises_rpc_error,
)

Expand All @@ -31,5 +32,15 @@ def run_test(self):
assert_raises_rpc_error(-4,"Error: Private keys are disabled for this wallet", w1.getrawchangeaddress)
w1.importpubkey(w2.getaddressinfo(w2.getnewaddress())['pubkey'])

self.log.info('Test that private keys cannot be imported')
addr = w2.getnewaddress('', 'legacy')
privkey = w2.dumpprivkey(addr)
assert_raises_rpc_error(-4, 'Cannot import private keys to a wallet with private keys disabled', w1.importprivkey, privkey)
result = w1.importmulti([{'scriptPubKey': {'address': addr}, 'timestamp': 'now', 'keys': [privkey]}])
assert(not result[0]['success'])
assert('warning' not in result[0])
assert_equal(result[0]['error']['code'], -4)
assert_equal(result[0]['error']['message'], 'Cannot import private keys to a wallet with private keys disabled')

if __name__ == '__main__':
DisablePrivateKeysTest().main()

0 comments on commit bc3d735

Please sign in to comment.