use crate::card::{Card, Retries};
use crate::error::Result;
use crate::pin::Pin;
use crate::transport::Transmit;
pub const DF: [u8; 10] = [0xD3, 0x92, 0x10, 0x00, 0x31, 0x00, 0x01, 0x01, 0x04, 0x01];
pub mod ef {
pub const KEY_REFERENCE: u16 = 0x0002;
pub const PIN: u16 = 0x001C;
}
#[derive(Debug)]
pub struct JukiAp<'a, T> {
card: &'a mut Card<T>,
}
impl<'a, T: Transmit> JukiAp<'a, T> {
pub fn select(card: &'a mut Card<T>) -> Result<Self> {
card.select_df(&DF)?;
Ok(JukiAp { card })
}
pub fn card(&mut self) -> &mut Card<T> {
self.card
}
pub fn read_record(&mut self, id: u16, record: u8) -> Result<Vec<u8>> {
self.card.select_ef(id)?;
self.card.read_record(record)
}
pub fn verify_pin(&mut self, pin: &Pin) -> Result<()> {
self.card.select_ef(ef::PIN)?;
self.card.verify(pin)
}
pub fn change_pin(&mut self, current_pin: &Pin, new_pin: &Pin) -> Result<()> {
self.card.select_ef(ef::PIN)?;
self.card.verify(current_pin)?;
self.card.change_key(new_pin)
}
pub fn pin_retries(&mut self) -> Result<Retries> {
self.card.select_ef(ef::PIN)?;
self.card.pin_retries()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::transport::mock::MockTransport;
#[test]
fn changing_the_pin_uses_jicsap_change_key() {
let mut card = Card::new(MockTransport::new([
vec![0x90, 0x00], vec![0x90, 0x00], vec![0x90, 0x00], vec![0x90, 0x00], ]));
let mut juki = JukiAp::select(&mut card).unwrap();
juki.change_pin(
&Pin::numeric("1234").unwrap(),
&Pin::numeric("5678").unwrap(),
)
.unwrap();
assert_eq!(
card.transport().sent[1],
[0x00, 0xA4, 0x02, 0x0C, 0x02, 0x00, 0x1C]
);
assert_eq!(
card.transport().sent[3],
[0x80, 0x32, 0x00, 0x80, 0x04, b'5', b'6', b'7', b'8']
);
}
}