Improve compatibility with ISO 7816-compliant PIV devices (#663)

This commit is contained in:
Johannes Herforth
2026-05-11 20:36:36 +02:00
committed by GitHub
parent 6c12c7b187
commit ca2615eef8
2 changed files with 29 additions and 3 deletions
+22 -2
View File
@@ -114,11 +114,31 @@ impl Apdu {
self self
} }
/// Transmit this APDU using the given card transaction /// Transmit this APDU using the given card transaction.
///
/// Handles ISO 7816-4 `SW1=61` (bytes remaining) responses by issuing
/// [`Ins::GetResponseApdu`] commands until all response data is collected.
pub fn transmit(&self, txn: &Transaction<'_>, recv_len: usize) -> Result<Response> { pub fn transmit(&self, txn: &Transaction<'_>, recv_len: usize) -> Result<Response> {
trace!(">>> {:?}", self); trace!(">>> {:?}", self);
let response = Response::from(txn.transmit(&self.to_bytes(), recv_len)?); let mut response = Response::from(txn.transmit(&self.to_bytes(), recv_len)?);
trace!("<<< {:?}", &response); trace!("<<< {:?}", &response);
if let StatusWords::BytesRemaining { .. } = response.status_words() {
let mut data = response.data().to_vec();
let mut sw = response.status_words();
while let StatusWords::BytesRemaining { .. } = sw {
let next = Response::from(
txn.transmit(&Apdu::new(Ins::GetResponseApdu).to_bytes(), recv_len)?,
);
trace!("<<< {:?}", &next);
data.extend_from_slice(next.data());
sw = next.status_words();
}
response = Response::new(sw, data);
}
Ok(response) Ok(response)
} }
+7 -1
View File
@@ -599,7 +599,13 @@ impl Key {
}; };
if !buf.is_empty() { if !buf.is_empty() {
let cert = Certificate::from_bytes(buf)?; let cert = match Certificate::from_bytes(buf) {
Ok(c) => c,
Err(e) => {
debug!("error parsing certificate in slot {:?}: {}", slot, e);
continue;
}
};
keys.push(Key { slot, cert }); keys.push(Key { slot, cert });
} }
} }