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 31, 2019
1 parent b5c5021 commit e6c58d3
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
Original file line number Diff line number Diff line change
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 @@ -617,6 +620,11 @@ UniValue importwallet(const JSONRPCRequest& request)
}
}
file.close();
// We now know whether we are importing private keys, so we can error if private keys are disabled
if (keys.size() > 0 && pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
uiInterface.ShowProgress("", 100, false); // hide progress dialog in GUI
throw JSONRPCError(RPC_WALLET_ERROR, "Importing wallets is disabled when private keys are disabled");
}
double total = (double)(keys.size() + scripts.size());
double progress = 0;
for (const auto& key_tuple : keys) {
Expand Down Expand Up @@ -967,6 +975,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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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 e6c58d3

Please sign in to comment.