Przeglądaj źródła

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>
Emily Trau 3 lat temu
rodzic
commit
4dc4d34d04
2 zmienionych plików z 31 dodań i 7 usunięć
  1. 29 6
      lib/nfc/protocols/emv.c
  2. 2 1
      lib/nfc/protocols/emv.h

+ 29 - 6
lib/nfc/protocols/emv.c

@@ -142,21 +142,44 @@ static bool emv_decode_response(uint8_t* buff, uint16_t len, EmvApplication* app
                 success = true;
                 FURI_LOG_T(TAG, "found EMV_TAG_AFL %x (len=%d)", tag, tlen);
                 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++) {
                     if(buff[i + x + 1] > 0xD0) {
                         memcpy(app->card_number, &buff[i], 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;
                     }
                 }
+
+                // 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;
-                FURI_LOG_T(
-                    TAG,
-                    "found EMV_TAG_CARD_NUM %x (len=%d)",
-                    EMV_TAG_CARD_NUM,
-                    app->card_number_len);
+                FURI_LOG_T(TAG, "found EMV_TAG_TRACK_2_EQUIV %x : %s", tag, track_2_equiv);
                 break;
+            }
             case EMV_TAG_PAN:
                 memcpy(app->card_number, &buff[i], tlen);
                 app->card_number_len = tlen;

+ 2 - 1
lib/nfc/protocols/emv.h

@@ -11,7 +11,8 @@
 #define EMV_TAG_CARD_NAME 0x50
 #define EMV_TAG_FCI 0xBF0C
 #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_AFL 0x94
 #define EMV_TAG_EXP_DATE 0x5F24