diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index d2fc837..b3d2f93 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -24,12 +24,11 @@ jobs: - name: show versions run: | rustup show - + - name: Install rustfmt + run: rustup component add rustfmt --toolchain nightly - name: rustfmt run: | - cargo fmt --version - cargo fmt -- --check - + cargo +nightly fmt -- --check - name: rust cache uses: Swatinem/rust-cache@v1 with: diff --git a/Cargo.toml b/Cargo.toml index 5ff0816..b9d3f46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,20 +4,11 @@ members = [ "ledger-apdu", "ledger-transport", "ledger-transport-hid", - "ledger-transport-zemu", "ledger-zondax-generic", ] exclude = [] [profile.release] -# Tell `rustc` to optimize for small code size. opt-level = "s" overflow-checks = true - -[patch.crates-io] -ledger-apdu = { path = "ledger-apdu" } -ledger-transport = { path = "ledger-transport" } -ledger-transport-hid = { path = "ledger-transport-hid" } -ledger-transport-zemu = { path = "ledger-transport-zemu" } -ledger-zondax-generic = { path = "ledger-zondax-generic" } diff --git a/ledger-apdu/Cargo.toml b/ledger-apdu/Cargo.toml index ddb31db..13fa88d 100644 --- a/ledger-apdu/Cargo.toml +++ b/ledger-apdu/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ledger-apdu" description = "Ledger Hardware Wallet - Common APDU Protocol Types" -version = "0.10.0" +version = "0.11.0" license = "Apache-2.0" authors = ["Zondax AG "] homepage = "https://github.com/zondax/ledger-rs" @@ -16,6 +16,6 @@ std = ["snafu/std", "no-std-compat/std"] default = ["std"] [dependencies] -arrayref = "0.3.6" -no-std-compat = "0.4.1" -snafu = { version = "0.7", features = ["rust_1_46"], default-features = false } +arrayref = "0.3" +no-std-compat = "0.4" +snafu = { version = "0.8", default-features = false } diff --git a/ledger-apdu/src/lib.rs b/ledger-apdu/src/lib.rs index 32a3a39..47087ad 100644 --- a/ledger-apdu/src/lib.rs +++ b/ledger-apdu/src/lib.rs @@ -74,7 +74,7 @@ pub enum APDUAnswerError { impl APDUAnswer where - B: std::ops::Deref, + B: Deref, { /// Attempt to interpret the given slice as an APDU answer pub fn from_answer(answer: B) -> Result { @@ -82,16 +82,13 @@ where let retcode = arrayref::array_ref!(answer, answer.len() - 2, 2); let retcode = u16::from_be_bytes(*retcode); - Ok(APDUAnswer { - data: answer, - retcode, - }) + Ok(APDUAnswer { data: answer, retcode }) } /// Will return the answer's payload #[inline(always)] pub fn apdu_data(&self) -> &[u8] { - &self.data[..self.data.len() - 2] + &self.data[.. self.data.len() - 2] } /// Will return the answer's payload @@ -103,7 +100,9 @@ where /// Will attempt to interpret the error code as an [APDUErrorCode], /// returning the code as is otherwise pub fn error_code(&self) -> Result { - self.retcode.try_into().map_err(|_| self.retcode) + self.retcode + .try_into() + .map_err(|_| self.retcode) } /// Returns the raw return code @@ -149,7 +148,7 @@ pub enum APDUErrorCode { #[cfg(feature = "std")] impl APDUErrorCode { - /// Quickhand to retrieve the error code's description / display + /// Quick-hand to retrieve the error code's description / display pub fn description(&self) -> std::string::String { std::format!("{}", self) } diff --git a/ledger-apdu/src/tests.rs b/ledger-apdu/src/tests.rs index b70b8ed..38b592f 100644 --- a/ledger-apdu/src/tests.rs +++ b/ledger-apdu/src/tests.rs @@ -23,55 +23,49 @@ const APDU_RESPONSE: &[u8] = &[0xDE, 0xAD, 0xBE, 0xEF, 0x90, 0x00]; fn apdu_command_vec() { let data = std::vec![SERIALIZED_APDU[5]; 3]; - let command = APDUCommand { - cla: 0xFF, - ins: 0x00, - p1: 0, - p2: 0, - data, - }; + let command = APDUCommand { cla: 0xFF, ins: 0x00, p1: 0, p2: 0, data }; assert_eq!(SERIALIZED_APDU, &command.serialize()[..]) } #[test] fn apdu_command_slice() { - let data = &SERIALIZED_APDU[5..]; - - let _ = APDUCommand { - cla: 0xFF, - ins: 0x00, - p1: 0, - p2: 0, - data, - }; + let data = &SERIALIZED_APDU[5 ..]; + + let _ = APDUCommand { cla: 0xFF, ins: 0x00, p1: 0, p2: 0, data }; } #[test] fn apdu_answer_success() { let answer = APDUAnswer::from_answer(APDU_RESPONSE).expect("valid answer length >= 2"); - let code = answer.error_code().expect("valid error code"); + let code = answer + .error_code() + .expect("valid error code"); assert_eq!(code, APDUErrorCode::NoError); - assert_eq!(answer.apdu_data(), &APDU_RESPONSE[..4]); + assert_eq!(answer.apdu_data(), &APDU_RESPONSE[.. 4]); } #[test] fn apdu_answer_vec() { let answer = APDUAnswer::from_answer(APDU_RESPONSE.to_vec()).expect("valid answer length >= 2"); - let code = answer.error_code().expect("valid error code"); + let code = answer + .error_code() + .expect("valid error code"); assert_eq!(code, APDUErrorCode::NoError); - assert_eq!(answer.apdu_data(), &APDU_RESPONSE[..4]); + assert_eq!(answer.apdu_data(), &APDU_RESPONSE[.. 4]); } #[test] fn apdu_answer_error() { let answer = APDUAnswer::from_answer(&[0x64, 0x00][..]).expect("valid answer length >= 2"); - let code = answer.error_code().expect("valid error code"); + let code = answer + .error_code() + .expect("valid error code"); assert_eq!(code, APDUErrorCode::ExecutionError); assert_eq!(answer.apdu_data(), &[]); @@ -79,9 +73,11 @@ fn apdu_answer_error() { #[test] fn apdu_answer_unknown() { - let answer = APDUAnswer::from_answer(&APDU_RESPONSE[..4]).expect("valid answer length >= 2"); + let answer = APDUAnswer::from_answer(&APDU_RESPONSE[.. 4]).expect("valid answer length >= 2"); - let code = answer.error_code().expect_err("invalid error code"); + let code = answer + .error_code() + .expect_err("invalid error code"); assert_eq!(code, 0xBEEF); assert_eq!(answer.apdu_data(), &[0xDE, 0xAD]); diff --git a/ledger-transport-hid/Cargo.toml b/ledger-transport-hid/Cargo.toml index d344cd4..6849bd6 100644 --- a/ledger-transport-hid/Cargo.toml +++ b/ledger-transport-hid/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ledger-transport-hid" description = "Ledger Hardware Wallet - HID Transport" -version = "0.10.0" +version = "0.11.0" license = "Apache-2.0" authors = ["Zondax AG "] homepage = "https://github.com/zondax/ledger-rs" @@ -13,19 +13,18 @@ edition = "2021" [dependencies] libc = "0.2" -byteorder = "1.4" -cfg-if = "1.0.0" -thiserror = "1.0" +byteorder = "1.5" +cfg-if = "1" +thiserror = "1" hex = "0.4" log = "0.4" -ledger-transport = "0.10" - -hidapi = { version = "1.4.1", features = ["linux-static-hidraw"], default-features = false } +ledger-transport = { path = "../ledger-transport" } +hidapi = { version = "2.6.1", features = ["linux-static-hidraw"], default-features = false } [dev-dependencies] once_cell = "1" -ledger-zondax-generic = "0.10" -serial_test = "0.7.0" -env_logger = "0.9" +ledger-zondax-generic = { path = "../ledger-zondax-generic" } +serial_test = "3" +env_logger = "0.11" futures = "0.3" diff --git a/ledger-transport-hid/src/lib.rs b/ledger-transport-hid/src/lib.rs index be30696..e86ae8a 100644 --- a/ledger-transport-hid/src/lib.rs +++ b/ledger-transport-hid/src/lib.rs @@ -14,16 +14,14 @@ * limitations under the License. ********************************************************************************/ mod errors; -pub use errors::LedgerHIDError; - -use byteorder::{BigEndian, ReadBytesExt}; -use hidapi::{DeviceInfo, HidApi, HidDevice}; -use log::info; - use std::{io::Cursor, ops::Deref, sync::Mutex}; +use byteorder::{BigEndian, ReadBytesExt}; +pub use errors::LedgerHIDError; pub use hidapi; +use hidapi::{DeviceInfo, HidApi, HidDevice}; use ledger_transport::{async_trait, APDUAnswer, APDUCommand, Exchange}; +use log::info; const LEDGER_VID: u16 = 0x2c97; const LEDGER_USAGE_PAGE: u16 = 0xFFA0; @@ -45,7 +43,8 @@ impl TransportNativeHID { /// Get a list of ledger devices available pub fn list_ledgers(api: &HidApi) -> impl Iterator { - api.device_list().filter(|dev| Self::is_ledger(dev)) + api.device_list() + .filter(|dev| Self::is_ledger(dev)) } /// Create a new HID transport, connecting to the first ledger found @@ -68,13 +67,14 @@ impl TransportNativeHID { /// # Warning /// Opening the same device concurrently will lead to device lock after the first handle is closed /// see [issue](https://github.com/ruabmbua/hidapi-rs/issues/81) - pub fn open_device(api: &HidApi, device: &DeviceInfo) -> Result { + pub fn open_device( + api: &HidApi, + device: &DeviceInfo, + ) -> Result { let device = device.open_device(api)?; let _ = device.set_blocking_mode(true); - let ledger = TransportNativeHID { - device: Mutex::new(device), - }; + let ledger = TransportNativeHID { device: Mutex::new(device) }; Ok(ledger) } @@ -84,7 +84,7 @@ impl TransportNativeHID { channel: u16, apdu_command: &[u8], ) -> Result { - let command_length = apdu_command.len() as usize; + let command_length = apdu_command.len(); let mut in_data = Vec::with_capacity(command_length + 2); in_data.push(((command_length >> 8) & 0xFF) as u8); in_data.push((command_length & 0xFF) as u8); @@ -103,7 +103,7 @@ impl TransportNativeHID { { buffer[4] = ((sequence_idx >> 8) & 0xFF) as u8; // sequence_idx big endian buffer[5] = (sequence_idx & 0xFF) as u8; // sequence_idx big endian - buffer[6..6 + chunk.len()].copy_from_slice(chunk); + buffer[6 .. 6 + chunk.len()].copy_from_slice(chunk); info!("[{:3}] << {:}", buffer.len(), hex::encode(&buffer)); @@ -112,11 +112,9 @@ impl TransportNativeHID { match result { Ok(size) => { if size < buffer.len() { - return Err(LedgerHIDError::Comm( - "USB write error. Could not send whole message", - )); + return Err(LedgerHIDError::Comm("USB write error. Could not send whole message")); } - } + }, Err(x) => return Err(LedgerHIDError::Hid(x)), } } @@ -164,9 +162,9 @@ impl TransportNativeHID { let missing: usize = expected_apdu_len - apdu_answer.len(); let end_p = rdr.position() as usize + std::cmp::min(available, missing); - let new_chunk = &buffer[rdr.position() as usize..end_p]; + let new_chunk = &buffer[rdr.position() as usize .. end_p]; - info!("[{:3}] << {:}", new_chunk.len(), hex::encode(&new_chunk)); + info!("[{:3}] << {:}", new_chunk.len(), hex::encode(new_chunk)); apdu_answer.extend_from_slice(new_chunk); @@ -182,7 +180,10 @@ impl TransportNativeHID { &self, command: &APDUCommand, ) -> Result>, LedgerHIDError> { - let device = self.device.lock().expect("HID device poisoned"); + let device = self + .device + .lock() + .expect("HID device poisoned"); Self::write_apdu(&device, LEDGER_CHANNEL, &command.serialize())?; @@ -211,14 +212,17 @@ impl Exchange for TransportNativeHID { #[cfg(test)] mod integration_tests { - use crate::{APDUCommand, TransportNativeHID}; use hidapi::HidApi; use log::info; use once_cell::sync::Lazy; use serial_test::serial; + use crate::{APDUCommand, TransportNativeHID}; + fn init_logging() { - let _ = env_logger::builder().is_test(true).try_init(); + let _ = env_logger::builder() + .is_test(true) + .try_init(); } fn hidapi() -> &'static HidApi { @@ -241,8 +245,12 @@ mod integration_tests { device_info.product_id(), device_info.usage_page(), device_info.interface_number(), - device_info.manufacturer_string().unwrap_or_default(), - device_info.product_string().unwrap_or_default() + device_info + .manufacturer_string() + .unwrap_or_default(), + device_info + .product_string() + .unwrap_or_default() ); } } @@ -253,9 +261,11 @@ mod integration_tests { init_logging(); let api = hidapi(); - let mut ledgers = TransportNativeHID::list_ledgers(&api); + let mut ledgers = TransportNativeHID::list_ledgers(api); - let a_ledger = ledgers.next().expect("could not find any ledger device"); + let a_ledger = ledgers + .next() + .expect("could not find any ledger device"); info!("{:?}", a_ledger.path()); } @@ -264,13 +274,7 @@ mod integration_tests { fn serialize() { let data = vec![0, 0, 0, 1, 0, 0, 0, 1]; - let command = APDUCommand { - cla: 0x56, - ins: 0x01, - p1: 0x00, - p2: 0x00, - data, - }; + let command = APDUCommand { cla: 0x56, ins: 0x01, p1: 0x00, p2: 0x00, data }; let serialized_command = command.serialize(); @@ -293,8 +297,7 @@ mod integration_tests { let ledger = TransportNativeHID::new(hidapi()).expect("Could not get a device"); // use device info command that works in the dashboard - let result = futures::executor::block_on(Dummy::get_device_info(&ledger)) - .expect("Error during exchange"); + let result = futures::executor::block_on(Dummy::get_device_info(&ledger)).expect("Error during exchange"); info!("{:x?}", result); } @@ -311,7 +314,7 @@ mod integration_tests { init_logging(); let api = hidapi(); - let ledger = TransportNativeHID::list_ledgers(&api) + let ledger = TransportNativeHID::list_ledgers(api) .next() .expect("could not get a device"); @@ -324,10 +327,7 @@ mod integration_tests { Dummy::get_device_info(&t2), )); - let (r1, r2) = ( - r1.expect("error during exchange (t1)"), - r2.expect("error during exchange (t2)"), - ); + let (r1, r2) = (r1.expect("error during exchange (t1)"), r2.expect("error during exchange (t2)")); info!("r1: {:x?}", r1); info!("r2: {:x?}", r2); diff --git a/ledger-transport-zemu/.gitignore b/ledger-transport-zemu/.gitignore deleted file mode 100644 index a703c75..0000000 --- a/ledger-transport-zemu/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -zemu.rs -zemu_grpc.rs diff --git a/ledger-transport-zemu/Cargo.toml b/ledger-transport-zemu/Cargo.toml deleted file mode 100644 index 041b7e1..0000000 --- a/ledger-transport-zemu/Cargo.toml +++ /dev/null @@ -1,29 +0,0 @@ -[package] -name = "ledger-transport-zemu" -description = "Ledger Hardware Wallet - Zemu Transport" -version = "0.10.0" -license = "Apache-2.0" -authors = ["Linfeng Yuan "] -homepage = "https://github.com/zondax/ledger-rs" -repository = "https://github.com/zondax/ledger-rs" -readme = "README.md" -categories = ["authentication", "cryptography"] -keywords = ["ledger", "nano", "blue", "apdu", "zemu"] -edition = "2021" - -[dependencies] -thiserror = "1.0" -log = "0.4" -protobuf = "2" -grpc = "0.8" -grpc-protobuf = "0.8" -reqwest = { version = "0.11", features = ["json"]} -hex = "0.4" -serde = { version = "1.0", features = ["derive"] } - -ledger-transport = "0.10" - -[build-dependencies] -protoc-rust-grpc = "0.8" -glob = "0.3" - diff --git a/ledger-transport-zemu/README.md b/ledger-transport-zemu/README.md deleted file mode 100644 index 54c8ca2..0000000 --- a/ledger-transport-zemu/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# ledger-transport-hid - -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) - -Ledger APDU transport - Zemu backend diff --git a/ledger-transport-zemu/build.rs b/ledger-transport-zemu/build.rs deleted file mode 100644 index 2965e94..0000000 --- a/ledger-transport-zemu/build.rs +++ /dev/null @@ -1,37 +0,0 @@ -use std::{env, fs, path::PathBuf}; - -use protoc_rust_grpc::Codegen; - -fn out_dir() -> PathBuf { - PathBuf::from(env::var_os("OUT_DIR").unwrap()) -} - -fn generate_mod_rs() { - let out_dir = out_dir(); - - let mods = glob::glob(&out_dir.join("*.rs").to_string_lossy()) - .expect("glob") - .filter_map(|p| { - p.ok() - .map(|p| format!("pub mod {};", p.file_stem().unwrap().to_string_lossy())) - }) - .collect::>() - .join("\n"); - - let mod_rs = out_dir.join("proto_mod.rs"); - fs::write(&mod_rs, format!("// @generated\n{}\n", mods)).expect("write"); - - println!("cargo:rustc-env=PROTO_MOD_RS={}", mod_rs.to_string_lossy()); -} - -fn main() { - println!("cargo:rerun-if-changed=zemu.proto"); - let out = out_dir(); - Codegen::new() - .out_dir(out) - .input("zemu.proto") - .rust_protobuf(true) - .run() - .expect("protoc-rust-grpc"); - generate_mod_rs(); -} diff --git a/ledger-transport-zemu/src/errors.rs b/ledger-transport-zemu/src/errors.rs deleted file mode 100644 index 08407cf..0000000 --- a/ledger-transport-zemu/src/errors.rs +++ /dev/null @@ -1,29 +0,0 @@ -/******************************************************************************* -* (c) 2022 Zondax AG -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ -use thiserror::Error; - -#[derive(Error, Debug)] -pub enum LedgerZemuError { - /// Device not found error - #[error("Ledger connect error")] - ConnectError, - /// zemu reponse error - #[error("Zemu response error")] - ResponseError, - /// Inner error - #[error("Ledger inner error")] - InnerError, -} diff --git a/ledger-transport-zemu/src/lib.rs b/ledger-transport-zemu/src/lib.rs deleted file mode 100644 index 79028af..0000000 --- a/ledger-transport-zemu/src/lib.rs +++ /dev/null @@ -1,153 +0,0 @@ -/******************************************************************************* -* (c) 2022 Zondax AG -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -********************************************************************************/ - -include!(env!("PROTO_MOD_RS")); - -use grpc::prelude::*; -use grpc::ClientConf; -use reqwest::header::{HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE}; -use reqwest::{Client as HttpClient, Response}; -use serde::{Deserialize, Serialize}; -use std::ops::Deref; -use std::time::Duration; - -use zemu::{ExchangeReply, ExchangeRequest}; -use zemu_grpc::ZemuCommandClient; - -use ledger_transport::{async_trait, APDUAnswer, APDUCommand, Exchange}; - -mod errors; -pub use errors::LedgerZemuError; - -pub struct TransportZemuGrpc { - client: ZemuCommandClient, -} - -impl TransportZemuGrpc { - pub fn new(host: &str, port: u16) -> Result { - let client = ZemuCommandClient::new_plain(host, port, ClientConf::new()) - .map_err(|_| LedgerZemuError::ConnectError)?; - Ok(Self { client }) - } -} - -#[async_trait] -impl Exchange for TransportZemuGrpc { - type Error = LedgerZemuError; - type AnswerType = Vec; - - async fn exchange( - &self, - command: &APDUCommand, - ) -> Result, Self::Error> - where - I: Deref + Send + Sync, - { - let request = { - let mut r = ExchangeRequest::new(); - r.set_command(command.serialize()); - r - }; - - let response: ExchangeReply = self - .client - .exchange(grpc::RequestOptions::new(), request) - .drop_metadata() - .await - .map_err(|e| { - log::error!("grpc response error: {:?}", e); - LedgerZemuError::ResponseError - })?; - - APDUAnswer::from_answer(response.reply).map_err(|_| LedgerZemuError::ResponseError) - } -} - -pub struct TransportZemuHttp { - url: String, -} - -#[derive(Serialize, Debug, Clone)] -#[serde(rename_all = "camelCase")] -struct ZemuRequest { - apdu_hex: String, -} - -#[derive(Deserialize, Debug, Clone)] -struct ZemuResponse { - data: String, - error: Option, -} - -impl TransportZemuHttp { - pub fn new(host: &str, port: u16) -> Self { - Self { - url: format!("http://{}:{}", host, port), - } - } -} - -#[async_trait] -impl Exchange for TransportZemuHttp { - type Error = LedgerZemuError; - type AnswerType = Vec; - - async fn exchange( - &self, - command: &APDUCommand, - ) -> Result, Self::Error> - where - I: Deref + Send + Sync, - { - let raw_command = hex::encode(command.serialize()); - let request = ZemuRequest { - apdu_hex: raw_command, - }; - - let mut headers = HeaderMap::new(); - headers.insert(ACCEPT, HeaderValue::from_static("application/json")); - headers.insert(CONTENT_TYPE, HeaderValue::from_static("application/json")); - - let resp: Response = HttpClient::new() - .post(&self.url) - .headers(headers) - .timeout(Duration::from_secs(5)) - .json(&request) - .send() - .await - .map_err(|e| { - log::error!("create http client error: {:?}", e); - LedgerZemuError::InnerError - })?; - log::debug!("http response: {:?}", resp); - - if resp.status().is_success() { - let result: ZemuResponse = resp.json().await.map_err(|e| { - log::error!("error response: {:?}", e); - LedgerZemuError::ResponseError - })?; - if result.error.is_none() { - APDUAnswer::from_answer(hex::decode(result.data).expect("decode error")) - .map_err(|_| LedgerZemuError::ResponseError) - } else { - Err(LedgerZemuError::ResponseError) - } - } else { - log::error!("error response: {:?}", resp.status()); - Err(LedgerZemuError::ResponseError) - } - } -} diff --git a/ledger-transport-zemu/zemu.proto b/ledger-transport-zemu/zemu.proto deleted file mode 100644 index c61a42a..0000000 --- a/ledger-transport-zemu/zemu.proto +++ /dev/null @@ -1,17 +0,0 @@ -syntax = "proto3"; - -//This file needs to be synced with the one of same name in Zemu repo - -package ledger_zemu; - -service ZemuCommand { - rpc Exchange (ExchangeRequest) returns (ExchangeReply) {} -} - -message ExchangeRequest { - bytes command = 1; -} - -message ExchangeReply { - bytes reply = 1; -} diff --git a/ledger-transport/Cargo.toml b/ledger-transport/Cargo.toml index 8027311..5970171 100644 --- a/ledger-transport/Cargo.toml +++ b/ledger-transport/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ledger-transport" description = "Ledger Hardware Wallet - Generic Transport" -version = "0.10.0" +version = "0.11.0" license = "Apache-2.0" authors = ["Zondax AG "] homepage = "https://github.com/zondax/ledger-rs" @@ -12,6 +12,5 @@ keywords = ["ledger", "nano", "blue", "apdu"] edition = "2021" [dependencies] -async-trait = "0.1" - -ledger-apdu = "0.10.0" +async-trait = "0.1.80" +ledger-apdu = { path = "../ledger-apdu" } diff --git a/ledger-zondax-generic/Cargo.toml b/ledger-zondax-generic/Cargo.toml index 8975c1e..b10ddf2 100644 --- a/ledger-zondax-generic/Cargo.toml +++ b/ledger-zondax-generic/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "ledger-zondax-generic" description = "Ledger Hardware Wallet - Common APDU Protocol Types" -version = "0.10.0" +version = "0.11.0" license = "Apache-2.0" authors = ["Zondax AG "] homepage = "https://github.com/zondax/ledger-rs" @@ -12,8 +12,8 @@ keywords = ["ledger", "nano", "blue", "apdu"] edition = "2021" [dependencies] -serde = { version = "1.0", features = ["derive"] } -thiserror = "1.0" +serde = { version = "1", features = ["derive"] } +thiserror = "1" -ledger-transport = "0.10" +ledger-transport = { path = "../ledger-transport" } async-trait = "0.1" diff --git a/ledger-zondax-generic/src/errors.rs b/ledger-zondax-generic/src/errors.rs index 06a6793..ef5bf03 100644 --- a/ledger-zondax-generic/src/errors.rs +++ b/ledger-zondax-generic/src/errors.rs @@ -62,6 +62,6 @@ pub enum LedgerAppError { #[error("App Error: | {0} {1}")] AppSpecific(u16, String), ///Unknown error has occurred - #[error("Uknown error: {0}")] + #[error("Unknown error: {0}")] Unknown(u16), } diff --git a/ledger-zondax-generic/src/lib.rs b/ledger-zondax-generic/src/lib.rs index dbf3a76..bdef3e6 100644 --- a/ledger-zondax-generic/src/lib.rs +++ b/ledger-zondax-generic/src/lib.rs @@ -22,13 +22,12 @@ #![deny(missing_docs)] mod errors; -pub use errors::*; - -use serde::{Deserialize, Serialize}; use std::str; use async_trait::async_trait; +pub use errors::*; use ledger_transport::{APDUAnswer, APDUCommand, APDUErrorCode, Exchange}; +use serde::{Deserialize, Serialize}; const INS_GET_VERSION: u8 = 0x00; const CLA_APP_INFO: u8 = 0xb0; @@ -129,41 +128,35 @@ where /// /// Works only in the dashboard async fn get_device_info(transport: &E) -> Result> { - let command = APDUCommand { - cla: CLA_DEVICE_INFO, - ins: INS_DEVICE_INFO, - p1: 0x00, - p2: 0x00, - data: Vec::new(), - }; + let command = APDUCommand { cla: CLA_DEVICE_INFO, ins: INS_DEVICE_INFO, p1: 0x00, p2: 0x00, data: Vec::new() }; let response = transport.exchange(&command).await?; match response.error_code() { - Ok(APDUErrorCode::NoError) => {} + Ok(APDUErrorCode::NoError) => {}, Ok(err) => return Err(LedgerAppError::Unknown(err as _)), Err(err) => return Err(LedgerAppError::Unknown(err)), } let response_data = response.data(); - let target_id_slice = &response_data[0..4]; + let target_id_slice = &response_data[0 .. 4]; let mut idx = 4; let se_version_len: usize = response_data[idx] as usize; idx += 1; - let se_version_bytes = &response_data[idx..idx + se_version_len]; + let se_version_bytes = &response_data[idx .. idx + se_version_len]; idx += se_version_len; let flags_len: usize = response_data[idx] as usize; idx += 1; - let flag = &response_data[idx..idx + flags_len]; + let flag = &response_data[idx .. idx + flags_len]; idx += flags_len; let mcu_version_len: usize = response_data[idx] as usize; idx += 1; - let mut tmp = &response_data[idx..idx + mcu_version_len]; + let mut tmp = &response_data[idx .. idx + mcu_version_len]; if tmp[mcu_version_len - 1] == 0 { - tmp = &response_data[idx..idx + mcu_version_len - 1]; + tmp = &response_data[idx .. idx + mcu_version_len - 1]; } let mut target_id = [Default::default(); 4]; @@ -186,17 +179,11 @@ where /// /// Works only in app (TOOD: dashboard support) async fn get_app_info(transport: &E) -> Result> { - let command = APDUCommand { - cla: CLA_APP_INFO, - ins: INS_APP_INFO, - p1: 0x00, - p2: 0x00, - data: Vec::new(), - }; + let command = APDUCommand { cla: CLA_APP_INFO, ins: INS_APP_INFO, p1: 0x00, p2: 0x00, data: Vec::new() }; let response = transport.exchange(&command).await?; match response.error_code() { - Ok(APDUErrorCode::NoError) => {} + Ok(APDUErrorCode::NoError) => {}, Ok(err) => return Err(LedgerAppError::AppSpecific(err as _, err.description())), Err(err) => return Err(LedgerAppError::Unknown(err as _)), } @@ -208,12 +195,12 @@ where } let app_name_len: usize = response_data[1] as usize; - let app_name_bytes = &response_data[2..app_name_len]; + let app_name_bytes = &response_data[2 .. app_name_len]; let mut idx = 2 + app_name_len; let app_version_len: usize = response_data[idx] as usize; idx += 1; - let app_version_bytes = &response_data[idx..idx + app_version_len]; + let app_version_bytes = &response_data[idx .. idx + app_version_len]; idx += app_version_len; @@ -240,17 +227,11 @@ where /// Retrieve the app version async fn get_version(transport: &E) -> Result> { - let command = APDUCommand { - cla: Self::CLA, - ins: INS_GET_VERSION, - p1: 0x00, - p2: 0x00, - data: Vec::new(), - }; + let command = APDUCommand { cla: Self::CLA, ins: INS_GET_VERSION, p1: 0x00, p2: 0x00, data: Vec::new() }; let response = transport.exchange(&command).await?; match response.error_code() { - Ok(APDUErrorCode::NoError) => {} + Ok(APDUErrorCode::NoError) => {}, Ok(err) => return Err(LedgerAppError::Unknown(err as _)), Err(err) => return Err(LedgerAppError::Unknown(err)), } @@ -283,12 +264,7 @@ where minor: response_data[2] as u16, patch: response_data[3] as u16, locked: response_data[4] != 0, - target_id: [ - response_data[5], - response_data[6], - response_data[7], - response_data[8], - ], + target_id: [response_data[5], response_data[6], response_data[7], response_data[8]], }, // double byte version numbers + lock + target id 12 => Version { @@ -297,12 +273,7 @@ where minor: response_data[3] as u16 * 256 + response_data[4] as u16, patch: response_data[5] as u16 * 256 + response_data[6] as u16, locked: response_data[7] != 0, - target_id: [ - response_data[8], - response_data[9], - response_data[10], - response_data[11], - ], + target_id: [response_data[8], response_data[9], response_data[10], response_data[11]], }, _ => return Err(LedgerAppError::InvalidVersion), }; @@ -328,7 +299,7 @@ where let mut response = transport.exchange(&command).await?; match response.error_code() { - Ok(APDUErrorCode::NoError) => {} + Ok(APDUErrorCode::NoError) => {}, Ok(err) => return Err(LedgerAppError::AppSpecific(err as _, err.description())), Err(err) => return Err(LedgerAppError::Unknown(err as _)), } @@ -341,17 +312,11 @@ where p1 = ChunkPayloadType::Last as u8 } - let command = APDUCommand { - cla: command.cla, - ins: command.ins, - p1, - p2: 0, - data: chunk.to_vec(), - }; + let command = APDUCommand { cla: command.cla, ins: command.ins, p1, p2: 0, data: chunk.to_vec() }; response = transport.exchange(&command).await?; match response.error_code() { - Ok(APDUErrorCode::NoError) => {} + Ok(APDUErrorCode::NoError) => {}, Ok(err) => return Err(LedgerAppError::AppSpecific(err as _, err.description())), Err(err) => return Err(LedgerAppError::Unknown(err as _)), } diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..4e425a3 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,38 @@ +# rustfmt.toml example for strict formatting + +# General +edition = "2021" # Target edition of Rust +max_width = 120 # Max width of each line +hard_tabs = false # Use spaces instead of tabs +tab_spaces = 4 # Number of spaces per tab +newline_style = "Unix" # Line ending style +use_small_heuristics = "Max" # Be aggressive with formatting small items + +# Imports +reorder_imports = true # Reorder import statements +reorder_modules = true # Reorder module declarations +group_imports = "StdExternalCrate" # Group imports by type + +# Spaces around punctuation +spaces_around_ranges = true # Spaces around range operators for readability +space_before_colon = false # No space before colons +space_after_colon = true # Space after colons + +# Blank lines +blank_lines_upper_bound = 1 # Max blank lines in a row +blank_lines_lower_bound = 0 # Min blank lines in a row + +# Control flow +brace_style = "SameLineWhere" # Opening brace on the same line +control_brace_style = "AlwaysSameLine" # Control flow braces on the same line + +# Function calls and definitions +fn_params_layout = "Vertical" # Function arguments layout to favor visual alignment + +# Structs, enums, and unions +struct_variant_width = 18 # Max width of struct variants before falling back to vertical formatting, corrected to integer + +# Misc +match_block_trailing_comma = true # Trailing comma in match blocks for easier editing +chain_width = 40 # Max width for a chain of method calls before breaking to enhance readability +overflow_delimited_expr = true # Allow certain expressions to overflow delimiters