implement get_applications_id command

This commit is contained in:
Alexander Sieg 2022-04-24 22:44:23 +02:00
parent 2d550a5bc3
commit e67f0b7fac
No known key found for this signature in database

View File

@ -51,6 +51,41 @@ impl Desfire {
response.check()
}
pub fn get_application_ids_cmd(&self) -> Result<APDUCommand> {
Ok(APDUCommand {
case: IsoCase::Case2Short,
cla: 0x90,
ins: APDUInstructions::GetApplicationIds as u8,
..Default::default()
})
}
/// Get all application ids on the defire token
pub fn get_application_ids(&self) -> Result<Vec<u32>> {
let cmd_get_application_ids = self.get_application_ids_cmd()?;
let response = self
.card
.as_ref()
.unwrap()
.transmit(cmd_get_application_ids)?;
response.check()?;
if let Some(body) = response.body {
Ok(body
// application ids are 3 byte long MSB first values
// TODO: use `slice::array_chunks` when its stable
.chunks_exact(3)
// pad with one byte extra byte to it it into an u32
.map(|chunk| u32::from_le_bytes([chunk[0], chunk[1], chunk[2], 0x0]))
.collect())
} else {
// body is empty, there are no applications on this card
// except the picc 0x000000 application
Ok(vec![])
}
}
/// Authenticate to PICC, with ISO Authenticate for DES Key
///
/// Arguments:
@ -1015,6 +1050,31 @@ mod tests {
desfire.select_application(0xff000000).unwrap();
}
#[test]
fn get_application_ids() {
let mut mock = MockVirtualCard::new();
mock.expect_transmit()
.withf(|x: &APDUCommand| {
(Vec::<u8>::try_from(x.clone()).unwrap()) == vec![0x90, 0x6a, 0x00, 0x00, 0x00]
})
.return_once(move |_| {
Ok(APDUResponse {
body: Some(vec![0x01, 0x00, 0x00, 0x02, 0x00, 0x00]),
sw1: 0x91,
sw2: 0x00,
})
});
let desfire = Desfire {
card: Some(Box::new(mock)),
cbc_iv: None,
session_key: None,
};
let ids = desfire.get_application_ids().unwrap();
assert_eq!(ids, vec![1, 2])
}
#[test]
#[ignore]
fn select_application_hardware() {