From 611ab307fbd8b6f8f7ffc1d569bb86d1f9cb4e92 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Jul 2018 23:15:53 -0700 Subject: Introduce KeyOriginInfo for fingerprint + path --- src/wallet/rpcwallet.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/wallet/rpcwallet.cpp') diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 4aed097364..fd3b82d9ab 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4464,7 +4464,7 @@ bool ParseHDKeypath(std::string keypath_str, std::vector& keypath) return true; } -void AddKeypathToMap(const CWallet* pwallet, const CKeyID& keyID, std::map>& hd_keypaths) +void AddKeypathToMap(const CWallet* pwallet, const CKeyID& keyID, std::map& hd_keypaths) { CPubKey vchPubKey; if (!pwallet->GetPubKey(keyID, vchPubKey)) { @@ -4475,9 +4475,9 @@ void AddKeypathToMap(const CWallet* pwallet, const CKeyID& keyID, std::mapmapKeyMetadata.end()) { meta = it->second; } - std::vector keypath; + KeyOriginInfo info; if (!meta.hdKeypath.empty()) { - if (!ParseHDKeypath(meta.hdKeypath, keypath)) { + if (!ParseHDKeypath(meta.hdKeypath, info.path)) { throw JSONRPCError(RPC_INTERNAL_ERROR, "Internal keypath is broken"); } // Get the proper master key id @@ -4485,12 +4485,13 @@ void AddKeypathToMap(const CWallet* pwallet, const CKeyID& keyID, std::mapGetKey(meta.hd_seed_id, key); CExtKey masterKey; masterKey.SetSeed(key.begin(), key.size()); - // Add to map - keypath.insert(keypath.begin(), ReadLE32(masterKey.key.GetPubKey().GetID().begin())); + // Compute identifier + CKeyID masterid = masterKey.key.GetPubKey().GetID(); + std::copy(masterid.begin(), masterid.begin() + 4, info.fingerprint); } else { // Single pubkeys get the master fingerprint of themselves - keypath.insert(keypath.begin(), ReadLE32(vchPubKey.GetID().begin())); + std::copy(keyID.begin(), keyID.begin() + 4, info.fingerprint); } - hd_keypaths.emplace(vchPubKey, keypath); + hd_keypaths.emplace(vchPubKey, std::move(info)); } bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const CTransaction* txConst, int sighash_type, bool sign, bool bip32derivs) -- cgit v1.2.3 From 81e1dd5ce1a32114a38691ec6b55e72ab04dbbb1 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 20 Jul 2018 00:04:02 -0700 Subject: Generalize PublicOnlySigningProvider into HidingSigningProvider --- src/wallet/rpcwallet.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'src/wallet/rpcwallet.cpp') diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index fd3b82d9ab..a719e883c7 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4520,11 +4520,7 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const C } SignatureData sigdata; - if (sign) { - complete &= SignPSBTInput(*pwallet, *psbtx.tx, input, sigdata, i, sighash_type); - } else { - complete &= SignPSBTInput(PublicOnlySigningProvider(pwallet), *psbtx.tx, input, sigdata, i, sighash_type); - } + complete &= SignPSBTInput(HidingSigningProvider(pwallet, !sign, false), *psbtx.tx, input, sigdata, i, sighash_type); if (it != pwallet->mapWallet.end()) { // Drop the unnecessary UTXO if we added both from the wallet. -- cgit v1.2.3 From 3b01efa0d1bf3d23d1b7b7e518849f1fc26314f9 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Jul 2018 17:37:19 -0700 Subject: [MOVEONLY] Move ParseHDKeypath to utilstrencodings --- src/wallet/rpcwallet.cpp | 41 ----------------------------------------- 1 file changed, 41 deletions(-) (limited to 'src/wallet/rpcwallet.cpp') diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index a719e883c7..aa7f5312b4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4423,47 +4423,6 @@ UniValue sethdseed(const JSONRPCRequest& request) return NullUniValue; } -bool ParseHDKeypath(std::string keypath_str, std::vector& keypath) -{ - std::stringstream ss(keypath_str); - std::string item; - bool first = true; - while (std::getline(ss, item, '/')) { - if (item.compare("m") == 0) { - if (first) { - first = false; - continue; - } - return false; - } - // Finds whether it is hardened - uint32_t path = 0; - size_t pos = item.find("'"); - if (pos != std::string::npos) { - // The hardened tick can only be in the last index of the string - if (pos != item.size() - 1) { - return false; - } - path |= 0x80000000; - item = item.substr(0, item.size() - 1); // Drop the last character which is the hardened tick - } - - // Ensure this is only numbers - if (item.find_first_not_of( "0123456789" ) != std::string::npos) { - return false; - } - uint32_t number; - if (!ParseUInt32(item, &number)) { - return false; - } - path |= number; - - keypath.push_back(path); - first = false; - } - return true; -} - void AddKeypathToMap(const CWallet* pwallet, const CKeyID& keyID, std::map& hd_keypaths) { CPubKey vchPubKey; -- cgit v1.2.3 From 03a99586a398ee38f40c3b72d24c6a2ba4b88579 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Jul 2018 17:56:52 -0700 Subject: Implement key origin lookup in CWallet --- src/wallet/rpcwallet.cpp | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) (limited to 'src/wallet/rpcwallet.cpp') diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index aa7f5312b4..0fcdd780a7 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4429,26 +4429,9 @@ void AddKeypathToMap(const CWallet* pwallet, const CKeyID& keyID, std::mapGetPubKey(keyID, vchPubKey)) { return; } - CKeyMetadata meta; - auto it = pwallet->mapKeyMetadata.find(keyID); - if (it != pwallet->mapKeyMetadata.end()) { - meta = it->second; - } KeyOriginInfo info; - if (!meta.hdKeypath.empty()) { - if (!ParseHDKeypath(meta.hdKeypath, info.path)) { - throw JSONRPCError(RPC_INTERNAL_ERROR, "Internal keypath is broken"); - } - // Get the proper master key id - CKey key; - pwallet->GetKey(meta.hd_seed_id, key); - CExtKey masterKey; - masterKey.SetSeed(key.begin(), key.size()); - // Compute identifier - CKeyID masterid = masterKey.key.GetPubKey().GetID(); - std::copy(masterid.begin(), masterid.begin() + 4, info.fingerprint); - } else { // Single pubkeys get the master fingerprint of themselves - std::copy(keyID.begin(), keyID.begin() + 4, info.fingerprint); + if (!pwallet->GetKeyOrigin(keyID, info)) { + throw JSONRPCError(RPC_INTERNAL_ERROR, "Internal keypath is broken"); } hd_keypaths.emplace(vchPubKey, std::move(info)); } -- cgit v1.2.3 From cad5dd2368109ec398a3b79c8b9e94dfd23f0845 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Thu, 19 Jul 2018 18:47:24 -0700 Subject: Pass HD path data through SignatureData --- src/wallet/rpcwallet.cpp | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'src/wallet/rpcwallet.cpp') diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 0fcdd780a7..c2cd4ea2a0 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4462,7 +4462,7 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const C } SignatureData sigdata; - complete &= SignPSBTInput(HidingSigningProvider(pwallet, !sign, false), *psbtx.tx, input, sigdata, i, sighash_type); + complete &= SignPSBTInput(HidingSigningProvider(pwallet, !sign, !bip32derivs), *psbtx.tx, input, sigdata, i, sighash_type); if (it != pwallet->mapWallet.end()) { // Drop the unnecessary UTXO if we added both from the wallet. @@ -4472,13 +4472,6 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const C input.witness_utxo.SetNull(); } } - - // Get public key paths - if (bip32derivs) { - for (const auto& pubkey_it : sigdata.misc_pubkeys) { - AddKeypathToMap(pwallet, pubkey_it.first, input.hd_keypaths); - } - } } // Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change @@ -4496,15 +4489,8 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const C psbt_out.FillSignatureData(sigdata); MutableTransactionSignatureCreator creator(psbtx.tx.get_ptr(), 0, out.nValue, 1); - ProduceSignature(*pwallet, creator, out.scriptPubKey, sigdata); + ProduceSignature(HidingSigningProvider(pwallet, true, !bip32derivs), creator, out.scriptPubKey, sigdata); psbt_out.FromSignatureData(sigdata); - - // Get public key paths - if (bip32derivs) { - for (const auto& pubkey_it : sigdata.misc_pubkeys) { - AddKeypathToMap(pwallet, pubkey_it.first, psbt_out.hd_keypaths); - } - } } return complete; } -- cgit v1.2.3 From 917353c8b0eff4cd95f9a5f7719f6756bb8338b1 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 20 Jul 2018 00:23:32 -0700 Subject: Make SignPSBTInput operate on a private SignatureData object --- src/wallet/rpcwallet.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'src/wallet/rpcwallet.cpp') diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index c2cd4ea2a0..b8e7b7fe0c 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -4461,17 +4461,7 @@ bool FillPSBT(const CWallet* pwallet, PartiallySignedTransaction& psbtx, const C throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Specified Sighash and sighash in PSBT do not match."); } - SignatureData sigdata; - complete &= SignPSBTInput(HidingSigningProvider(pwallet, !sign, !bip32derivs), *psbtx.tx, input, sigdata, i, sighash_type); - - if (it != pwallet->mapWallet.end()) { - // Drop the unnecessary UTXO if we added both from the wallet. - if (sigdata.witness) { - input.non_witness_utxo = nullptr; - } else { - input.witness_utxo.SetNull(); - } - } + complete &= SignPSBTInput(HidingSigningProvider(pwallet, !sign, !bip32derivs), *psbtx.tx, input, i, sighash_type); } // Fill in the bip32 keypaths and redeemscripts for the outputs so that hardware wallets can identify change -- cgit v1.2.3