Add some more inline documentation

This commit is contained in:
puck 2025-12-08 10:08:20 +00:00
parent c9e96b3260
commit bb8d954510

View file

@ -337,8 +337,8 @@ async fn run_auth(
)
.unwrap();
// We send a new SET AT along with a GENERAL AUTHENTICATE for internal/restricted identification.
// This has to be encrypted, for Reasons.
// Set up the first part of the terminal authentication:
// send a SET AT with reference id-TA-ECDSA-SHA-256.
let mut set_at_params = ca_info.0.as_bytes().to_vec();
prepend_do(&mut set_at_params, 0x80);
if let Some(v) = ca_info.1 {
@ -359,6 +359,11 @@ async fn run_auth(
let resp = enc_crad.transmit(new_apdu).await?;
assert_eq!(resp.status, 0x9000);
// Do a GENERAL AUTHENTICATE with all-0 parameters.
// This _seems_ to swap the ephemeral key we've been using to
// communicate with the card with that of the terminal's, and as side
// effect resets the session. Once this is transmitted, we can no
// longer communicate with the card in this session.
prepend_do(&mut remote_ephemeral_key_bytes, 0x80);
prepend_do(&mut remote_ephemeral_key_bytes, 0x7c);
let new_apdu = OwnedCommandAPDU {
@ -376,6 +381,19 @@ async fn run_auth(
assert_eq!(resp.status, 0x9000);
}
// The APDUs sent by the terminal are to be sent now.
// Because there's not a lot of documentation, here's what seems to be
// happening:
//
// 1. The card-verifiable certificate chain between the one in EF.CVCA and
// the certificate used by the terminal to authenticate are transmitted and
// verified (SET DST, plus VERIFY CERTIFICATE).
//
// 2. A SET AT is issued with the terminal's certificate's subject.
// 3. A GET CHALLENGE is issued to the card, with the response being
// shuttled back to the terminal.
//
// This part follows standard BSI TR-03110, if you want to take a look.
ctg_pipe
.send(pipe::CardToGUI::ProcessingMessage {
message: String::from("Running server-sent APDUs... (0/?)"),
@ -405,6 +423,27 @@ async fn run_auth(
.extend_from_slice(&last_response.status.to_be_bytes());
let apdus = ctx.prepare_pca(counter, &last_response.data).await;
// 1. The terminal uses the challenge, plus previously-cached information,
// to sign the challenge; this signature is sent back as a EXTERNAL
// AUTHENTICATE. The terminal is now authenticated.
//
// 2. The terminal transmits a SET AT, with an OID of { id-BSNk-scheme-nl 9
// 3 3 } (assuming a PIP). This is immediately followed by a GENERAL
// AUTHENTICATE, which has no parameters (TODO: check) and returns the
// polymorphic identity, as a CardPolymorph.
//
// A CardPolymorph is:
// - 0x80 Point0 (ECPoint)
// - 0x81 Point1 (ECPoint, optional)
// - 0x82 Point2 (ECPoint, optional)
// - 0x85 Scheme version (INTEGER)
// - 0x86 Scheme key version (INTEGER)
// - 0x87 Creator (BCD string)
// - 0x88 Recipient (BCD String)
// - 0x89 Recipient key set version (INTEGER)
// - 0x8a Type (INTEGER)
// - 0x8b Sequence number (BCD string)
let apdu_count = apdus.len() as isize + counter;
for apdu in apdus {
counter += 1;