]>
git.zerfleddert.de Git - proxmark3-svn/blob - client/emv/emvcore.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2017 Merlok
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
7 //-----------------------------------------------------------------------------
9 //-----------------------------------------------------------------------------
13 #include "util_posix.h"
15 // Got from here. Thanks)
16 // https://eftlab.co.uk/index.php/site-map/knowledge-base/211-emv-aid-rid-pix
17 static const char *PSElist
[] = {
18 "325041592E5359532E4444463031", // 2PAY.SYS.DDF01 - Visa Proximity Payment System Environment - PPSE
19 "315041592E5359532E4444463031" // 1PAY.SYS.DDF01 - Visa Payment System Environment - PSE
21 //static const size_t PSElistLen = sizeof(PSElist)/sizeof(char*);
23 char *TransactionTypeStr
[] = {
31 enum CardPSVendor vendor
;
35 static const TAIDList AIDlist
[] = {
37 { CV_VISA
, "A00000000305076010"}, // VISA ELO Credit
38 { CV_VISA
, "A0000000031010" }, // VISA Debit/Credit (Classic)
39 { CV_VISA
, "A000000003101001" }, // VISA Credit
40 { CV_VISA
, "A000000003101002" }, // VISA Debit
41 { CV_VISA
, "A0000000032010" }, // VISA Electron
42 { CV_VISA
, "A0000000032020" }, // VISA
43 { CV_VISA
, "A0000000033010" }, // VISA Interlink
44 { CV_VISA
, "A0000000034010" }, // VISA Specific
45 { CV_VISA
, "A0000000035010" }, // VISA Specific
46 { CV_VISA
, "A0000000036010" }, // Domestic Visa Cash Stored Value
47 { CV_VISA
, "A0000000036020" }, // International Visa Cash Stored Value
48 { CV_VISA
, "A0000000038002" }, // VISA Auth, VisaRemAuthen EMV-CAP (DPA)
49 { CV_VISA
, "A0000000038010" }, // VISA Plus
50 { CV_VISA
, "A0000000039010" }, // VISA Loyalty
51 { CV_VISA
, "A000000003999910" }, // VISA Proprietary ATM
53 { CV_VISA
, "A000000098" }, // Debit Card
54 { CV_VISA
, "A0000000980848" }, // Debit Card
55 // Mastercard International
56 { CV_MASTERCARD
, "A00000000401" }, // MasterCard PayPass
57 { CV_MASTERCARD
, "A0000000041010" }, // MasterCard Credit
58 { CV_MASTERCARD
, "A00000000410101213" }, // MasterCard Credit
59 { CV_MASTERCARD
, "A00000000410101215" }, // MasterCard Credit
60 { CV_MASTERCARD
, "A0000000042010" }, // MasterCard Specific
61 { CV_MASTERCARD
, "A0000000043010" }, // MasterCard Specific
62 { CV_MASTERCARD
, "A0000000043060" }, // Maestro (Debit)
63 { CV_MASTERCARD
, "A000000004306001" }, // Maestro (Debit)
64 { CV_MASTERCARD
, "A0000000044010" }, // MasterCard Specific
65 { CV_MASTERCARD
, "A0000000045010" }, // MasterCard Specific
66 { CV_MASTERCARD
, "A0000000046000" }, // Cirrus
67 { CV_MASTERCARD
, "A0000000048002" }, // SecureCode Auth EMV-CAP
68 { CV_MASTERCARD
, "A0000000049999" }, // MasterCard PayPass
70 { CV_AMERICANEXPRESS
, "A000000025" },
71 { CV_AMERICANEXPRESS
, "A0000000250000" },
72 { CV_AMERICANEXPRESS
, "A00000002501" },
73 { CV_AMERICANEXPRESS
, "A000000025010402" },
74 { CV_AMERICANEXPRESS
, "A000000025010701" },
75 { CV_AMERICANEXPRESS
, "A000000025010801" },
76 // Groupement des Cartes Bancaires "CB"
77 { CV_CB
, "A0000000421010" }, // Cartes Bancaire EMV Card
78 { CV_CB
, "A0000000422010" },
79 { CV_CB
, "A0000000423010" },
80 { CV_CB
, "A0000000424010" },
81 { CV_CB
, "A0000000425010" },
83 { CV_JCB
, "A00000006510" }, // JCB
84 { CV_JCB
, "A0000000651010" }, // JCB J Smart Credit
86 { CV_OTHER
, "A0000001544442" }, // Banricompras Debito - Banrisul - Banco do Estado do Rio Grande do SUL - S.A.
87 { CV_OTHER
, "F0000000030001" }, // BRADESCO
88 { CV_OTHER
, "A0000005241010" }, // RuPay - RuPay
89 { CV_OTHER
, "D5780000021010" } // Bankaxept - Bankaxept
91 static const size_t AIDlistLen
= sizeof(AIDlist
)/sizeof(TAIDList
);
93 static bool APDULogging
= false;
94 void SetAPDULogging(bool logging
) {
95 APDULogging
= logging
;
98 enum CardPSVendor
GetCardPSVendor(uint8_t * AID
, size_t AIDlen
) {
103 hex_to_buffer((uint8_t *)buf
, AID
, AIDlen
, sizeof(buf
) - 1, 0, 0, true);
105 for(int i
= 0; i
< AIDlistLen
; i
++) {
106 if (strncmp(AIDlist
[i
].aid
, buf
, strlen(AIDlist
[i
].aid
)) == 0){
107 return AIDlist
[i
].vendor
;
114 static bool print_cb(void *data
, const struct tlv
*tlv
, int level
, bool is_leaf
) {
115 emv_tag_dump(tlv
, stdout
, level
);
117 dump_buffer(tlv
->value
, tlv
->len
, stdout
, level
);
123 void TLVPrintFromBuffer(uint8_t *data
, int datalen
) {
124 struct tlvdb
*t
= NULL
;
125 t
= tlvdb_parse_multi(data
, datalen
);
127 PrintAndLog("-------------------- TLV decoded --------------------");
129 tlvdb_visit(t
, print_cb
, NULL
, 0);
132 PrintAndLog("TLV ERROR: Can't parse response as TLV tree.");
136 void TLVPrintFromTLVLev(struct tlvdb
*tlv
, int level
) {
140 tlvdb_visit(tlv
, print_cb
, NULL
, level
);
143 void TLVPrintFromTLV(struct tlvdb
*tlv
) {
144 TLVPrintFromTLVLev(tlv
, 0);
147 void TLVPrintAIDlistFromSelectTLV(struct tlvdb
*tlv
) {
148 PrintAndLog("|------------------|--------|-------------------------|");
149 PrintAndLog("| AID |Priority| Name |");
150 PrintAndLog("|------------------|--------|-------------------------|");
152 struct tlvdb
*ttmp
= tlvdb_find(tlv
, 0x6f);
154 PrintAndLog("| none |");
157 const struct tlv
*tgAID
= tlvdb_get_inchild(ttmp
, 0x84, NULL
);
158 const struct tlv
*tgName
= tlvdb_get_inchild(ttmp
, 0x50, NULL
);
159 const struct tlv
*tgPrio
= tlvdb_get_inchild(ttmp
, 0x87, NULL
);
162 PrintAndLog("|%s| %s |%s|",
163 sprint_hex_inrow_ex(tgAID
->value
, tgAID
->len
, 18),
164 (tgPrio
) ? sprint_hex(tgPrio
->value
, 1) : " ",
165 (tgName
) ? sprint_ascii_ex(tgName
->value
, tgName
->len
, 25) : " ");
167 ttmp
= tlvdb_find_next(ttmp
, 0x6f);
170 PrintAndLog("|------------------|--------|-------------------------|");
173 struct tlvdb
*GetPANFromTrack2(const struct tlv
*track2
) {
174 char track2Hex
[200] = {0};
175 uint8_t PAN
[100] = {0};
177 char *tmp
= track2Hex
;
182 for (int i
= 0; i
< track2
->len
; ++i
, tmp
+= 2)
183 sprintf(tmp
, "%02x", (unsigned int)track2
->value
[i
]);
185 int posD
= strchr(track2Hex
, 'd') - track2Hex
;
190 if (strlen(track2Hex
) % 2) {
191 track2Hex
[posD
] = 'F';
192 track2Hex
[posD
+ 1] = '\0';
195 param_gethex_to_eol(track2Hex
, 0, PAN
, sizeof(PAN
), &PANlen
);
197 return tlvdb_fixed(0x5a, PANlen
, PAN
);
200 struct tlvdb
*GetdCVVRawFromTrack2(const struct tlv
*track2
) {
201 char track2Hex
[200] = {0};
202 char dCVVHex
[100] = {0};
203 uint8_t dCVV
[100] = {0};
205 const int PINlen
= 5; // must calculated from 9F67 MSD Offset but i have not seen this tag)
206 char *tmp
= track2Hex
;
211 for (int i
= 0; i
< track2
->len
; ++i
, tmp
+= 2)
212 sprintf(tmp
, "%02x", (unsigned int)track2
->value
[i
]);
214 int posD
= strchr(track2Hex
, 'd') - track2Hex
;
218 memset(dCVVHex
, '0', 32);
220 memcpy(dCVVHex
+ 0, track2Hex
+ posD
+ PINlen
+ 11, 4);
222 memcpy(dCVVHex
+ 4, track2Hex
, 5);
224 memcpy(dCVVHex
+ 9, track2Hex
+ posD
+ 1, 4);
226 memcpy(dCVVHex
+ 13, track2Hex
+ posD
+ 5, 3);
228 param_gethex_to_eol(dCVVHex
, 0, dCVV
, sizeof(dCVV
), &dCVVlen
);
230 return tlvdb_fixed(0x02, dCVVlen
, dCVV
);
233 int EMVExchangeEx(bool ActivateField
, bool LeaveFieldON
, sAPDU apdu
, bool IncludeLe
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
) {
234 uint8_t data
[APDU_RES_LEN
] = {0};
246 memcpy(data
, &apdu
, 5);
248 memcpy(&data
[5], apdu
.data
, apdu
.Lc
);
251 PrintAndLog(">>>> %s", sprint_hex(data
, (IncludeLe
?6:5) + apdu
.Lc
));
253 // 6 byes + data = INS + CLA + P1 + P2 + Lc + <data = Nc> + Le(?IncludeLe)
254 int res
= ExchangeAPDU14a(data
, (IncludeLe
?6:5) + apdu
.Lc
, ActivateField
, LeaveFieldON
, Result
, (int)MaxResultLen
, (int *)ResultLen
);
261 PrintAndLog("<<<< %s", sprint_hex(Result
, *ResultLen
));
264 isw
= Result
[*ResultLen
] * 0x0100 + Result
[*ResultLen
+ 1];
270 if (*sw
>> 8 == 0x61) {
271 PrintAndLog("APDU chaining len:%02x -->", *sw
& 0xff);
273 PrintAndLog("APDU(%02x%02x) ERROR: [%4X] %s", apdu
.CLA
, apdu
.INS
, isw
, GetAPDUCodeDescription(*sw
>> 8, *sw
& 0xff));
281 struct tlvdb
*t
= tlvdb_parse_multi(Result
, *ResultLen
);
288 int EMVExchange(bool LeaveFieldON
, sAPDU apdu
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
) {
289 return EMVExchangeEx(false, LeaveFieldON
, apdu
, true, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
292 int EMVSelect(bool ActivateField
, bool LeaveFieldON
, uint8_t *AID
, size_t AIDLen
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
) {
293 return EMVExchangeEx(ActivateField
, LeaveFieldON
, (sAPDU
){0x00, 0xa4, 0x04, 0x00, AIDLen
, AID
}, true, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
296 int EMVSelectPSE(bool ActivateField
, bool LeaveFieldON
, uint8_t PSENum
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
) {
297 uint8_t buf
[APDU_AID_LEN
] = {0};
303 param_gethex_to_eol(PSElist
[1], 0, buf
, sizeof(buf
), &len
);
306 param_gethex_to_eol(PSElist
[0], 0, buf
, sizeof(buf
), &len
);
313 res
= EMVSelect(ActivateField
, LeaveFieldON
, buf
, len
, Result
, MaxResultLen
, ResultLen
, sw
, NULL
);
318 int EMVSearchPSE(bool ActivateField
, bool LeaveFieldON
, bool decodeTLV
, struct tlvdb
*tlv
) {
319 uint8_t data
[APDU_RES_LEN
] = {0};
325 res
= EMVSelectPSE(ActivateField
, true, 2, data
, sizeof(data
), &datalen
, &sw
);
328 struct tlvdb
*t
= NULL
;
329 t
= tlvdb_parse_multi(data
, datalen
);
332 struct tlvdb
*ttmp
= tlvdb_find_path(t
, (tlv_tag_t
[]){0x6f, 0xa5, 0xbf0c, 0x61, 0x00});
334 PrintAndLog("PPSE don't have records.");
337 const struct tlv
*tgAID
= tlvdb_get_inchild(ttmp
, 0x4f, NULL
);
339 res
= EMVSelect(false, true, (uint8_t *)tgAID
->value
, tgAID
->len
, data
, sizeof(data
), &datalen
, &sw
, tlv
);
341 // retry if error and not returned sw error
342 if (res
&& res
!= 5) {
346 // card select error, proxmark error
348 PrintAndLog("Exit...");
353 PrintAndLog("Retry failed [%s]. Skiped...", sprint_hex_inrow(tgAID
->value
, tgAID
->len
));
357 ttmp
= tlvdb_find_next(ttmp
, 0x61);
364 PrintAndLog("%s:", sprint_hex_inrow(tgAID
->value
, tgAID
->len
));
365 TLVPrintFromBuffer(data
, datalen
);
369 ttmp
= tlvdb_find_next(ttmp
, 0x61);
374 PrintAndLog("PPSE ERROR: Can't get TLV from response.");
377 PrintAndLog("PPSE ERROR: Can't select PPSE AID. Error: %d", res
);
386 int EMVSearch(bool ActivateField
, bool LeaveFieldON
, bool decodeTLV
, struct tlvdb
*tlv
) {
387 uint8_t aidbuf
[APDU_AID_LEN
] = {0};
389 uint8_t data
[APDU_RES_LEN
] = {0};
395 for(int i
= 0; i
< AIDlistLen
; i
++) {
396 param_gethex_to_eol(AIDlist
[i
].aid
, 0, aidbuf
, sizeof(aidbuf
), &aidlen
);
397 res
= EMVSelect((i
== 0) ? ActivateField
: false, (i
== AIDlistLen
- 1) ? LeaveFieldON
: true, aidbuf
, aidlen
, data
, sizeof(data
), &datalen
, &sw
, tlv
);
398 // retry if error and not returned sw error
399 if (res
&& res
!= 5) {
403 // card select error, proxmark error
405 PrintAndLog("Exit...");
410 PrintAndLog("Retry failed [%s]. Skiped...", AIDlist
[i
].aid
);
420 PrintAndLog("%s:", AIDlist
[i
].aid
);
421 TLVPrintFromBuffer(data
, datalen
);
428 int EMVSelectApplication(struct tlvdb
*tlv
, uint8_t *AID
, size_t *AIDlen
) {
429 // check priority. 0x00 - highest
434 struct tlvdb
*ttmp
= tlvdb_find(tlv
, 0x6f);
439 const struct tlv
*tgAID
= tlvdb_get_inchild(ttmp
, 0x84, NULL
);
440 const struct tlv
*tgPrio
= tlvdb_get_inchild(ttmp
, 0x87, NULL
);
446 int pt
= bytes_to_num((uint8_t*)tgPrio
->value
, (tgPrio
->len
< 2) ? tgPrio
->len
: 2);
450 memcpy(AID
, tgAID
->value
, tgAID
->len
);
451 *AIDlen
= tgAID
->len
;
454 // takes the first application from list wo priority
456 memcpy(AID
, tgAID
->value
, tgAID
->len
);
457 *AIDlen
= tgAID
->len
;
461 ttmp
= tlvdb_find_next(ttmp
, 0x6f);
467 int EMVGPO(bool LeaveFieldON
, uint8_t *PDOL
, size_t PDOLLen
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
) {
468 return EMVExchange(LeaveFieldON
, (sAPDU
){0x80, 0xa8, 0x00, 0x00, PDOLLen
, PDOL
}, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
471 int EMVReadRecord(bool LeaveFieldON
, uint8_t SFI
, uint8_t SFIrec
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
) {
472 int res
= EMVExchange(LeaveFieldON
, (sAPDU
){0x00, 0xb2, SFIrec
, (SFI
<< 3) | 0x04, 0, NULL
}, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
474 PrintAndLog(">>> trying to reissue command withouth Le...");
475 res
= EMVExchangeEx(false, LeaveFieldON
, (sAPDU
){0x00, 0xb2, SFIrec
, (SFI
<< 3) | 0x04, 0, NULL
}, false, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
480 int EMVAC(bool LeaveFieldON
, uint8_t RefControl
, uint8_t *CDOL
, size_t CDOLLen
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
) {
481 return EMVExchange(LeaveFieldON
, (sAPDU
){0x80, 0xae, RefControl
, 0x00, CDOLLen
, CDOL
}, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
484 int EMVGenerateChallenge(bool LeaveFieldON
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
) {
485 int res
= EMVExchange(LeaveFieldON
, (sAPDU
){0x00, 0x84, 0x00, 0x00, 0x00, NULL
}, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
487 PrintAndLog(">>> trying to reissue command withouth Le...");
488 res
= EMVExchangeEx(false, LeaveFieldON
, (sAPDU
){0x00, 0x84, 0x00, 0x00, 0x00, NULL
}, false, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
493 int EMVInternalAuthenticate(bool LeaveFieldON
, uint8_t *DDOL
, size_t DDOLLen
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
) {
494 return EMVExchange(LeaveFieldON
, (sAPDU
){0x00, 0x88, 0x00, 0x00, DDOLLen
, DDOL
}, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
497 int MSCComputeCryptoChecksum(bool LeaveFieldON
, uint8_t *UDOL
, uint8_t UDOLlen
, uint8_t *Result
, size_t MaxResultLen
, size_t *ResultLen
, uint16_t *sw
, struct tlvdb
*tlv
) {
498 return EMVExchange(LeaveFieldON
, (sAPDU
){0x80, 0x2a, 0x8e, 0x80, UDOLlen
, UDOL
}, Result
, MaxResultLen
, ResultLen
, sw
, tlv
);
502 static struct emv_pk
*get_ca_pk(struct tlvdb
*db
) {
503 const struct tlv
*df_tlv
= tlvdb_get(db
, 0x84, NULL
);
504 const struct tlv
*caidx_tlv
= tlvdb_get(db
, 0x8f, NULL
);
506 if (!df_tlv
|| !caidx_tlv
|| df_tlv
->len
< 6 || caidx_tlv
->len
!= 1)
509 PrintAndLog("CA public key index 0x%0x", caidx_tlv
->value
[0]);
510 return emv_pk_get_ca_pk(df_tlv
->value
, caidx_tlv
->value
[0]);
513 int trSDA(struct tlvdb
*tlv
) {
515 struct emv_pk
*pk
= get_ca_pk(tlv
);
517 PrintAndLog("ERROR: Key not found. Exit.");
521 struct emv_pk
*issuer_pk
= emv_pki_recover_issuer_cert(pk
, tlv
);
524 PrintAndLog("ERROR: Issuer certificate not found. Exit.");
528 PrintAndLog("Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx",
535 issuer_pk
->serial
[0],
536 issuer_pk
->serial
[1],
540 const struct tlv
*sda_tlv
= tlvdb_get(tlv
, 0x21, NULL
);
541 if (!sda_tlv
|| sda_tlv
->len
< 1) {
542 emv_pk_free(issuer_pk
);
544 PrintAndLog("ERROR: Can't find input list for Offline Data Authentication. Exit.");
548 struct tlvdb
*dac_db
= emv_pki_recover_dac(issuer_pk
, tlv
, sda_tlv
);
550 const struct tlv
*dac_tlv
= tlvdb_get(dac_db
, 0x9f45, NULL
);
551 PrintAndLog("SDA verified OK. (%02hhx:%02hhx)\n", dac_tlv
->value
[0], dac_tlv
->value
[1]);
552 tlvdb_add(tlv
, dac_db
);
554 emv_pk_free(issuer_pk
);
556 PrintAndLog("ERROR: SSAD verify error");
560 emv_pk_free(issuer_pk
);
565 static const unsigned char default_ddol_value
[] = {0x9f, 0x37, 0x04};
566 static struct tlv default_ddol_tlv
= {.tag
= 0x9f49, .len
= 3, .value
= default_ddol_value
};
568 int trDDA(bool decodeTLV
, struct tlvdb
*tlv
) {
569 uint8_t buf
[APDU_RES_LEN
] = {0};
573 struct emv_pk
*pk
= get_ca_pk(tlv
);
575 PrintAndLog("ERROR: Key not found. Exit.");
579 const struct tlv
*sda_tlv
= tlvdb_get(tlv
, 0x21, NULL
);
580 if (!sda_tlv
|| sda_tlv
->len
< 1) {
582 PrintAndLog("ERROR: Can't find input list for Offline Data Authentication. Exit.");
586 struct emv_pk
*issuer_pk
= emv_pki_recover_issuer_cert(pk
, tlv
);
589 PrintAndLog("ERROR: Issuer certificate not found. Exit.");
592 printf("Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
599 issuer_pk
->serial
[0],
600 issuer_pk
->serial
[1],
604 struct emv_pk
*icc_pk
= emv_pki_recover_icc_cert(issuer_pk
, tlv
, sda_tlv
);
607 emv_pk_free(issuer_pk
);
608 PrintAndLog("ERROR: ICC setrificate not found. Exit.");
611 printf("ICC PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
623 struct emv_pk
*icc_pe_pk
= emv_pki_recover_icc_pe_cert(issuer_pk
, tlv
);
625 PrintAndLog("WARNING: ICC PE PK recover error. ");
627 printf("ICC PE PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
634 icc_pe_pk
->serial
[0],
635 icc_pe_pk
->serial
[1],
640 // 9F4B: Signed Dynamic Application Data
641 const struct tlv
*sdad_tlv
= tlvdb_get(tlv
, 0x9f4b, NULL
);
642 // DDA with internal authenticate OR fDDA with filled 0x9F4B tag (GPO result)
643 // EMV kernel3 v2.4, contactless book C-3, C.1., page 147
645 PrintAndLog("\n* * Got Signed Dynamic Application Data (9F4B) form GPO. Maybe fDDA...");
647 const struct tlvdb
*atc_db
= emv_pki_recover_atc_ex(icc_pk
, tlv
, true);
649 PrintAndLog("ERROR: Can't recover IDN (ICC Dynamic Number)");
651 emv_pk_free(issuer_pk
);
656 // 9f36 Application Transaction Counter (ATC)
657 const struct tlv
*atc_tlv
= tlvdb_get(atc_db
, 0x9f36, NULL
);
659 PrintAndLog("\nATC (Application Transaction Counter) [%zu] %s", atc_tlv
->len
, sprint_hex_inrow(atc_tlv
->value
, atc_tlv
->len
));
661 const struct tlv
*core_atc_tlv
= tlvdb_get(tlv
, 0x9f36, NULL
);
662 if(tlv_equal(core_atc_tlv
, atc_tlv
)) {
663 PrintAndLog("ATC check OK.");
664 PrintAndLog("fDDA (fast DDA) verified OK.");
666 PrintAndLog("ERROR: fDDA verified, but ATC in the certificate and ATC in the record not the same.");
669 PrintAndLog("\nERROR: fDDA (fast DDA) verify error");
671 emv_pk_free(issuer_pk
);
676 struct tlvdb
*dac_db
= emv_pki_recover_dac(issuer_pk
, tlv
, sda_tlv
);
678 const struct tlv
*dac_tlv
= tlvdb_get(dac_db
, 0x9f45, NULL
);
679 printf("SDA verified OK. (%02hhx:%02hhx)\n", dac_tlv
->value
[0], dac_tlv
->value
[1]);
680 tlvdb_add(tlv
, dac_db
);
682 PrintAndLog("ERROR: SSAD verify error");
684 emv_pk_free(issuer_pk
);
689 PrintAndLog("\n* Calc DDOL");
690 const struct tlv
*ddol_tlv
= tlvdb_get(tlv
, 0x9f49, NULL
);
692 ddol_tlv
= &default_ddol_tlv
;
693 PrintAndLog("DDOL [9f49] not found. Using default DDOL");
696 struct tlv
*ddol_data_tlv
= dol_process(ddol_tlv
, tlv
, 0);
697 if (!ddol_data_tlv
) {
698 PrintAndLog("ERROR: Can't create DDOL TLV");
700 emv_pk_free(issuer_pk
);
705 PrintAndLog("DDOL data[%d]: %s", ddol_data_tlv
->len
, sprint_hex(ddol_data_tlv
->value
, ddol_data_tlv
->len
));
707 PrintAndLog("\n* Internal Authenticate");
708 int res
= EMVInternalAuthenticate(true, (uint8_t *)ddol_data_tlv
->value
, ddol_data_tlv
->len
, buf
, sizeof(buf
), &len
, &sw
, NULL
);
710 PrintAndLog("Internal Authenticate error(%d): %4x. Exit...", res
, sw
);
713 emv_pk_free(issuer_pk
);
718 struct tlvdb
*dda_db
= NULL
;
719 if (buf
[0] == 0x80) {
721 PrintAndLog("ERROR: Internal Authenticate format1 parsing error. length=%d", len
);
723 // 9f4b Signed Dynamic Application Data
724 dda_db
= tlvdb_fixed(0x9f4b, len
- 2, buf
+ 2);
725 tlvdb_add(tlv
, dda_db
);
727 PrintAndLog("* * Decode response format 1:");
728 TLVPrintFromTLV(dda_db
);
732 dda_db
= tlvdb_parse_multi(buf
, len
);
734 PrintAndLog("ERROR: Can't parse Internal Authenticate result as TLV");
737 emv_pk_free(issuer_pk
);
741 tlvdb_add(tlv
, dda_db
);
744 TLVPrintFromTLV(dda_db
);
747 struct tlvdb
*idn_db
= emv_pki_recover_idn_ex(icc_pk
, dda_db
, ddol_data_tlv
, true);
750 PrintAndLog("ERROR: Can't recover IDN (ICC Dynamic Number)");
753 emv_pk_free(issuer_pk
);
759 // 9f4c ICC Dynamic Number
760 const struct tlv
*idn_tlv
= tlvdb_get(idn_db
, 0x9f4c, NULL
);
762 PrintAndLog("\nIDN (ICC Dynamic Number) [%zu] %s", idn_tlv
->len
, sprint_hex_inrow(idn_tlv
->value
, idn_tlv
->len
));
763 PrintAndLog("DDA verified OK.");
764 tlvdb_add(tlv
, idn_db
);
767 PrintAndLog("\nERROR: DDA verify error");
771 emv_pk_free(issuer_pk
);
778 emv_pk_free(issuer_pk
);
783 int trCDA(struct tlvdb
*tlv
, struct tlvdb
*ac_tlv
, struct tlv
*pdol_data_tlv
, struct tlv
*ac_data_tlv
) {
785 struct emv_pk
*pk
= get_ca_pk(tlv
);
787 PrintAndLog("ERROR: Key not found. Exit.");
791 const struct tlv
*sda_tlv
= tlvdb_get(tlv
, 0x21, NULL
);
792 if (!sda_tlv
|| sda_tlv
->len
< 1) {
793 PrintAndLog("ERROR: Can't find input list for Offline Data Authentication. Exit.");
798 struct emv_pk
*issuer_pk
= emv_pki_recover_issuer_cert(pk
, tlv
);
800 PrintAndLog("ERROR: Issuer certificate not found. Exit.");
804 printf("Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
811 issuer_pk
->serial
[0],
812 issuer_pk
->serial
[1],
816 struct emv_pk
*icc_pk
= emv_pki_recover_icc_cert(issuer_pk
, tlv
, sda_tlv
);
818 PrintAndLog("ERROR: ICC setrificate not found. Exit.");
820 emv_pk_free(issuer_pk
);
823 printf("ICC PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
835 struct tlvdb
*dac_db
= emv_pki_recover_dac(issuer_pk
, tlv
, sda_tlv
);
837 const struct tlv
*dac_tlv
= tlvdb_get(dac_db
, 0x9f45, NULL
);
838 PrintAndLog("SSAD verified OK. (%02hhx:%02hhx)", dac_tlv
->value
[0], dac_tlv
->value
[1]);
839 tlvdb_add(tlv
, dac_db
);
841 PrintAndLog("ERROR: SSAD verify error");
843 emv_pk_free(issuer_pk
);
848 PrintAndLog("\n* * Check Signed Dynamic Application Data (SDAD)");
849 struct tlvdb
*idn_db
= emv_pki_perform_cda_ex(icc_pk
, tlv
, ac_tlv
,
850 pdol_data_tlv
, // pdol
851 ac_data_tlv
, // cdol1
855 const struct tlv
*idn_tlv
= tlvdb_get(idn_db
, 0x9f4c, NULL
);
856 PrintAndLog("\nIDN (ICC Dynamic Number) [%zu] %s", idn_tlv
->len
, sprint_hex_inrow(idn_tlv
->value
, idn_tlv
->len
));
857 PrintAndLog("CDA verified OK.");
858 tlvdb_add(tlv
, idn_db
);
860 PrintAndLog("\nERROR: CDA verify error");
864 emv_pk_free(issuer_pk
);
869 int RecoveryCertificates(struct tlvdb
*tlvRoot
, json_t
*root
) {
871 struct emv_pk
*pk
= get_ca_pk(tlvRoot
);
873 PrintAndLog("ERROR: Key not found. Exit.");
877 struct emv_pk
*issuer_pk
= emv_pki_recover_issuer_cert(pk
, tlvRoot
);
880 PrintAndLog("WARNING: Issuer certificate not found. Exit.");
883 PrintAndLog("Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx",
890 issuer_pk
->serial
[0],
891 issuer_pk
->serial
[1],
895 JsonSaveBufAsHex(root
, "$.ApplicationData.RID", issuer_pk
->rid
, 5);
897 char *issuer_pk_c
= emv_pk_dump_pk(issuer_pk
);
898 JsonSaveStr(root
, "$.ApplicationData.IssuerPublicKeyDec", issuer_pk_c
);
899 JsonSaveBufAsHex(root
, "$.ApplicationData.IssuerPublicKeyModulus", issuer_pk
->modulus
, issuer_pk
->mlen
);
902 struct emv_pk
*icc_pk
= emv_pki_recover_icc_cert(issuer_pk
, tlvRoot
, NULL
);
905 emv_pk_free(issuer_pk
);
906 PrintAndLog("WARNING: ICC certificate not found. Exit.");
909 printf("ICC PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
921 char *icc_pk_c
= emv_pk_dump_pk(icc_pk
);
922 JsonSaveStr(root
, "$.ApplicationData.ICCPublicKeyDec", icc_pk_c
);
923 JsonSaveBufAsHex(root
, "$.ApplicationData.ICCPublicKeyModulus", icc_pk
->modulus
, icc_pk
->mlen
);