Handle PIN failures

This commit is contained in:
puck 2025-12-08 11:18:22 +00:00
parent bb8d954510
commit 3636245aa7
7 changed files with 127 additions and 84 deletions

View file

@ -157,74 +157,88 @@ async fn run_auth(
break crad;
};
// Select the PCA application
iso7816::select(
&mut crad,
0,
iso7816::SelectFile::DedicatedFileName(&[
0xA0, 0x00, 0x00, 0x07, 0x88, 0x50, 0x43, 0x41, 0x2D, 0x65, 0x4D, 0x52, 0x54, 0x44,
]),
iso7816::SelectOccurrence::First,
)
.await?;
let creds = loop {
// Select the PCA application
iso7816::select(
&mut crad,
0,
iso7816::SelectFile::DedicatedFileName(&[
0xA0, 0x00, 0x00, 0x07, 0x88, 0x50, 0x43, 0x41, 0x2D, 0x65, 0x4D, 0x52, 0x54, 0x44,
]),
iso7816::SelectOccurrence::First,
)
.await?;
// Select _its_ MF (what?)
iso7816::select(
&mut crad,
0,
iso7816::SelectFile::File(&[]),
iso7816::SelectOccurrence::First,
)
.await?;
// Select _its_ MF (what?)
iso7816::select(
&mut crad,
0,
iso7816::SelectFile::File(&[]),
iso7816::SelectOccurrence::First,
)
.await?;
iso7816::select(
&mut crad,
0,
iso7816::files::EF_CARDACCESS,
iso7816::SelectOccurrence::First,
)
.await?;
let ef_cardaccess_bytes = iso7816::read_binary(&mut crad, 0).await?.unwrap();
let ef_cardaccess = pace::SecurityInfos::from_der(&ef_cardaccess_bytes).unwrap();
iso7816::select(
&mut crad,
0,
iso7816::files::EF_CARDACCESS,
iso7816::SelectOccurrence::First,
)
.await?;
let ef_cardaccess_bytes = iso7816::read_binary(&mut crad, 0).await?.unwrap();
let ef_cardaccess = pace::SecurityInfos::from_der(&ef_cardaccess_bytes).unwrap();
let status = pace::set_authentication_template(
&mut crad,
ef_cardaccess.get(0).unwrap().protocol,
pace::PasswordType::PIN,
)
.await?;
let (msg, can_continue) = match status {
pace::PACEStatus::Okay => (None, true),
pace::PACEStatus::TriesLeft(n) => (Some(format!("{} tries left", n)), true),
pace::PACEStatus::Error(unk) => (Some(format!("Unknown error {:04x}", unk)), false),
pace::PACEStatus::PasswordSuspended => (Some("PIN suspended. Use app.".to_string()), false),
pace::PACEStatus::PasswordBlocked => (Some("PIN blocked. Use app.".to_string()), false),
};
let (msg, can_continue) = match pace::set_authentication_template(
&mut crad,
ef_cardaccess.get(0).unwrap().protocol,
pace::PasswordType::PIN,
)
.await
{
Ok(()) => (None, true),
Err(pace::PACEStatus::CardError(e)) => return Err(e),
Err(pace::PACEStatus::TriesLeft(n)) => (Some(format!("{} tries left", n)), true),
Err(pace::PACEStatus::Error(unk)) => {
(Some(format!("Unknown error {:04x}", unk)), false)
}
Err(pace::PACEStatus::PasswordSuspended) => {
(Some("PIN suspended. Use app.".to_string()), false)
}
Err(pace::PACEStatus::PasswordBlocked) => {
(Some("PIN blocked. Use app.".to_string()), false)
}
};
if can_continue {
ctg_pipe
.send(pipe::CardToGUI::ReadyForPIN { message: msg })
.await;
} else {
if can_continue {
ctg_pipe
.send(pipe::CardToGUI::ReadyForPIN { message: msg })
.await;
} else {
ctg_pipe
.send(pipe::CardToGUI::ProcessingMessage {
message: msg.unwrap(),
})
.await;
}
let GUIToCard::PIN(pin) = gtc_pipe.recv().await.unwrap();
ctg_pipe
.send(pipe::CardToGUI::ProcessingMessage {
message: msg.unwrap(),
message: String::from("Negotiating with the card..."),
})
.await;
}
let GUIToCard::PIN(pin) = gtc_pipe.recv().await.unwrap();
ctg_pipe
.send(pipe::CardToGUI::ProcessingMessage {
message: String::from("Negotiating with the card..."),
})
.await;
let creds = pace::authenticate_pin(
&mut crad,
pin.as_bytes(),
ef_cardaccess.get(0).unwrap().protocol,
)
.await?;
match pace::authenticate_pin(
&mut crad,
pin.as_bytes(),
ef_cardaccess.get(0).unwrap().protocol,
)
.await
{
Ok(creds) => break creds,
Err(pace::PACEStatus::CardError(n)) => return Err(n),
_ => (),
}
};
let apdus;