Add some more inline documentation
This commit is contained in:
parent
c9e96b3260
commit
bb8d954510
43
src/main.rs
43
src/main.rs
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue