pub const DEFAULT_ATR: &[u8] = &[
0x3B, 0x88, 0x01, 0x00, 0x73, 0x00, 0x00, 0xE0, 0x05, 0x90, 0x00, 0x8F, ];
pub const SIMPLE_ATR: &[u8] = &[
0x3B, 0x80, 0x80, 0x01, 0x01, ];
pub fn build_atr(historical_bytes: &[u8]) -> Vec<u8> {
let mut atr = Vec::with_capacity(32);
atr.push(0x3B);
let hist_len = historical_bytes.len().min(15) as u8;
atr.push(0x80 | hist_len);
atr.push(0x01);
atr.extend_from_slice(&historical_bytes[..hist_len as usize]);
let tck: u8 = atr[1..].iter().fold(0u8, |acc, &b| acc ^ b);
atr.push(tck);
atr
}
pub fn create_openpgp_atr() -> Vec<u8> {
let historical = [
0x00, 0x73, 0x00, 0x00, 0xE0, 0x05, 0x90, 0x00, ];
build_atr(&historical)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_atr() {
assert_eq!(DEFAULT_ATR[0], 0x3B);
assert!(DEFAULT_ATR.len() >= 4);
assert!(DEFAULT_ATR.len() <= 33);
}
#[test]
fn test_build_atr() {
let hist = [0x01, 0x02, 0x03, 0x04];
let atr = build_atr(&hist);
assert_eq!(atr[0], 0x3B); assert_eq!(atr[1] & 0x0F, 4); assert_eq!(&atr[3..7], &hist); }
#[test]
fn test_create_openpgp_atr() {
let atr = create_openpgp_atr();
assert_eq!(atr[0], 0x3B);
assert!(atr.windows(2).any(|w| w == [0x90, 0x00]));
}
#[test]
fn test_atr_checksum() {
let hist = [0x00, 0x73, 0x00, 0x00];
let atr = build_atr(&hist);
let calculated_tck: u8 = atr[1..atr.len() - 1].iter().fold(0u8, |acc, &b| acc ^ b);
assert_eq!(atr[atr.len() - 1], calculated_tck);
}
}