From f3533d1722425982ecca0d657f5780b5eaffaab8 Mon Sep 17 00:00:00 2001 From: Robin Krahl Date: Wed, 12 Oct 2022 13:48:50 +0200 Subject: [PATCH] Fix maximum response length check To decide whether we send out the response in whole or in chunks, we not only have to compare the length with the maximum length supported by interchange but also with the maximum response length specified in the request APDU. --- CHANGELOG.md | 3 +++ src/dispatch.rs | 6 +++--- tests/dispatch.rs | 19 ++++++++++--------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7c86c3..cdc81dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Fixed +- Fixed the calculation of the maximum length of a response when deciding + whether to send it in one or multiple APDUs. ## [0.1.1] - 2022-08-22 - respect `Le` field @sosthene-nitrokey diff --git a/src/dispatch.rs b/src/dispatch.rs index cc57c7c..6108a9f 100644 --- a/src/dispatch.rs +++ b/src/dispatch.rs @@ -288,11 +288,11 @@ impl ApduDispatch ) } RawApduBuffer::Response(res) => { - - if self.was_request_chained || res.len() > MAX_INTERCHANGE_DATA { + let max_response_len = self.response_len_expected.min(MAX_INTERCHANGE_DATA); + if self.was_request_chained || res.len() > max_response_len { // Do not send more than the expected bytes - let boundary = self.response_len_expected.min(res.len()).min(MAX_INTERCHANGE_DATA); + let boundary = max_response_len.min(res.len()); let to_send = &res[..boundary]; let remaining = &res[boundary..]; diff --git a/tests/dispatch.rs b/tests/dispatch.rs index 550fb6a..921ebc6 100644 --- a/tests/dispatch.rs +++ b/tests/dispatch.rs @@ -330,7 +330,7 @@ fn echo_1(){ &hex!("9000"), // Echo - &hex!("00100000 05 0102030405"), + &hex!("00100000 05 0102030405 00"), // Echo + Ok &hex!("0000000000 01020304059000"), ] @@ -348,7 +348,7 @@ fn echo_with_cla_bits_set(){ &hex!("9000"), // Echo - &hex!("80100000 05 0102030405"), + &hex!("80100000 05 0102030405 00"), // Echo + Ok &hex!("0000000000 0102030405 9000"), ] @@ -366,7 +366,7 @@ fn echo_wrong_instruction(){ &hex!("9000"), // Echo - &hex!("00200000 05 0102030405"), + &hex!("00200000 05 0102030405 00"), // Wrong Ins &hex!("6d00"), ] @@ -384,7 +384,7 @@ fn echo_2(){ &hex!("9000"), // Echo - &hex!("00200000 05 0102030405"), + &hex!("00200000 05 0102030405 00"), // Echo + Ok &hex!("0000000000 0102030405 9000"), ] @@ -402,7 +402,7 @@ fn echo_wrong_instruction_2(){ &hex!("9000"), // Echo - &hex!("00100000 05 0102030405"), + &hex!("00100000 05 0102030405 00"), // Wrong Ins &hex!("6d00"), ] @@ -432,7 +432,7 @@ fn deselect (){ &hex!("9000"), // Echo 1 - &hex!("00100000 05 0102030405"), + &hex!("00100000 05 0102030405 00"), &hex!("0000000000 0102030405 9000"), // Select 2 @@ -440,7 +440,7 @@ fn deselect (){ &hex!("9000"), // Echo 1 - &hex!("00100000 05 0102030405"), + &hex!("00100000 05 0102030405 00"), &hex!("6d00"), ] ) @@ -456,7 +456,7 @@ fn extended_length_echo (){ &hex!("9000"), // To be echo'd - &hex!("00100000000123 + &hex!("00100000 000123 /* 1 8 16 24 32 */ /* 1 */ 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 /* 2 */ 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 @@ -468,6 +468,7 @@ fn extended_length_echo (){ /* 8 */ 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 /* 9 */ 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 /* 10 */ 01 01 01 + 0000 "), // echo Success &hex!("0000000000 @@ -1123,7 +1124,7 @@ fn check_stack_burden(){ dump_hex(&response); contact_requester.request(&interchanges::Data::from_slice( - &hex!("00150000") + &hex!("0015000000") ).unwrap()).expect("could not deposit command"); apdu_dispatch.poll(&mut[&mut app1]);