From d8028723107b09bdb257328d2ee9b666da6d9f67 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Fri, 6 Nov 2020 20:53:03 +0100 Subject: [PATCH] Improvements to extended keys encoding logic end errors --- src/util/bip32.rs | 49 ++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/src/util/bip32.rs b/src/util/bip32.rs index df144ae1..ba536f8c 100644 --- a/src/util/bip32.rs +++ b/src/util/bip32.rs @@ -27,7 +27,7 @@ use secp256k1::{self, Secp256k1}; use network::constants::Network; use util::{base58, endian}; -use util::key::{PublicKey, PrivateKey}; +use util::key::{self, PublicKey, PrivateKey}; /// A chain code #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] @@ -422,6 +422,15 @@ impl error::Error for Error { } } +impl From for Error { + fn from(err: key::Error) -> Self { + match err { + key::Error::Base58(e) => Error::Base58(e), + key::Error::Secp256k1(e) => Error::Ecdsa(e), + } + } +} + impl From for Error { fn from(e: secp256k1::Error) -> Error { Error::Ecdsa(e) } } @@ -432,12 +441,6 @@ impl From for Error { } } -impl From for base58::Error { - fn from(err: Error) -> Self { - base58::Error::Other(err.to_string()) - } -} - impl ExtendedPrivKey { /// Construct a new master key from a seed value pub fn new_master(network: Network, seed: &[u8]) -> Result { @@ -516,31 +519,28 @@ impl ExtendedPrivKey { return Err(Error::WrongExtendedKeyLength(data.len())) } - let cn_int: u32 = endian::slice_to_u32_be(&data[9..13]); - let child_number: ChildNumber = ChildNumber::from(cn_int); - let network = if data[0..4] == [0x04u8, 0x88, 0xAD, 0xE4] { Network::Bitcoin } else if data[0..4] == [0x04u8, 0x35, 0x83, 0x94] { Network::Testnet } else { - return Err(base58::Error::InvalidVersion((&data[0..4]).to_vec()).into()); + let mut ver = [0u8; 4]; + ver.copy_from_slice(&data[0..4]); + return Err(Error::UnknownVersion(ver)); }; Ok(ExtendedPrivKey { network: network, depth: data[4], parent_fingerprint: Fingerprint::from(&data[5..9]), - child_number: child_number, + child_number: endian::slice_to_u32_be(&data[9..13]).into(), chain_code: ChainCode::from(&data[13..45]), private_key: PrivateKey { compressed: true, network: network, key: secp256k1::SecretKey::from_slice( &data[46..78] - ).map_err(|e| - base58::Error::Other(e.to_string()) - )?, + ).map_err(Error::Ecdsa)?, }, }) } @@ -659,15 +659,16 @@ impl ExtendedPubKey { } else if data[0..4] == [0x04u8, 0x35, 0x87, 0xCF] { Network::Testnet } else { - return Err(base58::Error::InvalidVersion((&data[0..4]).to_vec()).into()); + let mut ver = [0u8; 4]; + ver.copy_from_slice(&data[0..4]); + return Err(Error::UnknownVersion(ver)); }, depth: data[4], parent_fingerprint: Fingerprint::from(&data[5..9]), child_number: child_number, chain_code: ChainCode::from(&data[13..45]), public_key: PublicKey::from_slice( - &data[45..78]).map_err(|e| - base58::Error::Other(e.to_string()))?, + &data[45..78])?, }) } @@ -706,13 +707,13 @@ impl fmt::Display for ExtendedPrivKey { } impl FromStr for ExtendedPrivKey { - type Err = base58::Error; + type Err = Error; - fn from_str(inp: &str) -> Result { + fn from_str(inp: &str) -> Result { let data = base58::from_check(inp)?; if data.len() != 78 { - return Err(base58::Error::InvalidLength(data.len())); + return Err(base58::Error::InvalidLength(data.len()).into()); } Ok(ExtendedPrivKey::decode(&data[..])?) @@ -726,13 +727,13 @@ impl fmt::Display for ExtendedPubKey { } impl FromStr for ExtendedPubKey { - type Err = base58::Error; + type Err = Error; - fn from_str(inp: &str) -> Result { + fn from_str(inp: &str) -> Result { let data = base58::from_check(inp)?; if data.len() != 78 { - return Err(base58::Error::InvalidLength(data.len())); + return Err(base58::Error::InvalidLength(data.len()).into()); } Ok(ExtendedPubKey::decode(&data[..])?)