Update to heapless 0.9.1 and iso7816 0.2.0

This commit is contained in:
Sosthène Guédon
2025-10-06 16:16:08 +02:00
parent edf19e997a
commit e7b3b2d8db
8 changed files with 37 additions and 39 deletions
+2 -1
View File
@@ -9,7 +9,8 @@ license = "Apache-2.0 OR MIT"
repository = "https://github.com/trussed-dev/apdu-dispatch"
[workspace.dependencies]
iso7816 = "0.1.2"
iso7816 = "0.2.0"
heapless = "0.9"
[patch.crates-io]
apdu-app.path = "app"
+1
View File
@@ -10,3 +10,4 @@ repository.workspace = true
[dependencies]
iso7816.workspace = true
heapless.workspace = true
+10 -4
View File
@@ -1,11 +1,12 @@
#![no_std]
pub use iso7816::{command::CommandView, Data, Interface, Status};
pub use heapless::VecView;
pub use iso7816::{command::CommandView, Interface};
pub type Result = iso7816::Result<()>;
/// An App can receive and respond APDUs at behest of the ApduDispatch.
pub trait App<const R: usize>: iso7816::App {
pub trait App: iso7816::App {
/// Given parsed APDU for select command.
/// Write response data back to buf, and return length of payload. Return APDU Error code on error.
/// Alternatively, the app can defer the response until later by returning it in `poll()`.
@@ -13,7 +14,7 @@ pub trait App<const R: usize>: iso7816::App {
&mut self,
interface: Interface,
apdu: CommandView<'_>,
reply: &mut Data<R>,
reply: &mut VecView<u8>,
) -> Result;
/// Deselects the app. This is the result of another app getting selected.
@@ -22,5 +23,10 @@ pub trait App<const R: usize>: iso7816::App {
/// Given parsed APDU for app when selected.
/// Write response data back to buf, and return length of payload. Return APDU Error code on error.
fn call(&mut self, interface: Interface, apdu: CommandView<'_>, reply: &mut Data<R>) -> Result;
fn call(
&mut self,
interface: Interface,
apdu: CommandView<'_>,
reply: &mut VecView<u8>,
) -> Result;
}
+1 -1
View File
@@ -11,9 +11,9 @@ repository.workspace = true
[dependencies]
apdu-app = "0.1.0"
delog = "0.1.4"
heapless = "0.7"
interchange = "0.3.0"
iso7816.workspace = true
heapless.workspace = true
[dev-dependencies]
# Testing
+5 -15
View File
@@ -8,7 +8,6 @@
//!
//! Apps need to implement the App trait to be managed.
//!
use core::mem;
use crate::response::SIZE as ResponseSize;
use crate::App;
@@ -123,8 +122,8 @@ impl<'pipe> ApduDispatch<'pipe> {
// but that won't work due to ownership rules
fn find_app<'a, 'b>(
aid: Option<&Aid>,
apps: &'a mut [&'b mut dyn App<ResponseSize>],
) -> Option<&'a mut &'b mut dyn App<ResponseSize>> {
apps: &'a mut [&'b mut dyn App],
) -> Option<&'a mut &'b mut dyn App> {
// match aid {
// Some(aid) => apps.iter_mut().find(|app| aid.starts_with(app.rid())),
// None => None,
@@ -366,12 +365,7 @@ impl<'pipe> ApduDispatch<'pipe> {
}
#[inline(never)]
fn handle_app_select(
&mut self,
apps: &mut [&mut dyn App<ResponseSize>],
aid: Aid,
interface: Interface,
) {
fn handle_app_select(&mut self, apps: &mut [&mut dyn App], aid: Aid, interface: Interface) {
// three cases:
// - currently selected app has different AID -> deselect it, to give it
// the chance to clear sensitive state
@@ -412,11 +406,7 @@ impl<'pipe> ApduDispatch<'pipe> {
}
#[inline(never)]
fn handle_app_command(
&mut self,
apps: &mut [&mut dyn App<ResponseSize>],
interface: Interface,
) {
fn handle_app_command(&mut self, apps: &mut [&mut dyn App], interface: Interface) {
// if there is a selected app, send it the command
let mut response = response::Data::new();
if let Some(app) = Self::find_app(self.current_aid.as_ref(), apps) {
@@ -431,7 +421,7 @@ impl<'pipe> ApduDispatch<'pipe> {
};
}
pub fn poll(&mut self, apps: &mut [&mut dyn App<ResponseSize>]) -> Option<Interface> {
pub fn poll(&mut self, apps: &mut [&mut dyn App]) -> Option<Interface> {
// Only take on one transaction at a time.
let request_type = self.check_for_request();
+12 -11
View File
@@ -1,6 +1,7 @@
use apdu_dispatch::app::{App, CommandView, Result as AppResult};
use apdu_dispatch::dispatch;
use apdu_dispatch::{interchanges, response};
use heapless::VecView;
use hex_literal::hex;
use interchange::Channel;
use iso7816::Status;
@@ -47,12 +48,12 @@ impl iso7816::App for TestApp1 {
}
// This app echos to Ins code 0x10
impl App<{ apdu_dispatch::response::SIZE }> for TestApp1 {
impl App for TestApp1 {
fn select(
&mut self,
_interface: dispatch::Interface,
_apdu: CommandView<'_>,
_reply: &mut response::Data,
_reply: &mut VecView<u8>,
) -> AppResult {
Ok(())
}
@@ -63,7 +64,7 @@ impl App<{ apdu_dispatch::response::SIZE }> for TestApp1 {
&mut self,
_: dispatch::Interface,
apdu: CommandView<'_>,
reply: &mut response::Data,
reply: &mut VecView<u8>,
) -> AppResult {
println!("TestApp1::call");
match apdu.instruction().into() {
@@ -79,8 +80,8 @@ impl App<{ apdu_dispatch::response::SIZE }> for TestApp1 {
}
// For measuring the stack burden of dispatch
0x15 => {
let buf = heapless::Vec::new();
let addr = (&buf as *const response::Data) as u32;
let buf = heapless::Vec::<u8, { response::SIZE }>::new();
let addr = (&buf as *const VecView<u8>).addr() as u32;
reply.extend_from_slice(&addr.to_be_bytes()).unwrap();
Ok(())
}
@@ -122,12 +123,12 @@ impl iso7816::App for TestApp2 {
}
// This app echos to Ins code 0x20
impl App<{ apdu_dispatch::response::SIZE }> for TestApp2 {
impl App for TestApp2 {
fn select(
&mut self,
_interface: dispatch::Interface,
_apdu: CommandView<'_>,
_reply: &mut response::Data,
_reply: &mut VecView<u8>,
) -> AppResult {
Ok(())
}
@@ -138,7 +139,7 @@ impl App<{ apdu_dispatch::response::SIZE }> for TestApp2 {
&mut self,
_: dispatch::Interface,
apdu: CommandView<'_>,
reply: &mut response::Data,
reply: &mut VecView<u8>,
) -> AppResult {
println!("TestApp2::call");
match apdu.instruction().into() {
@@ -174,12 +175,12 @@ impl iso7816::App for PanicApp {
}
// This app echos to Ins code 0x20
impl App<{ apdu_dispatch::response::SIZE }> for PanicApp {
impl App for PanicApp {
fn select(
&mut self,
_interface: dispatch::Interface,
_apdu: CommandView<'_>,
_reply: &mut response::Data,
_reply: &mut VecView<u8>,
) -> AppResult {
panic!("Dont call the panic app");
}
@@ -192,7 +193,7 @@ impl App<{ apdu_dispatch::response::SIZE }> for PanicApp {
&mut self,
_: dispatch::Interface,
_apdu: CommandView<'_>,
_reply: &mut response::Data,
_reply: &mut VecView<u8>,
) -> AppResult {
panic!("Dont call the panic app");
}
+1
View File
@@ -12,6 +12,7 @@ cargo-fuzz = true
libfuzzer-sys = "0.4"
arbitrary = { version = "1", features = ["derive"] }
interchange = "0.3.0"
heapless = "0.9.0"
[dependencies.apdu-dispatch]
path = "../dispatch"
+5 -7
View File
@@ -2,6 +2,7 @@
use apdu_dispatch::app::Result as AppResult;
use apdu_dispatch::{dispatch::Interface, interchanges, iso7816, App};
use arbitrary::{Arbitrary, Unstructured};
use heapless::VecView;
use interchange::Channel;
use libfuzzer_sys::fuzz_target;
@@ -53,12 +54,12 @@ impl iso7816::App for FuzzAppImpl {
}
}
impl App<{ apdu_dispatch::response::SIZE }> for FuzzAppImpl {
impl App for FuzzAppImpl {
fn select(
&mut self,
_interface: iso7816::Interface,
_apdu: apdu_dispatch::app::CommandView<'_>,
_reply: &mut apdu_dispatch::response::Data,
_reply: &mut heapless::VecView<u8>,
) -> AppResult {
Ok(())
}
@@ -69,7 +70,7 @@ impl App<{ apdu_dispatch::response::SIZE }> for FuzzAppImpl {
&mut self,
_: Interface,
_apdu: apdu_dispatch::app::CommandView<'_>,
reply: &mut apdu_dispatch::response::Data,
reply: &mut VecView<u8>,
) -> AppResult {
let (ref data, status) = &self.responses[self.count];
reply.extend_from_slice(data).ok();
@@ -89,10 +90,7 @@ fuzz_target!(|input: Input| {
.enumerate()
.map(|(idx, app)| FuzzAppImpl::new(idx, app))
.collect();
let mut dyn_apps: Vec<_> = apps
.iter_mut()
.map(|s| (s as &mut dyn apdu_dispatch::App<7609>))
.collect();
let mut dyn_apps: Vec<&mut dyn apdu_dispatch::App> = apps.iter_mut().map(|s| s as _).collect();
let contact = Channel::new();
let (mut contact_requester, contact_responder) = contact