Merge #1212: DesKeyChecker.check() => check the change multipath is not hardened
8d495579e1f0b2bd329d3d299e707491c02a31bd lianad: DesKeyChecker.check() => check the change multipath is not hardened (pythcoiner) Pull request description: This PR add a check to verify that the change descriptor is not hardened. without this check it allow import of invalid (not derivable change) multipath like <0;1'> into a LianaDescriptor. closes #1183 ACKs for top commit: jp1ac4: ACK 8d495579e1f0b2bd329d3d299e707491c02a31bd. darosior: ACK 8d495579e1f0b2bd329d3d299e707491c02a31bd Tree-SHA512: f003fa7b819fa03f84126794b30371419208f1ab4f9e36df2f640dd1c1d20564db7bf1abb9897942e5c43f12e7547f01f07dabf2e8ad1df2e1a3218616883444
This commit is contained in:
commit
1f8d17e414
@ -116,11 +116,10 @@ impl DescKeyChecker {
|
||||
// without origin entirely.
|
||||
if let Some(ref origin) = xpub.origin {
|
||||
let der_paths = xpub.derivation_paths.paths();
|
||||
let first_der_path = der_paths.first().expect("Cannot be empty");
|
||||
// We also rule out xpubs with hardened derivation steps (non-normalized xpubs).
|
||||
let valid = xpub.wildcard == descriptor::Wildcard::Unhardened
|
||||
&& der_paths.len() == 2
|
||||
&& first_der_path.into_iter().all(|step| step.is_normal());
|
||||
&& der_paths.iter().flatten().all(|step| step.is_normal());
|
||||
if valid {
|
||||
return Ok(origin.0);
|
||||
}
|
||||
@ -776,3 +775,70 @@ impl PartialSpendInfo {
|
||||
&self.recovery_paths
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
fn valid_key() {
|
||||
let xpub_str =
|
||||
"[8c3ffb6e/48'/1'/0'/2']tpubDEMt3bpQMa99W81K9h8f2FJH1C81eSd6bbSkBP8tcqQHAfSKvuGp2fz6xiVpfShzT9sKPx7DVBphChjxvNd15WcbsCca5oVz1AcUTWHxkdS/<0;1>/*";
|
||||
let key = descriptor::DescriptorPublicKey::from_str(xpub_str).unwrap();
|
||||
let mut checker = DescKeyChecker::new();
|
||||
assert!(checker.check(&key).is_ok());
|
||||
}
|
||||
#[test]
|
||||
fn invalid_key() {
|
||||
// Multipath of size 3
|
||||
let xpub_str =
|
||||
"[8c3ffb6e/48'/1'/0'/2']tpubDEMt3bpQMa99W81K9h8f2FJH1C81eSd6bbSkBP8tcqQHAfSKvuGp2fz6xiVpfShzT9sKPx7DVBphChjxvNd15WcbsCca5oVz1AcUTWHxkdS/<0;1;2>/*";
|
||||
let key = descriptor::DescriptorPublicKey::from_str(xpub_str).unwrap();
|
||||
let mut checker = DescKeyChecker::new();
|
||||
assert!(matches!(
|
||||
checker.check(&key),
|
||||
Err(LianaPolicyError::InvalidKey(k)) if k == key.into()
|
||||
));
|
||||
|
||||
// No multipath
|
||||
let xpub_str =
|
||||
"[8c3ffb6e/48'/1'/0'/2']tpubDEMt3bpQMa99W81K9h8f2FJH1C81eSd6bbSkBP8tcqQHAfSKvuGp2fz6xiVpfShzT9sKPx7DVBphChjxvNd15WcbsCca5oVz1AcUTWHxkdS/0/*";
|
||||
let key = descriptor::DescriptorPublicKey::from_str(xpub_str).unwrap();
|
||||
let mut checker = DescKeyChecker::new();
|
||||
assert!(matches!(
|
||||
checker.check(&key),
|
||||
Err(LianaPolicyError::InvalidKey(k)) if k == key.into()
|
||||
));
|
||||
|
||||
// Hardened receive path
|
||||
let xpub_str =
|
||||
"[8c3ffb6e/48'/1'/0'/2']tpubDEMt3bpQMa99W81K9h8f2FJH1C81eSd6bbSkBP8tcqQHAfSKvuGp2fz6xiVpfShzT9sKPx7DVBphChjxvNd15WcbsCca5oVz1AcUTWHxkdS/<0';1>/*";
|
||||
let key = descriptor::DescriptorPublicKey::from_str(xpub_str).unwrap();
|
||||
let mut checker = DescKeyChecker::new();
|
||||
assert!(matches!(
|
||||
checker.check(&key),
|
||||
Err(LianaPolicyError::InvalidKey(k)) if k == key.into()
|
||||
));
|
||||
|
||||
// Hardened change path
|
||||
let xpub_str =
|
||||
"[8c3ffb6e/48'/1'/0'/2']tpubDEMt3bpQMa99W81K9h8f2FJH1C81eSd6bbSkBP8tcqQHAfSKvuGp2fz6xiVpfShzT9sKPx7DVBphChjxvNd15WcbsCca5oVz1AcUTWHxkdS/<0;1'>/*";
|
||||
let key = descriptor::DescriptorPublicKey::from_str(xpub_str).unwrap();
|
||||
let mut checker = DescKeyChecker::new();
|
||||
assert!(matches!(
|
||||
checker.check(&key),
|
||||
Err(LianaPolicyError::InvalidKey(k)) if k == key.into()
|
||||
));
|
||||
|
||||
// Hardened wildcard
|
||||
let xpub_str =
|
||||
"[8c3ffb6e/48'/1'/0'/2']tpubDEMt3bpQMa99W81K9h8f2FJH1C81eSd6bbSkBP8tcqQHAfSKvuGp2fz6xiVpfShzT9sKPx7DVBphChjxvNd15WcbsCca5oVz1AcUTWHxkdS/<0;1>/*'";
|
||||
let key = descriptor::DescriptorPublicKey::from_str(xpub_str).unwrap();
|
||||
let mut checker = DescKeyChecker::new();
|
||||
assert!(matches!(
|
||||
checker.check(&key),
|
||||
Err(LianaPolicyError::InvalidKey(k)) if k == key.into()
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user