From cf6fedc5b29b75f005c860e765bfe12319dccb66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sosth=C3=A8ne=20Gu=C3=A9don?= Date: Mon, 13 Feb 2023 17:24:51 +0100 Subject: [PATCH] Migrate to interchange 0.3.0 --- Cargo.toml | 2 +- fuzz/Cargo.toml | 2 +- fuzz/fuzz_targets/fuzz_target_1.rs | 20 ++++++++------- src/dispatch.rs | 39 ++++++++++++++---------------- src/interchanges.rs | 10 ++------ tests/dispatch.rs | 38 ++++++++++++++++------------- 6 files changed, 54 insertions(+), 57 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ddc2711..0d28a80 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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] diff --git a/fuzz/Cargo.toml b/fuzz/Cargo.toml index c4353d2..7bec317 100644 --- a/fuzz/Cargo.toml +++ b/fuzz/Cargo.toml @@ -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 = ".." diff --git a/fuzz/fuzz_targets/fuzz_target_1.rs b/fuzz/fuzz_targets/fuzz_target_1.rs index 59462ba..6074e89 100644 --- a/fuzz/fuzz_targets/fuzz_target_1.rs +++ b/fuzz/fuzz_targets/fuzz_target_1.rs @@ -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); diff --git a/src/dispatch.rs b/src/dispatch.rs index ec20b37..568d013 100644 --- a/src/dispatch.rs +++ b/src/dispatch.rs @@ -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, - contact: Responder, - contactless: Responder, + 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(apdu: &iso7816::Command) -> 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, - contactless: Responder, - ) -> 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"), diff --git a/src/interchanges.rs b/src/interchanges.rs index 673fa81..2628bad 100644 --- a/src/interchanges.rs +++ b/src/interchanges.rs @@ -1,10 +1,4 @@ pub const SIZE: usize = 3072; pub type Data = iso7816::Data; - -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>; diff --git a/tests/dispatch.rs b/tests/dispatch.rs index b10faac..968cb45 100644 --- a/tests/dispatch.rs +++ b/tests/dispatch.rs @@ -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]);