Migrate to interchange 0.3.0

This commit is contained in:
Sosthène Guédon
2023-02-14 10:45:07 +01:00
committed by Robin Krahl
parent fcd5ad38a1
commit cf6fedc5b2
6 changed files with 54 additions and 57 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ documentation = "https://docs.rs/apdu-dispatch"
[dependencies]
delog = "0.1.4"
heapless = "0.7"
interchange = "0.2.0"
interchange = "0.3.0"
iso7816 = "0.1.1"
[dev-dependencies]
+1 -1
View File
@@ -11,7 +11,7 @@ cargo-fuzz = true
[dependencies]
libfuzzer-sys = "0.4"
arbitrary = { version = "1", features = ["derive"] }
interchange = "0.2.0"
interchange = "0.3.0"
[dependencies.apdu-dispatch]
path = ".."
+11 -9
View File
@@ -2,7 +2,7 @@
use apdu_dispatch::app::Result as AppResult;
use apdu_dispatch::{dispatch::Interface, interchanges, iso7816, App};
use arbitrary::{Arbitrary, Unstructured};
use interchange::Interchange;
use interchange::Channel;
use libfuzzer_sys::fuzz_target;
use std::convert::TryFrom;
@@ -87,8 +87,6 @@ impl App<{ apdu_dispatch::command::SIZE }, { apdu_dispatch::response::SIZE }> fo
}
fuzz_target!(|input: Input| {
unsafe { interchanges::Contact::reset_claims() };
unsafe { interchanges::Contactless::reset_claims() };
let mut apps: Vec<_> = input
.apps
.into_iter()
@@ -100,11 +98,15 @@ fuzz_target!(|input: Input| {
.map(|s| (s as &mut dyn apdu_dispatch::App<7609, 7609>))
.collect();
let (mut contact_requester, contact_responder) =
interchanges::Contact::claim().expect("could not setup ccid ApduInterchange");
let contact = Channel::new();
let (mut contact_requester, contact_responder) = contact
.split()
.expect("could not setup ccid ApduInterchange");
let (mut contactless_requester, contactless_responder) =
interchanges::Contactless::claim().expect("could not setup iso14443 ApduInterchange");
let contactless = Channel::new();
let (mut contactless_requester, contactless_responder) = contactless
.split()
.expect("could not setup iso14443 ApduInterchange");
let mut apdu_dispatch =
apdu_dispatch::dispatch::ApduDispatch::new(contact_responder, contactless_responder);
@@ -113,11 +115,11 @@ fuzz_target!(|input: Input| {
apdu.truncate(interchanges::SIZE);
if requester {
contact_requester
.request(&interchanges::Data::from_slice(&apdu).unwrap())
.request(interchanges::Data::from_slice(&apdu).unwrap())
.expect("could not deposit command");
} else {
contactless_requester
.request(&interchanges::Data::from_slice(&apdu).unwrap())
.request(interchanges::Data::from_slice(&apdu).unwrap())
.expect("could not deposit command");
}
apdu_dispatch.poll(&mut dyn_apps);
+18 -21
View File
@@ -11,7 +11,10 @@
use crate::command::SIZE as CommandSize;
use crate::response::SIZE as ResponseSize;
use crate::App;
use crate::{interchanges, response, Command};
use crate::{
interchanges::{self, Responder},
response, Command,
};
use core::convert::TryInto;
use iso7816::{command::FromSliceError, Aid, Instruction, Result, Status};
@@ -36,8 +39,6 @@ pub enum RequestType {
None,
}
use interchange::Responder;
#[derive(PartialEq)]
enum RawApduBuffer {
None,
@@ -71,11 +72,11 @@ impl ApduBuffer {
}
}
pub struct ApduDispatch {
pub struct ApduDispatch<'pipe> {
// or currently_selected_aid, or...
current_aid: Option<Aid>,
contact: Responder<interchanges::Contact>,
contactless: Responder<interchanges::Contactless>,
contact: Responder<'pipe>,
contactless: Responder<'pipe>,
current_interface: Interface,
buffer: ApduBuffer,
@@ -83,7 +84,7 @@ pub struct ApduDispatch {
was_request_chained: bool,
}
impl ApduDispatch {
impl<'pipe> ApduDispatch<'pipe> {
fn apdu_type<const S: usize>(apdu: &iso7816::Command<S>) -> RequestType {
info!("instruction: {:?} {}", apdu.instruction(), apdu.p1);
if apdu.instruction() == Instruction::Select && (apdu.p1 & 0x04) != 0 {
@@ -101,10 +102,7 @@ impl ApduDispatch {
}
}
pub fn new(
contact: Responder<interchanges::Contact>,
contactless: Responder<interchanges::Contactless>,
) -> ApduDispatch {
pub fn new(contact: Responder<'pipe>, contactless: Responder<'pipe>) -> Self {
ApduDispatch {
current_aid: None,
contact,
@@ -185,12 +183,12 @@ impl ApduDispatch {
// acknowledge
Interface::Contact => {
self.contact
.respond(&Status::Success.try_into().unwrap())
.respond(Status::Success.try_into().unwrap())
.expect("Could not respond");
}
Interface::Contactless => {
self.contactless
.respond(&Status::Success.try_into().unwrap())
.respond(Status::Success.try_into().unwrap())
.expect("Could not respond");
}
}
@@ -258,12 +256,11 @@ impl ApduDispatch {
match interface {
Interface::Contactless => self
.contactless
.respond(&response.into())
.expect("cant respond"),
Interface::Contact => self
.contact
.respond(&response.into())
.respond(response.into())
.expect("cant respond"),
Interface::Contact => {
self.contact.respond(response.into()).expect("cant respond")
}
}
RequestType::None
}
@@ -275,7 +272,7 @@ impl ApduDispatch {
#[inline(never)]
fn reply_error(&mut self, status: Status) {
self.respond(&status.into());
self.respond(status.into());
self.buffer.raw = RawApduBuffer::None;
}
@@ -333,7 +330,7 @@ impl ApduDispatch {
}
};
self.buffer.raw = new_state;
self.respond(&response);
self.respond(response);
}
#[inline(never)]
@@ -463,7 +460,7 @@ impl ApduDispatch {
}
#[inline(never)]
fn respond(&mut self, message: &interchanges::Data) {
fn respond(&mut self, message: interchanges::Data) {
debug!("<< {}", hex_str!(message.as_slice(), sep:""));
match self.current_interface {
Interface::Contactless => self.contactless.respond(message).expect("cant respond"),
+2 -8
View File
@@ -1,10 +1,4 @@
pub const SIZE: usize = 3072;
pub type Data = iso7816::Data<SIZE>;
interchange::interchange! {
Contact: (Data, Data)
}
interchange::interchange! {
Contactless: (Data, Data)
}
pub type Responder<'pipe> = interchange::Responder<'pipe, Data, Data>;
pub type Requester<'pipe> = interchange::Responder<'pipe, Data, Data>;
+21 -17
View File
@@ -3,7 +3,7 @@ use apdu_dispatch::dispatch;
use apdu_dispatch::Command;
use apdu_dispatch::{interchanges, response};
use hex_literal::hex;
use interchange::Interchange;
use interchange::Channel;
use iso7816::Status;
#[macro_use]
@@ -189,13 +189,16 @@ fn run_apdus(apdu_response_pairs: &[&[u8]]) {
assert!((apdu_response_pairs.len() & 1) == 0);
Delogger::init_default(delog::LevelFilter::Info, &STDOUT_FLUSHER).ok();
unsafe { interchanges::Contact::reset_claims() };
unsafe { interchanges::Contactless::reset_claims() };
let (mut contact_requester, contact_responder) =
interchanges::Contact::claim().expect("could not setup ccid ApduInterchange");
let (_contactless_requester, contactless_responder) =
interchanges::Contactless::claim().expect("could not setup iso14443 ApduInterchange");
let contact = Channel::new();
let (mut contact_requester, contact_responder) = contact
.split()
.expect("could not setup ccid ApduInterchange");
let contactless = Channel::new();
let (_contactless_requester, contactless_responder) = contactless
.split()
.expect("could not setup iso14443 ApduInterchange");
let mut apdu_dispatch =
apdu_dispatch::dispatch::ApduDispatch::new(contact_responder, contactless_responder);
@@ -222,7 +225,7 @@ fn run_apdus(apdu_response_pairs: &[&[u8]]) {
dump_hex(raw_req);
contact_requester
.request(&interchanges::Data::from_slice(raw_req).unwrap())
.request(interchanges::Data::from_slice(raw_req).unwrap())
.expect("could not deposit command");
apdu_dispatch.poll(&mut [&mut app0, &mut app1, &mut app2, &mut app3, &mut app4]);
@@ -1055,14 +1058,15 @@ fn response_larger_than_interchange() {
#[test]
#[serial]
fn check_stack_burden() {
unsafe { interchanges::Contact::reset_claims() };
unsafe { interchanges::Contactless::reset_claims() };
let contact = Channel::new();
let (mut contact_requester, contact_responder) = contact
.split()
.expect("could not setup ccid ApduInterchange");
let (mut contact_requester, contact_responder) =
interchanges::Contact::claim().expect("could not setup ccid ApduInterchange");
let (_contactless_requester, contactless_responder) =
interchanges::Contactless::claim().expect("could not setup iso14443 ApduInterchange");
let contactless = Channel::new();
let (_contactless_requester, contactless_responder) = contactless
.split()
.expect("could not setup iso14443 ApduInterchange");
let mut apdu_dispatch =
apdu_dispatch::dispatch::ApduDispatch::new(contact_responder, contactless_responder);
@@ -1070,7 +1074,7 @@ fn check_stack_burden() {
let mut app1 = TestApp1 {};
contact_requester
.request(&interchanges::Data::from_slice(&hex!("00A40400050A01000001")).unwrap())
.request(interchanges::Data::from_slice(&hex!("00A40400050A01000001")).unwrap())
.expect("could not deposit command");
apdu_dispatch.poll(&mut [&mut app1]);
@@ -1081,7 +1085,7 @@ fn check_stack_burden() {
dump_hex(&response);
contact_requester
.request(&interchanges::Data::from_slice(&hex!("0015000000")).unwrap())
.request(interchanges::Data::from_slice(&hex!("0015000000")).unwrap())
.expect("could not deposit command");
apdu_dispatch.poll(&mut [&mut app1]);