Skip to content

Commit a6044de

Browse files
refactor: add MalformedKeyDataKind enum to DescriptorKeyParseError definition
1 parent 790b08f commit a6044de

File tree

1 file changed

+74
-19
lines changed

1 file changed

+74
-19
lines changed

src/descriptor/key.rs

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ impl DescriptorMultiXKey<bip32::Xpriv> {
278278
Ok(*child_num)
279279
} else {
280280
Err(DescriptorKeyParseError::MalformedKeyData(
281-
"Can't make a multi-xpriv with hardened derivation steps that are not shared among all paths into a public key"
281+
MalformedKeyDataKind::InvalidMultiXKeyDerivation,
282282
))
283283
}
284284
})
@@ -327,6 +327,53 @@ impl DescriptorMultiXKey<bip32::Xpriv> {
327327
}
328328
}
329329

330+
/// Kinds of malformed key data
331+
#[derive(Debug, PartialEq, Clone)]
332+
#[non_exhaustive]
333+
pub enum MalformedKeyDataKind {
334+
InvalidMultiXKeyDerivation,
335+
KeyTooShort,
336+
InvalidFullPublicKeyPrefix,
337+
InvalidPublicKeyLength,
338+
EncounteredUnprintableCharacter,
339+
EmptyKey,
340+
UnclosedSquareBracket,
341+
NoMasterFingerprintFound,
342+
InvalidMasterFingerprintLength,
343+
NoKeyAfterOrigin,
344+
MultipleClosingSquareBracketsInPublicKey,
345+
InvalidWildcardInDerivationPath,
346+
MultipleDerivationPathIndexSteps,
347+
InvalidMultiIndexStep,
348+
WildcardAsDerivedDescriptorKey,
349+
}
350+
351+
impl fmt::Display for MalformedKeyDataKind {
352+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
353+
use MalformedKeyDataKind::*;
354+
355+
let err = match self {
356+
InvalidMultiXKeyDerivation => "Can't make a multi-xpriv with hardened derivation steps that are not shared among all paths into a public key",
357+
KeyTooShort => "Key too short",
358+
InvalidFullPublicKeyPrefix => "Only full public keys with prefixes '02', '03' or '04' are allowed",
359+
InvalidPublicKeyLength => "Public keys must be 64, 66 or 130 characters in size",
360+
EncounteredUnprintableCharacter => "Encountered an unprintable character",
361+
EmptyKey => "Empty key",
362+
UnclosedSquareBracket => "Unclosed '['",
363+
NoMasterFingerprintFound => "No master fingerprint found after '['",
364+
InvalidMasterFingerprintLength => "Master fingerprint should be 8 characters long",
365+
NoKeyAfterOrigin => "No key after origin",
366+
MultipleClosingSquareBracketsInPublicKey => "Multiple ']' in Descriptor Public Key",
367+
InvalidWildcardInDerivationPath => "'*' may only appear as last element in a derivation path",
368+
MultipleDerivationPathIndexSteps => "'<' may only appear once in a derivation path",
369+
InvalidMultiIndexStep => "Invalid multi index step in multipath descriptor",
370+
WildcardAsDerivedDescriptorKey => "cannot parse key with a wilcard as a DerivedDescriptorKey",
371+
};
372+
373+
f.write_str(err)
374+
}
375+
}
376+
330377
/// Descriptor Key parsing errors
331378
#[derive(Debug, PartialEq, Clone)]
332379
#[non_exhaustive]
@@ -344,8 +391,8 @@ pub enum DescriptorKeyParseError {
344391
},
345392
/// Error deriving the hardened private key.
346393
DeriveHardenedKey(bip32::Error),
347-
/// Error indicating the key data was malformed with details provided
348-
MalformedKeyData(&'static str),
394+
/// Error indicating the key data was malformed
395+
MalformedKeyData(MalformedKeyDataKind),
349396
/// Error while parsing the master derivation path.
350397
MasterDerivationPath(bip32::Error),
351398
/// Error indicating a malformed master fingerprint (invalid hex).
@@ -567,7 +614,9 @@ impl FromStr for DescriptorPublicKey {
567614
fn from_str(s: &str) -> Result<Self, Self::Err> {
568615
// A "raw" public key without any origin is the least we accept.
569616
if s.len() < 64 {
570-
return Err(DescriptorKeyParseError::MalformedKeyData("Key too short"));
617+
return Err(DescriptorKeyParseError::MalformedKeyData(
618+
MalformedKeyDataKind::KeyTooShort,
619+
));
571620
}
572621

573622
let (key_part, origin) = parse_key_origin(s)?;
@@ -602,7 +651,7 @@ impl FromStr for DescriptorPublicKey {
602651
|| &key_part[0..2] == "04")
603652
{
604653
return Err(DescriptorKeyParseError::MalformedKeyData(
605-
"Only publickeys with prefixes '02', '03' or '04' are allowed",
654+
MalformedKeyDataKind::InvalidFullPublicKeyPrefix,
606655
));
607656
}
608657
let key = bitcoin::PublicKey::from_str(key_part)
@@ -611,7 +660,7 @@ impl FromStr for DescriptorPublicKey {
611660
}
612661
_ => {
613662
return Err(DescriptorKeyParseError::MalformedKeyData(
614-
"Public keys must be 64, 66 or 130 characters in size",
663+
MalformedKeyDataKind::InvalidPublicKeyLength,
615664
))
616665
}
617666
};
@@ -878,31 +927,33 @@ fn parse_key_origin(s: &str) -> Result<(&str, Option<bip32::KeySource>), Descrip
878927
for ch in s.as_bytes() {
879928
if *ch < 20 || *ch > 127 {
880929
return Err(DescriptorKeyParseError::MalformedKeyData(
881-
"Encountered an unprintable character",
930+
MalformedKeyDataKind::EncounteredUnprintableCharacter,
882931
));
883932
}
884933
}
885934

886935
if s.is_empty() {
887-
return Err(DescriptorKeyParseError::MalformedKeyData("Empty key"));
936+
return Err(DescriptorKeyParseError::MalformedKeyData(MalformedKeyDataKind::EmptyKey));
888937
}
889938
let mut parts = s[1..].split(']');
890939

891940
if let Some('[') = s.chars().next() {
892941
let mut raw_origin = parts
893942
.next()
894-
.ok_or(DescriptorKeyParseError::MalformedKeyData("Unclosed '['"))?
943+
.ok_or(DescriptorKeyParseError::MalformedKeyData(
944+
MalformedKeyDataKind::UnclosedSquareBracket,
945+
))?
895946
.split('/');
896947

897948
let origin_id_hex = raw_origin
898949
.next()
899950
.ok_or(DescriptorKeyParseError::MalformedKeyData(
900-
"No master fingerprint found after '['",
951+
MalformedKeyDataKind::NoMasterFingerprintFound,
901952
))?;
902953

903954
if origin_id_hex.len() != 8 {
904955
return Err(DescriptorKeyParseError::MalformedKeyData(
905-
"Master fingerprint should be 8 characters long",
956+
MalformedKeyDataKind::InvalidMasterFingerprintLength,
906957
));
907958
}
908959
let parent_fingerprint = bip32::Fingerprint::from_hex(origin_id_hex).map_err(|err| {
@@ -918,11 +969,13 @@ fn parse_key_origin(s: &str) -> Result<(&str, Option<bip32::KeySource>), Descrip
918969

919970
let key = parts
920971
.next()
921-
.ok_or(DescriptorKeyParseError::MalformedKeyData("No key after origin"))?;
972+
.ok_or(DescriptorKeyParseError::MalformedKeyData(
973+
MalformedKeyDataKind::NoKeyAfterOrigin,
974+
))?;
922975

923976
if parts.next().is_some() {
924977
Err(DescriptorKeyParseError::MalformedKeyData(
925-
"Multiple ']' in Descriptor Public Key",
978+
MalformedKeyDataKind::MultipleClosingSquareBracketsInPublicKey,
926979
))
927980
} else {
928981
Ok((key, Some((parent_fingerprint, origin_path))))
@@ -947,7 +1000,9 @@ fn parse_xkey_deriv<Key>(
9471000
let mut key_deriv = key_deriv.split('/');
9481001
let xkey_str = key_deriv
9491002
.next()
950-
.ok_or(DescriptorKeyParseError::MalformedKeyData("No key after origin"))?;
1003+
.ok_or(DescriptorKeyParseError::MalformedKeyData(
1004+
MalformedKeyDataKind::NoKeyAfterOrigin,
1005+
))?;
9511006

9521007
let xkey = parse_xkey_fn(xkey_str)?;
9531008

@@ -963,7 +1018,7 @@ fn parse_xkey_deriv<Key>(
9631018
None
9641019
} else if wildcard != Wildcard::None {
9651020
Some(Err(DescriptorKeyParseError::MalformedKeyData(
966-
"'*' may only appear as last element in a derivation path",
1021+
MalformedKeyDataKind::InvalidWildcardInDerivationPath,
9671022
)))
9681023
} else {
9691024
// BIP389 defines a new step in the derivation path. This step contains two or more
@@ -972,7 +1027,7 @@ fn parse_xkey_deriv<Key>(
9721027
// There may only be one occurence of this step.
9731028
if multipath {
9741029
return Some(Err(DescriptorKeyParseError::MalformedKeyData(
975-
"'<' may only appear once in a derivation path",
1030+
MalformedKeyDataKind::MultipleDerivationPathIndexSteps,
9761031
)));
9771032
}
9781033
multipath = true;
@@ -981,7 +1036,7 @@ fn parse_xkey_deriv<Key>(
9811036
// So it's at least '<' + a number + ';' + a number + '>'.
9821037
if p.len() < 5 || !p.contains(';') {
9831038
return Some(Err(DescriptorKeyParseError::MalformedKeyData(
984-
"Invalid multi index step in multipath descriptor",
1039+
MalformedKeyDataKind::InvalidMultiIndexStep,
9851040
)));
9861041
}
9871042

@@ -1239,7 +1294,7 @@ impl FromStr for DefiniteDescriptorKey {
12391294
fn from_str(s: &str) -> Result<Self, Self::Err> {
12401295
let inner = DescriptorPublicKey::from_str(s)?;
12411296
DefiniteDescriptorKey::new(inner).ok_or(DescriptorKeyParseError::MalformedKeyData(
1242-
"cannot parse key with a wilcard as a DerivedDescriptorKey",
1297+
MalformedKeyDataKind::WildcardAsDerivedDescriptorKey,
12431298
))
12441299
}
12451300
}
@@ -1366,7 +1421,7 @@ mod test {
13661421
let desc = "0777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777";
13671422
assert_eq!(
13681423
DescriptorPublicKey::from_str(desc).unwrap_err().to_string(),
1369-
"Only publickeys with prefixes '02', '03' or '04' are allowed"
1424+
"Only full public keys with prefixes '02', '03' or '04' are allowed"
13701425
);
13711426
}
13721427

0 commit comments

Comments
 (0)