emv: parse track1&2 equivalent data (#2332)

* emv: parse track1&2 equivalent data
* emv: alternate expiry parser
* nfc: log EMV track1&2 data to trace output

Co-authored-by: gornekich <n.gorbadey@gmail.com>
Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Emily Trau 2023-01-27 16:10:08 +11:00 committed by GitHub
parent 8fc834090d
commit 4dc4d34d04
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 7 deletions

View file

@ -142,21 +142,44 @@ static bool emv_decode_response(uint8_t* buff, uint16_t len, EmvApplication* app
success = true; success = true;
FURI_LOG_T(TAG, "found EMV_TAG_AFL %x (len=%d)", tag, tlen); FURI_LOG_T(TAG, "found EMV_TAG_AFL %x (len=%d)", tag, tlen);
break; break;
case EMV_TAG_CARD_NUM: // Track 2 Equivalent Data. 0xD0 delimits PAN from expiry (YYMM) case EMV_TAG_TRACK_1_EQUIV: {
char track_1_equiv[80];
memcpy(track_1_equiv, &buff[i], tlen);
track_1_equiv[tlen] = '\0';
success = true;
FURI_LOG_T(TAG, "found EMV_TAG_TRACK_1_EQUIV %x : %s", tag, track_1_equiv);
break;
}
case EMV_TAG_TRACK_2_EQUIV: {
// 0xD0 delimits PAN from expiry (YYMM)
for(int x = 1; x < tlen; x++) { for(int x = 1; x < tlen; x++) {
if(buff[i + x + 1] > 0xD0) { if(buff[i + x + 1] > 0xD0) {
memcpy(app->card_number, &buff[i], x + 1); memcpy(app->card_number, &buff[i], x + 1);
app->card_number_len = x + 1; app->card_number_len = x + 1;
app->exp_year = (buff[i + x + 1] << 4) | (buff[i + x + 2] >> 4);
app->exp_month = (buff[i + x + 2] << 4) | (buff[i + x + 3] >> 4);
break; break;
} }
} }
// Convert 4-bit to ASCII representation
char track_2_equiv[41];
uint8_t track_2_equiv_len = 0;
for(int x = 0; x < tlen; x++) {
char top = (buff[i + x] >> 4) + '0';
char bottom = (buff[i + x] & 0x0F) + '0';
track_2_equiv[x * 2] = top;
track_2_equiv_len++;
if(top == '?') break;
track_2_equiv[x * 2 + 1] = bottom;
track_2_equiv_len++;
if(bottom == '?') break;
}
track_2_equiv[track_2_equiv_len] = '\0';
success = true; success = true;
FURI_LOG_T( FURI_LOG_T(TAG, "found EMV_TAG_TRACK_2_EQUIV %x : %s", tag, track_2_equiv);
TAG,
"found EMV_TAG_CARD_NUM %x (len=%d)",
EMV_TAG_CARD_NUM,
app->card_number_len);
break; break;
}
case EMV_TAG_PAN: case EMV_TAG_PAN:
memcpy(app->card_number, &buff[i], tlen); memcpy(app->card_number, &buff[i], tlen);
app->card_number_len = tlen; app->card_number_len = tlen;

View file

@ -11,7 +11,8 @@
#define EMV_TAG_CARD_NAME 0x50 #define EMV_TAG_CARD_NAME 0x50
#define EMV_TAG_FCI 0xBF0C #define EMV_TAG_FCI 0xBF0C
#define EMV_TAG_LOG_CTRL 0x9F4D #define EMV_TAG_LOG_CTRL 0x9F4D
#define EMV_TAG_CARD_NUM 0x57 #define EMV_TAG_TRACK_1_EQUIV 0x56
#define EMV_TAG_TRACK_2_EQUIV 0x57
#define EMV_TAG_PAN 0x5A #define EMV_TAG_PAN 0x5A
#define EMV_TAG_AFL 0x94 #define EMV_TAG_AFL 0x94
#define EMV_TAG_EXP_DATE 0x5F24 #define EMV_TAG_EXP_DATE 0x5F24