mirror of
https://github.com/trussed-dev/piv-authenticator.git
synced 2026-06-20 04:16:15 -07:00
Remove outdated comments
This commit is contained in:
@@ -105,14 +105,10 @@ impl TryFrom<u8> for VerifyKeyReference {
|
||||
// then no other key reference shall be able to be verified by the PIV Card Application VERIFY command.
|
||||
match p2 {
|
||||
0x00 => Ok(Self::GlobalPin),
|
||||
// 0x00 => Err(Status::FunctionNotSupported),
|
||||
0x80 => Ok(Self::PivPin),
|
||||
0x96 => Ok(Self::PrimaryFingerOcc),
|
||||
0x97 => Ok(Self::SecondaryFingerOcc),
|
||||
0x98 => Ok(Self::PairingCode),
|
||||
// 0x96 => Err(Status::FunctionNotSupported),
|
||||
// 0x97 => Err(Status::FunctionNotSupported),
|
||||
// 0x98 => Err(Status::FunctionNotSupported),
|
||||
_ => Err(Status::KeyReferenceNotFound),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,139 +111,6 @@ pub const GET_DATA: (u8, u8, u8, u8) = (
|
||||
// 256,
|
||||
);
|
||||
|
||||
// SW (SP 800-73 Part 1, Table 6)
|
||||
// == == == == == == == == == == ==
|
||||
// 61, xx success, more response data bytes
|
||||
//
|
||||
// 63, 00 verification failed
|
||||
// 63, Cx verification failed, x furtehr retries or resets
|
||||
//
|
||||
// 68, 82 secure messaging not supported
|
||||
//
|
||||
// 69, 82 security status not satisfied
|
||||
// 69, 83 authn method blocked
|
||||
// : (more secure messaging stuff)
|
||||
//
|
||||
|
||||
//// ISO/IEC 7816-4, 5.1.3 "Status bytes"
|
||||
//#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
//pub enum StatusWord {
|
||||
|
||||
////////////////////////////////
|
||||
//// Normal processing (90, 61)
|
||||
////////////////////////////////
|
||||
|
||||
// // 9000
|
||||
// Success,
|
||||
|
||||
// // 61XX
|
||||
// MoreAvailable(u8),
|
||||
|
||||
/////////////////////////////////
|
||||
//// Warning processing (62, 63)
|
||||
/////////////////////////////////
|
||||
|
||||
// // 62XX: state of non-volatile memory unchanged (cf. SW2)
|
||||
|
||||
// // 63XX: state of non-volatile memory changed (cf. SW2)
|
||||
// VerificationFailed,
|
||||
// FailedRetries(u8),
|
||||
|
||||
//////////////////////////////////
|
||||
//// Execution error (64, 65, 66)
|
||||
//////////////////////////////////
|
||||
|
||||
// // 64XX: persistent memory unchanged (cf. SW2)
|
||||
// // 65XX: persistent memory changed (cf. SW2)
|
||||
// // 66XX: security related issues
|
||||
|
||||
/////////////////////////////////
|
||||
//// Checking error (67 - 6F)
|
||||
/////////////////////////////////
|
||||
|
||||
// // 6700: wrong length, no further indication
|
||||
|
||||
// // 68XX: functions in CLA not supported (cf. SW2)
|
||||
// SecureMessagingNotSupported,
|
||||
// CommandChainingNotSupported,
|
||||
|
||||
// // 69xx: command not allowed (cf. SW2)
|
||||
// SecurityStatusNotSatisfied,
|
||||
// OperationBlocked,
|
||||
|
||||
// // 6Axx: wrong parameters P1-P2 (cf. SW2)
|
||||
// IncorrectDataParameter,
|
||||
// FunctionNotSupported,
|
||||
// NotFound,
|
||||
// NotEnoughMemory,
|
||||
// IncorrectP1OrP2Parameter,
|
||||
// KeyReferenceNotFound,
|
||||
|
||||
// // 6BXX: wrong parameters P1-P2
|
||||
|
||||
// // 6CXX: wrong Le field, SW2 encodes available bytes
|
||||
|
||||
// // 6D00: instruction code not supported or invalid
|
||||
// InstructionNotSupportedOrInvalid,
|
||||
|
||||
// // 6E00: class not supported
|
||||
// ClassNotSupported,
|
||||
|
||||
// // 6F00: no precise diagnosis
|
||||
// UnspecifiedCheckingError,
|
||||
//}
|
||||
|
||||
//impl Into<u16> for StatusWord {
|
||||
// #[inline]
|
||||
// fn into(self) -> u16 {
|
||||
// match self {
|
||||
// Self::VerificationFailed => 0x6300,
|
||||
// Self::FailedRetries(x) => {
|
||||
// assert!(x < 16);
|
||||
// u16::from_be_bytes([0x63, 0xc0 + x])
|
||||
// }
|
||||
|
||||
// Self::SecureMessagingNotSupported => 0x6882,
|
||||
// Self::CommandChainingNotSupported => 0x6884,
|
||||
|
||||
// Self::SecurityStatusNotSatisfied => 0x6982,
|
||||
// Self::OperationBlocked => 0x6983,
|
||||
|
||||
// Self::IncorrectDataParameter => 0x6a80,
|
||||
// Self::FunctionNotSupported => 0x6a81,
|
||||
// Self::NotFound => 0x6a82,
|
||||
// Self::NotEnoughMemory => 0x6a84,
|
||||
// Self::IncorrectP1OrP2Parameter => 0x6a86,
|
||||
// Self::KeyReferenceNotFound => 0x6a88,
|
||||
|
||||
// Self::InstructionNotSupportedOrInvalid => 0x6d00,
|
||||
// Self::ClassNotSupported => 0x6e00,
|
||||
// Self::UnspecifiedCheckingError => 0x6f00,
|
||||
|
||||
// Self::Success => 0x9000,
|
||||
// Self::MoreAvailable(x) => u16::from_be_bytes([0x61, x]),
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
//impl Into<[u8; 2]> for StatusWord {
|
||||
// #[inline]
|
||||
// fn into(self) -> [u8; 2] {
|
||||
// let sw: u16 = self.into();
|
||||
// sw.to_be_bytes()
|
||||
// }
|
||||
//}
|
||||
|
||||
// 6A, 80 incorrect parameter in command data field
|
||||
// 6A, 81 function not supported
|
||||
// 6A, 82 data object not found ( = NOT FOUND for files, e.g. certificate, e.g. after GET-DATA)
|
||||
// 6A, 84 not enough memory
|
||||
// 6A, 86 incorrect parameter in P1/P2
|
||||
// 6A, 88 reference(d) data not found ( = NOT FOUND for keys, e.g. global PIN, e.g. after VERIFY)
|
||||
//
|
||||
// 90, 00 SUCCESS!
|
||||
// == == == == == == == == == == ==
|
||||
|
||||
// #[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub struct DataObjects {}
|
||||
#[allow(non_upper_case_globals)]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use core::convert::TryFrom;
|
||||
|
||||
use hex_literal::hex;
|
||||
// use flexiber::{Decodable, Encodable};
|
||||
|
||||
pub struct Tag<'a>(&'a [u8]);
|
||||
impl<'a> Tag<'a> {
|
||||
@@ -194,64 +193,3 @@ impl TryFrom<Tag<'_>> for Container {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// #[derive(Clone, Copy, PartialEq)]
|
||||
// pub struct CertInfo {
|
||||
// compressed: bool,
|
||||
// }
|
||||
|
||||
// impl From<CertInfo> for u8 {
|
||||
// fn from(cert_info: CertInfo) -> Self {
|
||||
// cert_info.compressed as u8
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl Encodable for CertInfo {
|
||||
// fn encoded_len(&self) -> der::Result<der::Length> {
|
||||
// Length::from(1)
|
||||
// }
|
||||
|
||||
// fn encode(&self, encoder: &mut Encoder<'_>) -> der::Result<()> {
|
||||
// encoder.encode(der::Any::new(0x71, &[u8::from(self)]))
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub struct Certificate<'a> {
|
||||
// // max bytes: 1856
|
||||
// certificate: &'a [u8], // tag: 0x70
|
||||
// // 1B
|
||||
// cert_info: CertInfo, // tag: 0x71
|
||||
// // 38
|
||||
// // mscuid: ?, // tag: 0x72
|
||||
// error_detection_code: [u8; 0], // tag: 0xFE
|
||||
// }
|
||||
|
||||
// impl Encodable for CertInfo {
|
||||
// fn encoded_len(&self) -> der::Result<der::Length> {
|
||||
// Length::from(1)
|
||||
// }
|
||||
|
||||
// fn encode(&self, encoder: &mut Encoder<'_>) -> der::Result<()> {
|
||||
// encoder.encode(der::Any::new(0x71, &[u8::from(self)]))
|
||||
// }
|
||||
// }
|
||||
|
||||
// #[derive(Encodable)]
|
||||
// pub struct DiscoveryObject<'a> {
|
||||
// #[tlv(tag = "0x4F")]
|
||||
// piv_card_application_aid: &'a [u8; 11], // tag: 0x4F, max bytes = 12,
|
||||
// #[tlv(tag = 0x5F2f)]
|
||||
// pin_usage_policy: [u8; 2], // tag: 0x5F2F, max bytes = 2,
|
||||
// }
|
||||
|
||||
// impl Encodable for CertInfo {
|
||||
// fn encoded_len(&self) -> der::Result<der::Length> {
|
||||
// Length::from(1)
|
||||
// }
|
||||
|
||||
// fn encode(&self, encoder: &mut Encoder<'_>) -> der::Result<()> {
|
||||
// encoder.encode(der::Any::new(0x71, &[u8::from(self)]))
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
-110
@@ -1,110 +0,0 @@
|
||||
pub enum Error {
|
||||
VerificationFailed { remaining: u8 }, // 63 00 or 63 CX
|
||||
SecureMessagingNotSupported, // 68 82
|
||||
SecurityStatusNotSatisfied, // 69 82
|
||||
AuthenticationMethodBlocked, // 69 83
|
||||
// ExpectedSecureMessagingDataObjectsMissing, // 69 87
|
||||
// SecureMessagingDataObjectsIncorrect, // 69 88
|
||||
IncorrectParameterInCommandDataField, // 6A 80
|
||||
FunctionNotSupported, // 6A 81
|
||||
DataObjectOrApplicationNotFound, // 6A 82
|
||||
NotEnoughMemory, // 6A 84
|
||||
IncorrecParameterInP1OrP2, // 6A 86
|
||||
ReferencedDataOrReferenceDataNotFound, // 6A 88
|
||||
}
|
||||
|
||||
pub enum Success {
|
||||
Success, // 61 xx
|
||||
SuccessResponseDataStillAvailable(u8), // 90 00
|
||||
}
|
||||
|
||||
pub type Result = core::result::Result<Success, Error>;
|
||||
|
||||
// macro_rules! status_word {
|
||||
// ($($Name:ident: [$sw1:expr, $sw2:tt],)*) => {
|
||||
// $(
|
||||
// // pub struct $Name {}
|
||||
|
||||
// status_word! ($Name, $sw1, $sw2);
|
||||
// )*
|
||||
|
||||
// pub enum StatusWord {
|
||||
// $($Name($Name),)*
|
||||
// }
|
||||
// };
|
||||
|
||||
// ($Name:ident, $sw1:expr, XX) => {
|
||||
// pub struct $Name {
|
||||
// sw2: u8,
|
||||
// }
|
||||
|
||||
// impl $Name {
|
||||
// const SW1: u8 = $sw1;
|
||||
|
||||
// pub fn new(sw2: u8) -> Self {
|
||||
// Self { sw2 }
|
||||
// }
|
||||
|
||||
// pub fn as_bytes(&self) -> [u8; 2] {
|
||||
// [Self::SW1, self.sw2]
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
// // impl core::ops::Deref for $Name {
|
||||
// // type Target = [u8; 2];
|
||||
// // fn deref(&self) -> &Self::Target {
|
||||
// // &[Self::SW1, self.sw2]
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// };
|
||||
|
||||
// ($Name:ident, $sw1:expr, $sw2:expr) => {
|
||||
// #[derive(Default)]
|
||||
// pub struct $Name {}
|
||||
|
||||
// impl $Name {
|
||||
// const SW1: u8 = $sw1;
|
||||
// const SW2: u8 = $sw2;
|
||||
|
||||
// pub fn new() -> Self {
|
||||
// Default::default()
|
||||
// }
|
||||
|
||||
// pub fn as_bytes(&self) -> [u8; 2] {
|
||||
// [Self::SW1, Self::SW2]
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// }
|
||||
|
||||
// status_word! {
|
||||
// SecurityStatusNotSatisfied: [0x69, 0x82],
|
||||
// NotFound: [0x6a, 0x82],
|
||||
// Success: [0x90, 0x00],
|
||||
|
||||
// SuccessBytesRemaining: [0x61, XX ],
|
||||
// }
|
||||
|
||||
// pub trait StatusWordTrait {
|
||||
// fn sw1(&self) -> u8;
|
||||
// fn sw2(&self) -> u8;
|
||||
//
|
||||
// fn sw(&self) -> [u8; 2] {
|
||||
// [self.sw1(), self.sw2()]
|
||||
// }
|
||||
// }
|
||||
|
||||
// #[cfg(test)]
|
||||
// mod tests {
|
||||
// use super::*;
|
||||
|
||||
// #[test]
|
||||
// fn deref() {
|
||||
// let sw = SuccessBytesRemaining::new(42);
|
||||
// println!("SW: {:?}", &sw.as_bytes());
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
-228
@@ -197,87 +197,6 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// pub fn old_respond(&mut self, command: &iso7816::Command<C>, reply: &mut Data<R>) -> Result {
|
||||
|
||||
// // TEMP
|
||||
// // blocking::dbg!(self.state.persistent(&mut self.trussed).timestamp(&mut self.trussed));
|
||||
|
||||
// // handle CLA
|
||||
// // - command chaining not supported
|
||||
// // - secure messaging not supported
|
||||
// // - only channel zero supported
|
||||
// // - ensure INS known to us
|
||||
|
||||
// let last_or_only = command.class().chain().last_or_only();
|
||||
|
||||
// // TODO: avoid owned copy?
|
||||
// let owned_command = match self.state.runtime.chained_command.as_mut() {
|
||||
// Some(command_so_far) => {
|
||||
// // TODO: make sure the prefix matches, e.g. '00 DB 3F FF'
|
||||
// command_so_far.data_mut().extend_from_slice(command.data()).unwrap();
|
||||
|
||||
// if last_or_only {
|
||||
// let total_command = command_so_far.clone();
|
||||
// self.state.runtime.chained_command = None;
|
||||
// total_command
|
||||
// } else {
|
||||
// return Ok(Default::default());
|
||||
// }
|
||||
// }
|
||||
|
||||
// None => {
|
||||
// if last_or_only {
|
||||
// // iso7816::Command<C>
|
||||
// command.clone()
|
||||
// } else {
|
||||
// self.state.runtime.chained_command = Some(command.clone());
|
||||
// return Ok(Default::default());
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
// let command = &owned_command;
|
||||
|
||||
// let class = command.class();
|
||||
|
||||
// if !class.secure_messaging().none() {
|
||||
// return Err(Status::SecureMessagingNotSupported);
|
||||
// }
|
||||
|
||||
// if class.channel() != Some(0) {
|
||||
// return Err(Status::LogicalChannelNotSupported);
|
||||
// }
|
||||
|
||||
// // info!("CLA = {:?}", &command.class());
|
||||
// info!("INS = {:?}, P1 = {:X}, P2 = {:X}",
|
||||
// &command.instruction(),
|
||||
// command.p1, command.p2,
|
||||
// );
|
||||
// // info!("extended = {:?}", command.extended);
|
||||
|
||||
// // info!("INS = {:?}" &command.instruction());
|
||||
// match command.instruction() {
|
||||
// Instruction::GetData => self.get_data(command, reply),
|
||||
// Instruction::PutData => self.put_data(command),
|
||||
// Instruction::Verify => panic!(),//self.old_verify(command),
|
||||
// Instruction::ChangeReferenceData => panic!(),//self.change_reference_data(command),
|
||||
// Instruction::GeneralAuthenticate => self.general_authenticate(command, reply),
|
||||
// Instruction::GenerateAsymmetricKeyPair => self.generate_asymmetric_keypair(command, reply),
|
||||
|
||||
// Instruction::Unknown(ins) => {
|
||||
|
||||
// // see if it's a Yubico thing
|
||||
// if let Ok(instruction) = YubicoPivExtension::try_from(ins) {
|
||||
// self.yubico_piv_extension(command, instruction, reply)
|
||||
// } else {
|
||||
// Err(Status::FunctionNotSupported)
|
||||
// }
|
||||
// }
|
||||
|
||||
// _ => Err(Status::FunctionNotSupported),
|
||||
// }
|
||||
// }
|
||||
|
||||
// SP 800-73-4, Part 2, Section 3.2.4
|
||||
// https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-73-4.pdf#page=92
|
||||
//
|
||||
@@ -530,153 +449,6 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
//fn change_reference_data(&mut self, command: &Command) -> Result {
|
||||
// // The way `piv-go` blocks PUK (which it needs to do because Yubikeys only
|
||||
// // allow their Reset if PIN+PUK are blocked) is that it sends "change PUK"
|
||||
// // with random (i.e. incorrect) PUK listed as both old and new PUK.
|
||||
// //
|
||||
// // 00 24 00 81 10
|
||||
// // 32 38 36 34 31 39 30 36 32 38 36 34 31 39 30 36
|
||||
// //
|
||||
// // For now, we don't support PUK, so we can just return "Blocked" directly
|
||||
// // if the key reference in P2 is '81' = PUK
|
||||
|
||||
// // application PIN
|
||||
// if command.p2 == 0x80 {
|
||||
// let remaining_retries = self.state.persistent(&mut self.trussed).remaining_pin_retries();
|
||||
|
||||
// if remaining_retries == 0 {
|
||||
// return Err(Status::OperationBlocked);
|
||||
// }
|
||||
|
||||
// if command.data().len() != 16 {
|
||||
// return Err(Status::IncorrectDataParameter);
|
||||
// }
|
||||
|
||||
// let (old_pin, new_pin) = command.data().split_at(8);
|
||||
|
||||
// let old_pin = match state::Pin::try_new(old_pin) {
|
||||
// Ok(pin) => pin,
|
||||
// _ => return Err(Status::IncorrectDataParameter),
|
||||
// };
|
||||
|
||||
// let new_pin = match state::Pin::try_new(new_pin) {
|
||||
// Ok(pin) => pin,
|
||||
// _ => return Err(Status::IncorrectDataParameter),
|
||||
// };
|
||||
|
||||
// if !self.state.persistent(&mut self.trussed).verify_pin(&old_pin) {
|
||||
// let remaining = self.state.persistent(&mut self.trussed).increment_consecutive_pin_mismatches(&mut self.trussed);
|
||||
// self.state.runtime.app_security_status.pin_verified = false;
|
||||
// return Err(Status::RemainingRetries(remaining));
|
||||
// }
|
||||
|
||||
// self.state.persistent(&mut self.trussed).reset_consecutive_pin_mismatches(&mut self.trussed);
|
||||
// self.state.persistent(&mut self.trussed).set_pin(&mut self.trussed, new_pin);
|
||||
// self.state.runtime.app_security_status.pin_verified = true;
|
||||
// return Ok(());
|
||||
// }
|
||||
|
||||
// // PUK
|
||||
// if command.p2 == 0x81 {
|
||||
// let remaining_retries = self.state.persistent(&mut self.trussed).remaining_puk_retries();
|
||||
|
||||
// if remaining_retries == 0 {
|
||||
// return Err(Status::OperationBlocked);
|
||||
// }
|
||||
|
||||
// if command.data().len() != 16 {
|
||||
// return Err(Status::IncorrectDataParameter);
|
||||
// }
|
||||
|
||||
// let (old_puk, new_puk) = command.data().split_at(8);
|
||||
|
||||
// let old_puk = match state::Pin::try_new(old_puk) {
|
||||
// Ok(puk) => puk,
|
||||
// _ => return Err(Status::IncorrectDataParameter),
|
||||
// };
|
||||
|
||||
// let new_puk = match state::Pin::try_new(new_puk) {
|
||||
// Ok(puk) => puk,
|
||||
// _ => return Err(Status::IncorrectDataParameter),
|
||||
// };
|
||||
|
||||
// if !self.state.persistent(&mut self.trussed).verify_puk(&old_puk) {
|
||||
// let remaining = self.state.persistent(&mut self.trussed).increment_consecutive_puk_mismatches(&mut self.trussed);
|
||||
// self.state.runtime.app_security_status.puk_verified = false;
|
||||
// return Err(Status::RemainingRetries(remaining));
|
||||
// }
|
||||
|
||||
// self.state.persistent(&mut self.trussed).reset_consecutive_puk_mismatches(&mut self.trussed);
|
||||
// self.state.persistent(&mut self.trussed).set_puk(&mut self.trussed, new_puk);
|
||||
// self.state.runtime.app_security_status.puk_verified = true;
|
||||
// return Ok(());
|
||||
// }
|
||||
|
||||
// Err(Status::KeyReferenceNotFound)
|
||||
//}
|
||||
|
||||
//fn old_verify(&mut self, command: &Command) -> Result {
|
||||
// // we only implement our own PIN, not global Pin, not OCC data, not pairing code
|
||||
// if command.p2 != 0x80 {
|
||||
// return Err(Status::KeyReferenceNotFound);
|
||||
// }
|
||||
|
||||
// let p1 = command.p1;
|
||||
// if p1 != 0x00 && p1 != 0xFF {
|
||||
// return Err(Status::IncorrectP1OrP2Parameter);
|
||||
// }
|
||||
|
||||
// // all above failures shall not change security status or retry counter
|
||||
|
||||
// // 1) If p1 is FF, "log out" of PIN
|
||||
// if p1 == 0xFF {
|
||||
// if command.data().len() != 0 {
|
||||
// return Err(Status::IncorrectDataParameter);
|
||||
// } else {
|
||||
// self.state.runtime.app_security_status.pin_verified = false;
|
||||
// return Ok(());
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 2) Get retries (or whether verification is even needed) by passing no data
|
||||
// if p1 == 0x00 && command.data().len() == 0 {
|
||||
// if self.state.runtime.app_security_status.pin_verified {
|
||||
// return Ok(());
|
||||
// } else {
|
||||
// let retries = self.state.persistent(&mut self.trussed).remaining_pin_retries();
|
||||
// return Err(Status::RemainingRetries(retries));
|
||||
// }
|
||||
// }
|
||||
|
||||
// // if malformed PIN is sent, no security implication
|
||||
// if command.data().len() != 8 {
|
||||
// return Err(Status::IncorrectDataParameter);
|
||||
// }
|
||||
|
||||
// let sent_pin = match state::Pin::try_new(&command.data()) {
|
||||
// Ok(pin) => pin,
|
||||
// _ => return Err(Status::IncorrectDataParameter),
|
||||
// };
|
||||
|
||||
// // 3) Verify le PIN!
|
||||
// let remaining_retries = self.state.persistent(&mut self.trussed).remaining_pin_retries();
|
||||
// if remaining_retries == 0 {
|
||||
// return Err(Status::OperationBlocked);
|
||||
// }
|
||||
|
||||
// if self.state.persistent(&mut self.trussed).verify_pin(&sent_pin) {
|
||||
// self.state.persistent(&mut self.trussed).reset_consecutive_pin_mismatches(&mut self.trussed);
|
||||
// self.state.runtime.app_security_status.pin_verified = true;
|
||||
// Ok(())
|
||||
|
||||
// } else {
|
||||
// let remaining = self.state.persistent(&mut self.trussed).increment_consecutive_pin_mismatches(&mut self.trussed);
|
||||
// self.state.runtime.app_security_status.pin_verified = false;
|
||||
// Err(Status::RemainingRetries(remaining))
|
||||
// }
|
||||
//}
|
||||
|
||||
pub fn generate_asymmetric_keypair<const R: usize>(
|
||||
&mut self,
|
||||
command: &iso7816::Command<C>,
|
||||
|
||||
@@ -305,23 +305,6 @@ pub struct CardHolderUniqueIdentifier<'l> {
|
||||
error_detection_code: [u8; 0],
|
||||
}
|
||||
|
||||
// #[derive(Decodable, Encodable)]
|
||||
// #[tlv(application, number = "0x13")]
|
||||
// pub struct CardHolderUniqueIdentifier {
|
||||
// #[tlv(slice, simple = "0x30")]
|
||||
// fasc_n: [u8; 25],
|
||||
// // #[tlv(slice, simple = "0x33")]
|
||||
// // duns: [u8; 9],
|
||||
// #[tlv(slice, simple = "0x34")]
|
||||
// guid: [u8; 16],
|
||||
// #[tlv(slice, simple = "0x35")]
|
||||
// expiration_date: [u8; 8], // YYYYMMDD
|
||||
// #[tlv(slice, simple = "0x3E")]
|
||||
// issuer_asymmetric_signature: [u8; 1],
|
||||
// #[tlv(slice, simple = "0xFE")]
|
||||
// error_detection_code: [u8; 0],
|
||||
// }
|
||||
|
||||
/// Corresponds to bit string in CBD (see https://www.idmanagement.gov/docs/pacs-tig-scepacs.pdf)
|
||||
/// 11010_10011_10011_10011_10011_10110_00001_00001_00001_00001
|
||||
/// 10110_00001_00001_00001_00001_00001_00001_10110_00001_10110
|
||||
|
||||
@@ -172,46 +172,6 @@ impl<const C: usize> State<C> {
|
||||
}
|
||||
}
|
||||
|
||||
// #[derive(Clone, Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
|
||||
// pub struct Pin {
|
||||
// // padded_pin: [u8; 8]
|
||||
// pin: heapless_bytes::Bytes<heapless::consts::U8>,
|
||||
// }
|
||||
|
||||
// impl Default for Pin {
|
||||
// /// Default is "202020"
|
||||
// /// But right now we have to use "123456" cause.. Filo
|
||||
// fn default() -> Self {
|
||||
// // Self::try_new(b"202020\xff\xff").unwrap()
|
||||
// Self::try_new(b"123456\xff\xff").unwrap()
|
||||
// }
|
||||
// }
|
||||
|
||||
// impl Pin {
|
||||
// pub fn try_new(padded_pin: &[u8]) -> Result<Self> {
|
||||
// if padded_pin.len() != 8 {
|
||||
// return Err(());
|
||||
// }
|
||||
// let first_pad_byte = padded_pin.iter().position(|&b| b == 0xff);
|
||||
// let unpadded_pin = match first_pad_byte {
|
||||
// Some(l) => &padded_pin[..l],
|
||||
// None => padded_pin,
|
||||
// };
|
||||
// if unpadded_pin.len() < 6 {
|
||||
// return Err(());
|
||||
// }
|
||||
// let valid_bytes = unpadded_pin.iter().all(|&b| b >= b'0' && b <= b'9');
|
||||
// if valid_bytes {
|
||||
// Ok(Self {
|
||||
// // padded_pin: padded_pin.try_into().unwrap(),
|
||||
// pin: Bytes::from_slice(padded_pin).unwrap(),//padded_pin.try_into().unwrap(),
|
||||
// })
|
||||
// } else {
|
||||
// Err(())
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, serde::Deserialize, serde::Serialize)]
|
||||
pub struct PersistentState {
|
||||
pub keys: Keys,
|
||||
|
||||
Reference in New Issue
Block a user