mirror of
https://gitlab.com/fabinfra/fabaccess/nfc_rs.git
synced 2025-03-12 06:41:46 +01:00
added tests for write_data and read_data
This commit is contained in:
parent
099c78d979
commit
3dd731e1cc
@ -11,7 +11,6 @@ use crate::crypto::util::expand_to_blocksize;
|
||||
use crate::desfire::{FileCommunication, ChangeMasterKeySettings, CreateDeleteFile, FileDirectoryAccess, ChangeMasterKey, ChangeApplicationKey, CryptoOperationsType, FileIdentifiers};
|
||||
use crate::iso7816_4::apduresponse::APDUResponse;
|
||||
use num_traits::FromPrimitive;
|
||||
use std::fs::read_to_string;
|
||||
|
||||
pub struct Desfire {
|
||||
card: Box<dyn Card>,
|
||||
@ -81,6 +80,8 @@ impl Desfire {
|
||||
rnd_b_rl.rotate_left(1);
|
||||
println!("RND_B_RL: {:x?}", rnd_b_rl);
|
||||
|
||||
//FIXME: This is ugly, we should find a better way to make the function testable
|
||||
//TODO: Check if we need a CSPRNG here
|
||||
let rnd_a = match rnd_a {
|
||||
None => { rand::random() }
|
||||
Some(i) => { i }
|
||||
@ -169,6 +170,8 @@ impl Desfire {
|
||||
rnd_b_rl.rotate_left(1);
|
||||
println!("RND_B_RL: {:x?}", rnd_b_rl);
|
||||
|
||||
//FIXME: This is ugly, we should find a better way to make the function testable
|
||||
//TODO: Check if we need a CSPRNG here
|
||||
let rnd_a = match rnd_a {
|
||||
None => { rand::random() }
|
||||
Some(i) => { i }
|
||||
@ -425,6 +428,8 @@ impl Desfire {
|
||||
return Err(InvalidFileID);
|
||||
}
|
||||
|
||||
println!("Writing data to file {}", file_id);
|
||||
|
||||
const MAX_BYTES_PER_TRANSACTION: usize = 47;
|
||||
let mut bytes_writen: usize = 0;
|
||||
let length: usize = data.len();
|
||||
@ -438,11 +443,14 @@ impl Desfire {
|
||||
};
|
||||
|
||||
let mut write_buffer = vec![file_id];
|
||||
write_buffer.append(&mut offset.to_le_bytes()[..3].to_vec());
|
||||
write_buffer.append(&mut (offset as usize + bytes_writen).to_le_bytes()[..3].to_vec());
|
||||
write_buffer.append(&mut bytes_towrite.to_le_bytes()[..3].to_vec());
|
||||
write_buffer.append(&mut data[bytes_writen..bytes_writen + bytes_towrite].to_vec());
|
||||
bytes_writen += bytes_towrite;
|
||||
|
||||
println!("WRITE_BUFFER: {:x?}", write_buffer);
|
||||
println!("BYTES_WRITEN: {}", bytes_writen);
|
||||
|
||||
let cmd_write_data = APDUCommand {
|
||||
case: IsoCase::Case4Short,
|
||||
cla: 0x90,
|
||||
@ -450,8 +458,10 @@ impl Desfire {
|
||||
data: Option::from(write_buffer),
|
||||
..Default::default()
|
||||
};
|
||||
println!("CMD_WRITE_DATA: {}", cmd_write_data);
|
||||
|
||||
let response = self.card.transmit(cmd_write_data).unwrap();
|
||||
println!("RESPONSE: {}", response);
|
||||
|
||||
ret = response.check();
|
||||
};
|
||||
@ -482,7 +492,7 @@ impl Desfire {
|
||||
};
|
||||
|
||||
let mut send_buffer = vec![file_id];
|
||||
send_buffer.append(&mut offset.to_le_bytes()[..3].to_vec());
|
||||
send_buffer.append(&mut (offset as usize + bytes_read).to_le_bytes()[..3].to_vec());
|
||||
send_buffer.append(&mut bytes_toread.to_le_bytes()[..3].to_vec());
|
||||
bytes_read += bytes_toread;
|
||||
|
||||
@ -493,8 +503,10 @@ impl Desfire {
|
||||
data: Option::from(send_buffer),
|
||||
..Default::default()
|
||||
};
|
||||
println!("CMD_READ_DATA: {}", cmd_read_data);
|
||||
|
||||
let response = self.card.transmit(cmd_read_data).unwrap();
|
||||
println!("RESPONSE: {}", response);
|
||||
|
||||
response.check().or_else(|e| return Err(e));
|
||||
|
||||
@ -785,7 +797,7 @@ mod tests {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
let mut card = PCSCCard {
|
||||
ctx,
|
||||
reader: CString::from(reader),
|
||||
@ -1114,4 +1126,151 @@ mod tests {
|
||||
let access_rights = generate_file_access_rights(FileAccessRights::FREE as u8, 0x00, 0x00, 0x00).unwrap();
|
||||
desfire.create_file_standard(0xFF, FileCommunication::PLAIN, access_rights, 0xF0).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_data() {
|
||||
let mut mock = MockVirtualCard::new();
|
||||
mock.expect_transmit().withf(|x: &APDUCommand| (Vec::<u8>::try_from(x.clone()).unwrap()) == hex!("903d00000f01000000080000546573743132333400")).return_once(move |_| Ok(APDUResponse {
|
||||
sw1: 0x91,
|
||||
sw2: 0x00,
|
||||
body: None
|
||||
}));
|
||||
|
||||
let mut desfire = Desfire {
|
||||
card: Box::new(mock),
|
||||
cbc_iv: None,
|
||||
session_key: None
|
||||
};
|
||||
|
||||
let data = "Test1234".as_bytes();
|
||||
assert!(desfire.write_data(0x01, 0x00, data.as_ref()).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn write_data_long() {
|
||||
let mut mock = MockVirtualCard::new();
|
||||
mock.expect_transmit().withf(|x: &APDUCommand| (Vec::<u8>::try_from(x.clone()).unwrap()) == hex!("903d000036010000002f0000546573743132333454657374313233345465737431323334546573743132333454657374313233345465737431323300")).return_once(move |_| Ok(APDUResponse {
|
||||
sw1: 0x91,
|
||||
sw2: 0x00,
|
||||
body: None
|
||||
}));
|
||||
|
||||
mock.expect_transmit().withf(|x: &APDUCommand| (Vec::<u8>::try_from(x.clone()).unwrap()) == hex!("903d000036012f00002f0000345465737431323334546573743132333454657374313233345465737431323334546573743132333454657374313200")).return_once(move |_| Ok(APDUResponse {
|
||||
sw1: 0x91,
|
||||
sw2: 0x00,
|
||||
body: None
|
||||
}));
|
||||
|
||||
mock.expect_transmit().withf(|x: &APDUCommand| (Vec::<u8>::try_from(x.clone()).unwrap()) == hex!("903d000019015e000012000033345465737431323334546573743132333400")).return_once(move |_| Ok(APDUResponse {
|
||||
sw1: 0x91,
|
||||
sw2: 0x00,
|
||||
body: None
|
||||
}));
|
||||
|
||||
let mut desfire = Desfire {
|
||||
card: Box::new(mock),
|
||||
cbc_iv: None,
|
||||
session_key: None
|
||||
};
|
||||
|
||||
let data = "Test1234Test1234Test1234Test1234Test1234Test1234Test1234Test1234Test1234Test1234Test1234Test1234Test1234Test1234".as_bytes();
|
||||
assert!(desfire.write_data(0x01, 0x00, data.as_ref()).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "InvalidFileID")]
|
||||
fn write_data_invalid_file_id() {
|
||||
let mut mock = MockVirtualCard::new();
|
||||
|
||||
let mut desfire = Desfire {
|
||||
card: Box::new(mock),
|
||||
cbc_iv: None,
|
||||
session_key: None
|
||||
};
|
||||
|
||||
desfire.write_data(0xFF, 0x00, &[0 as u8; 1]).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_data() {
|
||||
let mut mock = MockVirtualCard::new();
|
||||
mock.expect_transmit().withf(|x: &APDUCommand| (Vec::<u8>::try_from(x.clone()).unwrap()) == hex!("90bd0000070100000020000000")).return_once(move |_| Ok(APDUResponse {
|
||||
sw1: 0x91,
|
||||
sw2: 0x00,
|
||||
body: Some(hex!("54657374313233340000000000000000000000000000000000000000000000009100").to_vec())
|
||||
}));
|
||||
|
||||
let mut desfire = Desfire {
|
||||
card: Box::new(mock),
|
||||
cbc_iv: None,
|
||||
session_key: None
|
||||
};
|
||||
|
||||
let data = desfire.read_data(0x01, 0x00, 0x20).unwrap();
|
||||
assert_eq!("Test1234", String::from_utf8(data).unwrap().replace("\0", ""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_data_cmac() {
|
||||
let mut mock = MockVirtualCard::new();
|
||||
mock.expect_transmit().withf(|x: &APDUCommand| (Vec::<u8>::try_from(x.clone()).unwrap()) == hex!("90bd0000070100000020000000")).return_once(move |_| Ok(APDUResponse {
|
||||
sw1: 0x91,
|
||||
sw2: 0x00,
|
||||
body: Some(hex!("5465737431323334000000000000000000000000000000000000000000000000809a9bedbc559a5b9100").to_vec())
|
||||
}));
|
||||
|
||||
let mut desfire = Desfire {
|
||||
card: Box::new(mock),
|
||||
cbc_iv: None,
|
||||
session_key: None
|
||||
};
|
||||
|
||||
let data = desfire.read_data(0x01, 0x00, 0x20).unwrap();
|
||||
assert_eq!("Test1234", String::from_utf8(data).unwrap().replace("\0", ""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn read_data_long() {
|
||||
let mut mock = MockVirtualCard::new();
|
||||
mock.expect_transmit().withf(|x: &APDUCommand| (Vec::<u8>::try_from(x.clone()).unwrap()) == hex!("90bd000007010000002f000000")).return_once(move |_| Ok(APDUResponse {
|
||||
sw1: 0x91,
|
||||
sw2: 0x00,
|
||||
body: Some(hex!("54657374313233340000000000000000000000000000000000000000000000000000000000000000000000000000009100").to_vec())
|
||||
}));
|
||||
|
||||
mock.expect_transmit().withf(|x: &APDUCommand| (Vec::<u8>::try_from(x.clone()).unwrap()) == hex!("90bd000007012f00002f000000")).return_once(move |_| Ok(APDUResponse {
|
||||
sw1: 0x91,
|
||||
sw2: 0x00,
|
||||
body: Some(hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009100").to_vec())
|
||||
}));
|
||||
|
||||
mock.expect_transmit().withf(|x: &APDUCommand| (Vec::<u8>::try_from(x.clone()).unwrap()) == hex!("90bd000007015e000002000000")).return_once(move |_| Ok(APDUResponse {
|
||||
sw1: 0x91,
|
||||
sw2: 0x00,
|
||||
body: Some(hex!("00009100").to_vec())
|
||||
}));
|
||||
|
||||
let mut desfire = Desfire {
|
||||
card: Box::new(mock),
|
||||
cbc_iv: None,
|
||||
session_key: None
|
||||
};
|
||||
|
||||
let data = desfire.read_data(0x01, 0x00, 0x60).unwrap();
|
||||
assert_eq!("Test1234", String::from_utf8(data).unwrap().replace("\0", ""));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(expected = "InvalidFileID")]
|
||||
fn read_data_invalid_file_id() {
|
||||
let mut mock = MockVirtualCard::new();
|
||||
|
||||
let mut desfire = Desfire {
|
||||
card: Box::new(mock),
|
||||
cbc_iv: None,
|
||||
session_key: None
|
||||
};
|
||||
|
||||
desfire.read_data(0xFF, 0x00, 0x20).unwrap();
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user