Skip to content

Commit

Permalink
Merge pull request #107 from LedgerHQ/ohe/cla-filtering
Browse files Browse the repository at this point in the history
Added automatic CLA filtering option in Comm
  • Loading branch information
kingofpayne authored Dec 20, 2023
2 parents b963604 + 9b0f9a1 commit d102bba
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
2 changes: 1 addition & 1 deletion ledger_device_sdk/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ledger_device_sdk"
version = "1.3.0"
version = "1.4.0"
authors = ["yhql", "yogh333"]
edition = "2021"
license.workspace = true
Expand Down
36 changes: 36 additions & 0 deletions ledger_device_sdk/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,18 @@ pub enum Event<T> {
Ticker,
}

/// Manages the communication of the device: receives events such as button presses, incoming
/// APDU requests, and provides methods to build and transmit APDU responses.
pub struct Comm {
pub apdu_buffer: [u8; 260],
pub rx: usize,
pub tx: usize,
buttons: ButtonsState,
/// Expected value for the APDU CLA byte.
/// If defined, [`Comm`] will automatically reply with [`StatusWords::BadCla`] when an APDU
/// with wrong CLA byte is received. If set to [`None`], all CLA are accepted.
/// Can be set using [`Comm::set_expected_cla`] method.
pub expected_cla: Option<u8>,
}

impl Default for Comm {
Expand All @@ -121,15 +128,36 @@ pub struct ApduHeader {
}

impl Comm {
/// Creates a new [`Comm`] instance, which accepts any CLA APDU by default.
pub const fn new() -> Self {
Self {
apdu_buffer: [0u8; 260],
rx: 0,
tx: 0,
buttons: ButtonsState::new(),
expected_cla: None,
}
}

/// Defines [`Comm::expected_cla`] in order to reply automatically [`StatusWords::BadCla`] when
/// an incoming APDU has a CLA byte different from the given value.
///
/// # Arguments
///
/// * `cla` - Expected value for APDUs CLA byte.
///
/// # Examples
///
/// This method can be used when building an instance of [`Comm`]:
///
/// ```
/// let mut comm = Comm::new().set_expected_cla(0xe0);
/// ```
pub fn set_expected_cla(mut self, cla: u8) -> Self {
self.expected_cla = Some(cla);
self
}

/// Send the currently held APDU
// This is private. Users should call reply to set the satus word and
// transmit the response.
Expand Down Expand Up @@ -303,6 +331,14 @@ impl Comm {
return None;
}

// If CLA filtering is enabled, automatically reject APDUs with wrong CLA
if let Some(cla) = self.expected_cla {
if self.apdu_buffer[0] != cla {
self.reply(StatusWords::BadCla);
return None;
}
}

let res = T::try_from(*self.get_apdu_metadata());
match res {
Ok(ins) => {
Expand Down

0 comments on commit d102bba

Please sign in to comment.