mirror of
https://github.com/trussed-dev/apdu-dispatch.git
synced 2026-06-20 04:16:15 -07:00
Update to heapless 0.9.1 and iso7816 0.2.0
This commit is contained in:
+2
-1
@@ -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"
|
||||
|
||||
@@ -10,3 +10,4 @@ repository.workspace = true
|
||||
|
||||
[dependencies]
|
||||
iso7816.workspace = true
|
||||
heapless.workspace = true
|
||||
|
||||
+10
-4
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user