From 65e08db86550dba51ec7152d81c74282e16a4b8b Mon Sep 17 00:00:00 2001 From: Arpit Jain Date: Sun, 13 Sep 2026 13:53:14 -0400 Subject: [PATCH] Sort EMV applications by the priority indicator, not the AID GetCardTokenAID reads both the AID (tag 0x4F) and the Application Priority Indicator (tag 0x87), validates that the priority node exists and is exactly one byte, and then pushes the first byte of the AID as the sort key. So aidPriorityNode is fetched and length-checked and never dereferenced; grep finds it on only three lines, all of them above the push. The key actually used is the AID's first byte, which on essentially every EMV card is 0xA0, the registered application provider prefix, so every key collapses to the same value and the card's stated priorities never enter the sort. EMV Book 1 section 12.4 makes the priority indicator the thing that orders candidate applications. On a multi-application card the keyfile is currently derived from a different application than the card designates. Signed-off-by: Arpit Jain --- src/Common/EMVCard.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Common/EMVCard.cpp b/src/Common/EMVCard.cpp index 59dc3cf049..b9fe745cc7 100644 --- a/src/Common/EMVCard.cpp +++ b/src/Common/EMVCard.cpp @@ -286,7 +286,10 @@ namespace VeraCrypt if (aidNode && aidNode->Value->size() > 0 && aidPriorityNode && aidPriorityNode->Value->size() == 1) { supportedAIDs.push_back(*aidNode->Value.get()); - supportedAIDsPriorities.push_back(aidNode->Value->at(0)); + // Sort on the Application Priority Indicator, which the line above + // already required to be exactly one byte. Using the AID's first + // byte collapsed every key to 0xA0, the registered provider prefix. + supportedAIDsPriorities.push_back(aidPriorityNode->Value->at(0)); } } for(size_t i = 0; i < supportedAIDs.size(); i++)