Wrap derivation_path::DerivationPath (#16609)
* Replace custom DerivationPath impl * Add method to parse full-path from str with hardening * Convert Bip44 to trait * Hoist more work on derivation-path * Privatize Bip44 trait
This commit is contained in:
@@ -34,8 +34,6 @@ const MAX_CHUNK_SIZE: usize = 255;
|
||||
|
||||
const APDU_SUCCESS_CODE: usize = 0x9000;
|
||||
|
||||
const SOL_DERIVATION_PATH_BE: [u8; 8] = [0x80, 0, 0, 44, 0x80, 0, 0x01, 0xF5]; // 44'/501', Solana
|
||||
|
||||
/// Ledger vendor ID
|
||||
const LEDGER_VID: u16 = 0x2c97;
|
||||
/// Ledger product IDs: Nano S and Nano X
|
||||
@@ -513,20 +511,16 @@ pub fn is_valid_ledger(vendor_id: u16, product_id: u16) -> bool {
|
||||
|
||||
/// Build the derivation path byte array from a DerivationPath selection
|
||||
fn extend_and_serialize(derivation_path: &DerivationPath) -> Vec<u8> {
|
||||
let byte = if derivation_path.change.is_some() {
|
||||
let byte = if derivation_path.change().is_some() {
|
||||
4
|
||||
} else if derivation_path.account.is_some() {
|
||||
} else if derivation_path.account().is_some() {
|
||||
3
|
||||
} else {
|
||||
2
|
||||
};
|
||||
let mut concat_derivation = vec![byte];
|
||||
concat_derivation.extend_from_slice(&SOL_DERIVATION_PATH_BE);
|
||||
if let Some(account) = &derivation_path.account {
|
||||
concat_derivation.extend_from_slice(&account.as_u32().to_be_bytes());
|
||||
if let Some(change) = &derivation_path.change {
|
||||
concat_derivation.extend_from_slice(&change.as_u32().to_be_bytes());
|
||||
}
|
||||
for index in derivation_path.path() {
|
||||
concat_derivation.extend_from_slice(&index.to_bits().to_be_bytes());
|
||||
}
|
||||
concat_derivation
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ use {
|
||||
log::*,
|
||||
parking_lot::{Mutex, RwLock},
|
||||
solana_sdk::{
|
||||
derivation_path::{DerivationPath, DerivationPathComponent, DerivationPathError},
|
||||
derivation_path::{DerivationPath, DerivationPathError},
|
||||
pubkey::Pubkey,
|
||||
signature::{Signature, SignerError},
|
||||
},
|
||||
@@ -288,26 +288,10 @@ impl RemoteWalletInfo {
|
||||
if let Some(mut pair) = query_pairs.next() {
|
||||
if pair.0 == "key" {
|
||||
let key_path = pair.1.to_mut();
|
||||
let _key_path = key_path.clone();
|
||||
if key_path.ends_with('/') {
|
||||
key_path.pop();
|
||||
}
|
||||
let mut parts = key_path.split('/');
|
||||
if let Some(account) = parts.next() {
|
||||
derivation_path.account =
|
||||
Some(DerivationPathComponent::from_str(account)?);
|
||||
}
|
||||
if let Some(change) = parts.next() {
|
||||
derivation_path.change =
|
||||
Some(DerivationPathComponent::from_str(change)?);
|
||||
}
|
||||
if parts.next().is_some() {
|
||||
return Err(DerivationPathError::InvalidDerivationPath(format!(
|
||||
"key path `{}` too deep, only <account>/<change> supported",
|
||||
_key_path
|
||||
))
|
||||
.into());
|
||||
}
|
||||
derivation_path = DerivationPath::from_key_str(key_path)?;
|
||||
} else {
|
||||
return Err(DerivationPathError::InvalidDerivationPath(format!(
|
||||
"invalid query string `{}={}`, only `key` supported",
|
||||
@@ -378,13 +362,7 @@ mod tests {
|
||||
pubkey,
|
||||
error: None,
|
||||
}));
|
||||
assert_eq!(
|
||||
derivation_path,
|
||||
DerivationPath {
|
||||
account: Some(1.into()),
|
||||
change: Some(2.into()),
|
||||
}
|
||||
);
|
||||
assert_eq!(derivation_path, DerivationPath::new_bip44(Some(1), Some(2)));
|
||||
let (wallet_info, derivation_path) =
|
||||
RemoteWalletInfo::parse_path(format!("usb://ledger/{:?}?key=1'/2'", pubkey)).unwrap();
|
||||
assert!(wallet_info.matches(&RemoteWalletInfo {
|
||||
@@ -395,13 +373,7 @@ mod tests {
|
||||
pubkey,
|
||||
error: None,
|
||||
}));
|
||||
assert_eq!(
|
||||
derivation_path,
|
||||
DerivationPath {
|
||||
account: Some(1.into()),
|
||||
change: Some(2.into()),
|
||||
}
|
||||
);
|
||||
assert_eq!(derivation_path, DerivationPath::new_bip44(Some(1), Some(2)));
|
||||
let (wallet_info, derivation_path) =
|
||||
RemoteWalletInfo::parse_path(format!("usb://ledger/{:?}?key=1\'/2\'", pubkey)).unwrap();
|
||||
assert!(wallet_info.matches(&RemoteWalletInfo {
|
||||
@@ -412,13 +384,7 @@ mod tests {
|
||||
pubkey,
|
||||
error: None,
|
||||
}));
|
||||
assert_eq!(
|
||||
derivation_path,
|
||||
DerivationPath {
|
||||
account: Some(1.into()),
|
||||
change: Some(2.into()),
|
||||
}
|
||||
);
|
||||
assert_eq!(derivation_path, DerivationPath::new_bip44(Some(1), Some(2)));
|
||||
let (wallet_info, derivation_path) =
|
||||
RemoteWalletInfo::parse_path(format!("usb://ledger/{:?}?key=1/2/", pubkey)).unwrap();
|
||||
assert!(wallet_info.matches(&RemoteWalletInfo {
|
||||
@@ -429,13 +395,7 @@ mod tests {
|
||||
pubkey,
|
||||
error: None,
|
||||
}));
|
||||
assert_eq!(
|
||||
derivation_path,
|
||||
DerivationPath {
|
||||
account: Some(1.into()),
|
||||
change: Some(2.into()),
|
||||
}
|
||||
);
|
||||
assert_eq!(derivation_path, DerivationPath::new_bip44(Some(1), Some(2)));
|
||||
let (wallet_info, derivation_path) =
|
||||
RemoteWalletInfo::parse_path(format!("usb://ledger/{:?}?key=1/", pubkey)).unwrap();
|
||||
assert!(wallet_info.matches(&RemoteWalletInfo {
|
||||
@@ -446,13 +406,7 @@ mod tests {
|
||||
pubkey,
|
||||
error: None,
|
||||
}));
|
||||
assert_eq!(
|
||||
derivation_path,
|
||||
DerivationPath {
|
||||
account: Some(1.into()),
|
||||
change: None,
|
||||
}
|
||||
);
|
||||
assert_eq!(derivation_path, DerivationPath::new_bip44(Some(1), None));
|
||||
|
||||
// Test that wallet id need not be complete for key derivation to work
|
||||
let (wallet_info, derivation_path) =
|
||||
@@ -465,13 +419,7 @@ mod tests {
|
||||
pubkey: Pubkey::default(),
|
||||
error: None,
|
||||
}));
|
||||
assert_eq!(
|
||||
derivation_path,
|
||||
DerivationPath {
|
||||
account: Some(1.into()),
|
||||
change: None,
|
||||
}
|
||||
);
|
||||
assert_eq!(derivation_path, DerivationPath::new_bip44(Some(1), None));
|
||||
let (wallet_info, derivation_path) =
|
||||
RemoteWalletInfo::parse_path("usb://ledger/?key=1/2".to_string()).unwrap();
|
||||
assert!(wallet_info.matches(&RemoteWalletInfo {
|
||||
@@ -482,13 +430,7 @@ mod tests {
|
||||
pubkey: Pubkey::default(),
|
||||
error: None,
|
||||
}));
|
||||
assert_eq!(
|
||||
derivation_path,
|
||||
DerivationPath {
|
||||
account: Some(1.into()),
|
||||
change: Some(2.into()),
|
||||
}
|
||||
);
|
||||
assert_eq!(derivation_path, DerivationPath::new_bip44(Some(1), Some(2)));
|
||||
|
||||
// Failure cases
|
||||
assert!(
|
||||
|
Reference in New Issue
Block a user