refactor(applet): retire AliroApplet INS_EXCHANGE stub
The stub was added earlier this session as an X-CUBE-ALIRO compat shim back when we (incorrectly) believed the vendor firmware ignored the §10.2 step-up AID SELECT requirement and routed EXCHANGE directly to the Expedited AID (ACCE5501). Today's Path X work proved the vendor firmware actually DOES the §10.2 SELECT correctly once the upstream crypto interop is right. With M1B.1 / M1C.1 now landing the real EXCHANGE and ENVELOPE handlers on StepUpApplet (ACCE5502), the AliroApplet stub is strictly wrong: it would let stale expedited_device_counter state confuse the vendor library if the reader ever hit it. Spec-conformant readers route EXCHANGE to ACCE5502 after the step-up SELECT and never touch ACCE5501 with INS=0xC9. So AliroApplet returns SW_INS_NOT_SUPPORTED (0x6D00) for INS=0xC9 like any other unknown INS, and we ship one less compat shim. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -33,7 +33,6 @@ public class AliroApplet extends Applet {
|
|||||||
private static final byte CLA_EXPEDITED = (byte) 0x80;
|
private static final byte CLA_EXPEDITED = (byte) 0x80;
|
||||||
private static final byte INS_AUTH0 = (byte) 0x80;
|
private static final byte INS_AUTH0 = (byte) 0x80;
|
||||||
private static final byte INS_AUTH1 = (byte) 0x81;
|
private static final byte INS_AUTH1 = (byte) 0x81;
|
||||||
private static final byte INS_EXCHANGE = (byte) 0xC9; // §8.3.3.5 / Table 8-14
|
|
||||||
|
|
||||||
// Diagnostic INSes (CLA=0x80) for profiling AUTH1 sub-operations.
|
// Diagnostic INSes (CLA=0x80) for profiling AUTH1 sub-operations.
|
||||||
// DEV / PERFORMANCE-DEBUG ONLY. Set DIAGNOSTICS_ENABLED = false for any
|
// DEV / PERFORMANCE-DEBUG ONLY. Set DIAGNOSTICS_ENABLED = false for any
|
||||||
@@ -521,34 +520,6 @@ public class AliroApplet extends Applet {
|
|||||||
case INS_AUTH1:
|
case INS_AUTH1:
|
||||||
processAuth1(apdu);
|
processAuth1(apdu);
|
||||||
return;
|
return;
|
||||||
case INS_EXCHANGE:
|
|
||||||
// EXCHANGE stub for the Reader Status sub-event variant of
|
|
||||||
// §8.3.3.5 -- the post-AUTH1 "transaction reporting" handshake
|
|
||||||
// X-CUBE-ALIRO always sends regardless of signaling_bitmap.
|
|
||||||
// We don't implement the Step-up phase (no CBOR / mdoc /
|
|
||||||
// ENVELOPE / GET RESPONSE), so we can't decrypt or honour the
|
|
||||||
// Reader Status payload. But returning 6D00 here makes the
|
|
||||||
// vendor firmware mark DOOR OPERATION FAILED even though
|
|
||||||
// AUTH1 succeeded (§10.2 line 5660 says the access decision
|
|
||||||
// SHOULD be independent of post-AUTH1 reporting -- vendor
|
|
||||||
// ignores that). So we ACK with 9000 + empty payload to let
|
|
||||||
// the demo terminate cleanly. Discards the inbound encrypted
|
|
||||||
// Reader Status bytes without parsing them; they're a
|
|
||||||
// status report the reader wanted to give us, not an access
|
|
||||||
// gate we need to satisfy.
|
|
||||||
//
|
|
||||||
// TODO (Step-Up impl): once StepUpApplet handles ENVELOPE /
|
|
||||||
// GET RESPONSE properly and signaling_bitmap honestly
|
|
||||||
// reflects capability, this stub becomes either dead code
|
|
||||||
// (spec-conformant readers route EXCHANGE to ACCE5502 after
|
|
||||||
// the step-up AID SELECT) or replaceable with a proper
|
|
||||||
// encrypted "Reader Status response sub-event" reply (for
|
|
||||||
// readers like X-CUBE-ALIRO that violate the §10.2 SHALL
|
|
||||||
// and bypass the step-up SELECT). See
|
|
||||||
// docs/plans/2026-06-07-step-up-implementation.md.
|
|
||||||
apdu.setIncomingAndReceive();
|
|
||||||
apdu.setOutgoingAndSend((short) 0, (short) 0);
|
|
||||||
return;
|
|
||||||
case INS_DIAG_HMAC:
|
case INS_DIAG_HMAC:
|
||||||
case INS_DIAG_ECDH:
|
case INS_DIAG_ECDH:
|
||||||
case INS_DIAG_ECDSA_SIGN:
|
case INS_DIAG_ECDSA_SIGN:
|
||||||
|
|||||||
@@ -92,4 +92,19 @@ class AliroAppletTest {
|
|||||||
assertEquals(0x01, versions[0] & 0xFF, "expected first protocol version high byte 0x01");
|
assertEquals(0x01, versions[0] & 0xFF, "expected first protocol version high byte 0x01");
|
||||||
assertEquals(0x00, versions[1] & 0xFF, "expected first protocol version low byte 0x00");
|
assertEquals(0x00, versions[1] & 0xFF, "expected first protocol version low byte 0x00");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void auth1ExchangeInsRejectedNowThatStepUpAppletOwnsIt() {
|
||||||
|
// Once M1B.1 / M1C.1 land StepUpApplet (ACCE5502) as the proper owner
|
||||||
|
// of INS_EXCHANGE (0xC9), AliroApplet must NOT also answer 0xC9 — a
|
||||||
|
// spec-conformant reader routes EXCHANGE to ACCE5502 after the §10.2
|
||||||
|
// step-up AID SELECT. AliroApplet receiving 0xC9 is a reader bug or
|
||||||
|
// a stale flow, and must be rejected with SW_INS_NOT_SUPPORTED so it
|
||||||
|
// can never accidentally interact with expedited session state.
|
||||||
|
selectExpedited();
|
||||||
|
CommandAPDU exchange = new CommandAPDU(0x80, 0xC9, 0x00, 0x00);
|
||||||
|
ResponseAPDU resp = sim.transmitCommand(exchange);
|
||||||
|
assertEquals(0x6D00, resp.getSW(),
|
||||||
|
"AliroApplet must reject INS_EXCHANGE (0xC9) — StepUpApplet (ACCE5502) owns it now");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user