]> git.zerfleddert.de Git - proxmark3-svn/blob - client/emv/cmdemv.c
Added loading EMV transaction parameters from json file (#659)
[proxmark3-svn] / client / emv / cmdemv.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2017 Merlok
3 //
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
6 // the license.
7 //-----------------------------------------------------------------------------
8 // EMV commands
9 //-----------------------------------------------------------------------------
10
11 #include <ctype.h>
12 #include "cmdemv.h"
13 #include "test/cryptotest.h"
14 #include <jansson.h>
15
16 int UsageCmdHFEMVSelect(void) {
17 PrintAndLog("HELP : Executes select applet command:\n");
18 PrintAndLog("Usage: hf emv select [-s][-k][-a][-t] <HEX applet AID>\n");
19 PrintAndLog(" Options:");
20 PrintAndLog(" -s : select card");
21 PrintAndLog(" -k : keep field for next command");
22 PrintAndLog(" -a : show APDU reqests and responses\n");
23 PrintAndLog(" -t : TLV decode results\n");
24 PrintAndLog("Samples:");
25 PrintAndLog(" hf emv select -s a00000000101 -> select card, select applet");
26 PrintAndLog(" hf emv select -s -t a00000000101 -> select card, select applet, show result in TLV");
27 return 0;
28 }
29
30 int CmdHFEMVSelect(const char *cmd) {
31 uint8_t data[APDU_AID_LEN] = {0};
32 int datalen = 0;
33 bool activateField = false;
34 bool leaveSignalON = false;
35 bool decodeTLV = false;
36
37 if (strlen(cmd) < 1) {
38 UsageCmdHFEMVSelect();
39 return 0;
40 }
41
42 SetAPDULogging(false);
43
44 int cmdp = 0;
45 while(param_getchar(cmd, cmdp) != 0x00) {
46 char c = param_getchar(cmd, cmdp);
47 if ((c == '-') && (param_getlength(cmd, cmdp) == 2))
48 switch (param_getchar_indx(cmd, 1, cmdp)) {
49 case 'h':
50 case 'H':
51 UsageCmdHFEMVSelect();
52 return 0;
53 case 's':
54 case 'S':
55 activateField = true;
56 break;
57 case 'k':
58 case 'K':
59 leaveSignalON = true;
60 break;
61 case 'a':
62 case 'A':
63 SetAPDULogging(true);
64 break;
65 case 't':
66 case 'T':
67 decodeTLV = true;
68 break;
69 default:
70 PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
71 return 1;
72 }
73
74 if (isxdigit((unsigned char)c)) {
75 switch(param_gethex_to_eol(cmd, cmdp, data, sizeof(data), &datalen)) {
76 case 1:
77 PrintAndLog("Invalid HEX value.");
78 return 1;
79 case 2:
80 PrintAndLog("AID too large.");
81 return 1;
82 case 3:
83 PrintAndLog("Hex must have even number of digits.");
84 return 1;
85 }
86
87 // we get all the hex to end of line with spaces
88 break;
89 }
90
91
92 cmdp++;
93 }
94
95 // exec
96 uint8_t buf[APDU_RES_LEN] = {0};
97 size_t len = 0;
98 uint16_t sw = 0;
99 int res = EMVSelect(activateField, leaveSignalON, data, datalen, buf, sizeof(buf), &len, &sw, NULL);
100
101 if (sw)
102 PrintAndLog("APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
103
104 if (res)
105 return res;
106
107 if (decodeTLV)
108 TLVPrintFromBuffer(buf, len);
109
110 return 0;
111 }
112
113 int UsageCmdHFEMVSearch(void) {
114 PrintAndLog("HELP : Tries to select all applets from applet list:\n");
115 PrintAndLog("Usage: hf emv search [-s][-k][-a][-t]\n");
116 PrintAndLog(" Options:");
117 PrintAndLog(" -s : select card");
118 PrintAndLog(" -k : keep field for next command");
119 PrintAndLog(" -a : show APDU reqests and responses\n");
120 PrintAndLog(" -t : TLV decode results of selected applets\n");
121 PrintAndLog("Samples:");
122 PrintAndLog(" hf emv search -s -> select card and search");
123 PrintAndLog(" hf emv search -s -t -> select card, search and show result in TLV");
124 return 0;
125 }
126
127 int CmdHFEMVSearch(const char *cmd) {
128
129 bool activateField = false;
130 bool leaveSignalON = false;
131 bool decodeTLV = false;
132
133 if (strlen(cmd) < 1) {
134 UsageCmdHFEMVSearch();
135 return 0;
136 }
137
138 SetAPDULogging(false);
139
140 int cmdp = 0;
141 while(param_getchar(cmd, cmdp) != 0x00) {
142 char c = param_getchar(cmd, cmdp);
143 if ((c == '-') && (param_getlength(cmd, cmdp) == 2))
144 switch (param_getchar_indx(cmd, 1, cmdp)) {
145 case 'h':
146 case 'H':
147 UsageCmdHFEMVSearch();
148 return 0;
149 case 's':
150 case 'S':
151 activateField = true;
152 break;
153 case 'k':
154 case 'K':
155 leaveSignalON = true;
156 break;
157 case 'a':
158 case 'A':
159 SetAPDULogging(true);
160 break;
161 case 't':
162 case 'T':
163 decodeTLV = true;
164 break;
165 default:
166 PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
167 return 1;
168 }
169 cmdp++;
170 }
171
172 struct tlvdb *t = NULL;
173 const char *al = "Applets list";
174 t = tlvdb_fixed(1, strlen(al), (const unsigned char *)al);
175
176 if (EMVSearch(activateField, leaveSignalON, decodeTLV, t)) {
177 tlvdb_free(t);
178 return 2;
179 }
180
181 PrintAndLog("Search completed.");
182
183 // print list here
184 if (!decodeTLV) {
185 TLVPrintAIDlistFromSelectTLV(t);
186 }
187
188 tlvdb_free(t);
189
190 return 0;
191 }
192
193 int UsageCmdHFEMVPPSE(void) {
194 PrintAndLog("HELP : Executes PSE/PPSE select command. It returns list of applet on the card:\n");
195 PrintAndLog("Usage: hf emv pse [-s][-k][-1][-2][-a][-t]\n");
196 PrintAndLog(" Options:");
197 PrintAndLog(" -s : select card");
198 PrintAndLog(" -k : keep field for next command");
199 PrintAndLog(" -1 : ppse (1PAY.SYS.DDF01)");
200 PrintAndLog(" -2 : pse (2PAY.SYS.DDF01)");
201 PrintAndLog(" -a : show APDU reqests and responses\n");
202 PrintAndLog(" -t : TLV decode results\n");
203 PrintAndLog("Samples:");
204 PrintAndLog(" hf emv pse -s -1 -> select, get pse");
205 PrintAndLog(" hf emv pse -s -k -2 -> select, get ppse, keep field");
206 PrintAndLog(" hf emv pse -s -t -2 -> select, get ppse, show result in TLV");
207 return 0;
208 }
209
210 int CmdHFEMVPPSE(const char *cmd) {
211
212 uint8_t PSENum = 2;
213 bool activateField = false;
214 bool leaveSignalON = false;
215 bool decodeTLV = false;
216
217 if (strlen(cmd) < 1) {
218 UsageCmdHFEMVPPSE();
219 return 0;
220 }
221
222 SetAPDULogging(false);
223
224 int cmdp = 0;
225 while(param_getchar(cmd, cmdp) != 0x00) {
226 char c = param_getchar(cmd, cmdp);
227 if ((c == '-') && (param_getlength(cmd, cmdp) == 2))
228 switch (param_getchar_indx(cmd, 1, cmdp)) {
229 case 'h':
230 case 'H':
231 UsageCmdHFEMVPPSE();
232 return 0;
233 case 's':
234 case 'S':
235 activateField = true;
236 break;
237 case 'k':
238 case 'K':
239 leaveSignalON = true;
240 break;
241 case 'a':
242 case 'A':
243 SetAPDULogging(true);
244 break;
245 case 't':
246 case 'T':
247 decodeTLV = true;
248 break;
249 case '1':
250 PSENum = 1;
251 break;
252 case '2':
253 PSENum = 2;
254 break;
255 default:
256 PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
257 return 1;
258 }
259 cmdp++;
260 }
261
262 // exec
263 uint8_t buf[APDU_RES_LEN] = {0};
264 size_t len = 0;
265 uint16_t sw = 0;
266 int res = EMVSelectPSE(activateField, leaveSignalON, PSENum, buf, sizeof(buf), &len, &sw);
267
268 if (sw)
269 PrintAndLog("APDU response status: %04x - %s", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
270
271 if (res)
272 return res;
273
274
275 if (decodeTLV)
276 TLVPrintFromBuffer(buf, len);
277
278 return 0;
279 }
280
281 int UsageCmdHFEMVExec(void) {
282 PrintAndLog("HELP : Executes EMV contactless transaction:\n");
283 PrintAndLog("Usage: hf emv exec [-s][-a][-t][-j][-f][-v][-c][-x][-g]\n");
284 PrintAndLog(" Options:");
285 PrintAndLog(" -s : select card");
286 PrintAndLog(" -a : show APDU reqests and responses\n");
287 PrintAndLog(" -t : TLV decode results\n");
288 PrintAndLog(" -j : load transaction parameters from `emv/defparams.json` file\n");
289 PrintAndLog(" -f : force search AID. Search AID instead of execute PPSE.\n");
290 PrintAndLog(" -v : transaction type - qVSDC or M/Chip.\n");
291 PrintAndLog(" -c : transaction type - qVSDC or M/Chip plus CDA (SDAD generation).\n");
292 PrintAndLog(" -x : transaction type - VSDC. For test only. Not a standart behavior.\n");
293 PrintAndLog(" -g : VISA. generate AC from GPO\n");
294 PrintAndLog("By default : transaction type - MSD.\n");
295 PrintAndLog("Samples:");
296 PrintAndLog(" hf emv exec -s -a -t -> execute MSD transaction");
297 PrintAndLog(" hf emv exec -s -a -t -c -> execute CDA transaction");
298 return 0;
299 }
300
301 #define TLV_ADD(tag, value)( tlvdb_change_or_add_node(tlvRoot, tag, sizeof(value) - 1, (const unsigned char *)value) )
302 #define dreturn(n) {free(pdol_data_tlv);tlvdb_free(tlvSelect);tlvdb_free(tlvRoot);DropField();return n;}
303
304 bool HexToBuffer(const char *errormsg, const char *hexvalue, uint8_t * buffer, size_t maxbufferlen, size_t *bufferlen) {
305 int buflen = 0;
306
307 switch(param_gethex_to_eol(hexvalue, 0, buffer, maxbufferlen, &buflen)) {
308 case 1:
309 PrintAndLog("%s Invalid HEX value.", errormsg);
310 return false;
311 case 2:
312 PrintAndLog("%s Hex value too large.", errormsg);
313 return false;
314 case 3:
315 PrintAndLog("%s Hex value must have even number of digits.", errormsg);
316 return false;
317 }
318
319 if (buflen > maxbufferlen) {
320 PrintAndLog("%s HEX length (%d) more than %d", errormsg, *bufferlen, maxbufferlen);
321 return false;
322 }
323
324 *bufferlen = buflen;
325
326 return true;
327 }
328
329 bool ParamLoadFromJson(struct tlvdb *tlv) {
330 json_t *root;
331 json_error_t error;
332
333 if (!tlv) {
334 PrintAndLog("ERROR load params: tlv tree is NULL.");
335 return false;
336 }
337
338 // current path + file name
339 const char *relfname = "emv/defparams.json";
340 char fname[strlen(get_my_executable_directory()) + strlen(relfname) + 1];
341 strcpy(fname, get_my_executable_directory());
342 strcat(fname, relfname);
343
344 root = json_load_file(fname, 0, &error);
345 if (!root) {
346 PrintAndLog("Load params: json error on line %d: %s", error.line, error.text);
347 return false;
348 }
349
350 if (!json_is_array(root)) {
351 PrintAndLog("Load params: Invalid json format. root must be array.");
352 return false;
353 }
354
355 PrintAndLog("Load params: json OK");
356
357 for(int i = 0; i < json_array_size(root); i++) {
358 json_t *data, *jtype, *jlength, *jvalue;
359
360 data = json_array_get(root, i);
361 if(!json_is_object(data))
362 {
363 PrintAndLog("Load params: data [%d] is not an object", i + 1);
364 json_decref(root);
365 return false;
366 }
367
368 jtype = json_object_get(data, "type");
369 if(!json_is_string(jtype))
370 {
371 PrintAndLog("Load params: data [%d] type is not a string", i + 1);
372 json_decref(root);
373 return false;
374 }
375 const char *tlvType = json_string_value(jtype);
376
377 jvalue = json_object_get(data, "value");
378 if(!json_is_string(jvalue))
379 {
380 PrintAndLog("Load params: data [%d] value is not a string", i + 1);
381 json_decref(root);
382 return false;
383 }
384 const char *tlvValue = json_string_value(jvalue);
385
386 jlength = json_object_get(data, "length");
387 if(!json_is_number(jlength))
388 {
389 PrintAndLog("Load params: data [%d] length is not a number", i + 1);
390 json_decref(root);
391 return false;
392 }
393
394 int tlvLength = json_integer_value(jlength);
395 if (tlvLength > 250) {
396 PrintAndLog("Load params: data [%d] length more than 250", i + 1);
397 json_decref(root);
398 return false;
399 }
400
401 PrintAndLog("TLV param: %s[%d]=%s", tlvType, tlvLength, tlvValue);
402 uint8_t buf[251] = {0};
403 size_t buflen = 0;
404
405 // here max length must be 4, but now tlv_tag_t is 2-byte var. so let it be 2 by now... TODO: needs refactoring tlv_tag_t...
406 if (!HexToBuffer("TLV Error type:", tlvType, buf, 2, &buflen)) {
407 json_decref(root);
408 return false;
409 }
410 tlv_tag_t tag = 0;
411 for (int i = 0; i < buflen; i++) {
412 tag = (tag << 8) + buf[i];
413 }
414
415 if (!HexToBuffer("TLV Error value:", tlvValue, buf, sizeof(buf) - 1, &buflen)) {
416 json_decref(root);
417 return false;
418 }
419
420 if (buflen != tlvLength) {
421 PrintAndLog("Load params: data [%d] length of HEX must(%d) be identical to length in TLV param(%d)", i + 1, buflen, tlvLength);
422 json_decref(root);
423 return false;
424 }
425
426 tlvdb_change_or_add_node(tlv, tag, tlvLength, (const unsigned char *)buf);
427 }
428
429 json_decref(root);
430
431 return true;
432 }
433
434 void ParamLoadDefaults(struct tlvdb *tlvRoot) {
435 //9F02:(Amount, authorized (Numeric)) len:6
436 TLV_ADD(0x9F02, "\x00\x00\x00\x00\x01\x00");
437 //9F1A:(Terminal Country Code) len:2
438 TLV_ADD(0x9F1A, "ru");
439 //5F2A:(Transaction Currency Code) len:2
440 // USD 840, EUR 978, RUR 810, RUB 643, RUR 810(old), UAH 980, AZN 031, n/a 999
441 TLV_ADD(0x5F2A, "\x09\x80");
442 //9A:(Transaction Date) len:3
443 TLV_ADD(0x9A, "\x00\x00\x00");
444 //9C:(Transaction Type) len:1 | 00 => Goods and service #01 => Cash
445 TLV_ADD(0x9C, "\x00");
446 // 9F37 Unpredictable Number len:4
447 TLV_ADD(0x9F37, "\x01\x02\x03\x04");
448 // 9F6A Unpredictable Number (MSD for UDOL) len:4
449 TLV_ADD(0x9F6A, "\x01\x02\x03\x04");
450 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
451 TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC
452 }
453
454 int CmdHFEMVExec(const char *cmd) {
455 bool activateField = false;
456 bool showAPDU = false;
457 bool decodeTLV = false;
458 bool forceSearch = false;
459 enum TransactionType TrType = TT_MSD;
460 bool GenACGPO = false;
461 bool paramLoadJSON = false;
462
463 uint8_t buf[APDU_RES_LEN] = {0};
464 size_t len = 0;
465 uint16_t sw = 0;
466 uint8_t AID[APDU_AID_LEN] = {0};
467 size_t AIDlen = 0;
468 uint8_t ODAiList[4096];
469 size_t ODAiListLen = 0;
470
471 int res;
472
473 struct tlvdb *tlvSelect = NULL;
474 struct tlvdb *tlvRoot = NULL;
475 struct tlv *pdol_data_tlv = NULL;
476
477 if (strlen(cmd) < 1) {
478 UsageCmdHFEMVExec();
479 return 0;
480 }
481
482 int cmdp = 0;
483 while(param_getchar(cmd, cmdp) != 0x00) {
484 char c = param_getchar(cmd, cmdp);
485 if ((c == '-') && (param_getlength(cmd, cmdp) == 2))
486 switch (param_getchar_indx(cmd, 1, cmdp)) {
487 case 'h':
488 case 'H':
489 UsageCmdHFEMVExec();
490 return 0;
491 case 's':
492 case 'S':
493 activateField = true;
494 break;
495 case 'a':
496 case 'A':
497 showAPDU = true;
498 break;
499 case 't':
500 case 'T':
501 decodeTLV = true;
502 break;
503 case 'f':
504 case 'F':
505 forceSearch = true;
506 break;
507 case 'x':
508 case 'X':
509 TrType = TT_VSDC;
510 break;
511 case 'v':
512 case 'V':
513 TrType = TT_QVSDCMCHIP;
514 break;
515 case 'c':
516 case 'C':
517 TrType = TT_CDA;
518 break;
519 case 'g':
520 case 'G':
521 GenACGPO = true;
522 break;
523 case 'j':
524 case 'J':
525 paramLoadJSON = true;
526 break;
527 default:
528 PrintAndLog("Unknown parameter '%c'", param_getchar_indx(cmd, 1, cmdp));
529 return 1;
530 }
531 cmdp++;
532 }
533
534
535 // init applets list tree
536 const char *al = "Applets list";
537 tlvSelect = tlvdb_fixed(1, strlen(al), (const unsigned char *)al);
538
539 // Application Selection
540 // https://www.openscdp.org/scripts/tutorial/emv/applicationselection.html
541 if (!forceSearch) {
542 // PPSE
543 PrintAndLog("\n* PPSE.");
544 SetAPDULogging(showAPDU);
545 res = EMVSearchPSE(activateField, true, decodeTLV, tlvSelect);
546
547 // check PPSE and select application id
548 if (!res) {
549 TLVPrintAIDlistFromSelectTLV(tlvSelect);
550 EMVSelectApplication(tlvSelect, AID, &AIDlen);
551 }
552 }
553
554 // Search
555 if (!AIDlen) {
556 PrintAndLog("\n* Search AID in list.");
557 SetAPDULogging(false);
558 if (EMVSearch(activateField, true, decodeTLV, tlvSelect)) {
559 dreturn(2);
560 }
561
562 // check search and select application id
563 TLVPrintAIDlistFromSelectTLV(tlvSelect);
564 EMVSelectApplication(tlvSelect, AID, &AIDlen);
565 }
566
567 // Init TLV tree
568 const char *alr = "Root terminal TLV tree";
569 tlvRoot = tlvdb_fixed(1, strlen(alr), (const unsigned char *)alr);
570
571 // check if we found EMV application on card
572 if (!AIDlen) {
573 PrintAndLog("Can't select AID. EMV AID not found");
574 dreturn(2);
575 }
576
577 // Select
578 PrintAndLog("\n* Selecting AID:%s", sprint_hex_inrow(AID, AIDlen));
579 SetAPDULogging(showAPDU);
580 res = EMVSelect(false, true, AID, AIDlen, buf, sizeof(buf), &len, &sw, tlvRoot);
581
582 if (res) {
583 PrintAndLog("Can't select AID (%d). Exit...", res);
584 dreturn(3);
585 }
586
587 if (decodeTLV)
588 TLVPrintFromBuffer(buf, len);
589 PrintAndLog("* Selected.");
590
591 PrintAndLog("\n* Init transaction parameters.");
592
593 ParamLoadDefaults(tlvRoot);
594
595 if (paramLoadJSON) {
596 PrintAndLog("* * Transaction parameters loading from JSON...");
597 ParamLoadFromJson(tlvRoot);
598 }
599
600 //9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
601 char *qVSDC = "\x26\x00\x00\x00";
602 if (GenACGPO) {
603 qVSDC = "\x26\x80\x00\x00";
604 }
605 switch(TrType) {
606 case TT_MSD:
607 TLV_ADD(0x9F66, "\x86\x00\x00\x00"); // MSD
608 break;
609 // not standard for contactless. just for test.
610 case TT_VSDC:
611 TLV_ADD(0x9F66, "\x46\x00\x00\x00"); // VSDC
612 break;
613 case TT_QVSDCMCHIP:
614 TLV_ADD(0x9F66, qVSDC); // qVSDC
615 break;
616 case TT_CDA:
617 TLV_ADD(0x9F66, qVSDC); // qVSDC (VISA CDA not enabled)
618 break;
619 default:
620 break;
621 }
622
623 TLVPrintFromTLV(tlvRoot); // TODO delete!!!
624
625 PrintAndLog("\n* Calc PDOL.");
626 pdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x9f38, NULL), tlvRoot, 0x83);
627 if (!pdol_data_tlv){
628 PrintAndLog("ERROR: can't create PDOL TLV.");
629 dreturn(4);
630 }
631
632 size_t pdol_data_tlv_data_len;
633 unsigned char *pdol_data_tlv_data = tlv_encode(pdol_data_tlv, &pdol_data_tlv_data_len);
634 if (!pdol_data_tlv_data) {
635 PrintAndLog("ERROR: can't create PDOL data.");
636 dreturn(4);
637 }
638 PrintAndLog("PDOL data[%d]: %s", pdol_data_tlv_data_len, sprint_hex(pdol_data_tlv_data, pdol_data_tlv_data_len));
639
640 PrintAndLog("\n* GPO.");
641 res = EMVGPO(true, pdol_data_tlv_data, pdol_data_tlv_data_len, buf, sizeof(buf), &len, &sw, tlvRoot);
642
643 free(pdol_data_tlv_data);
644 //free(pdol_data_tlv); --- free on exit.
645
646 if (res) {
647 PrintAndLog("GPO error(%d): %4x. Exit...", res, sw);
648 dreturn(5);
649 }
650
651 // process response template format 1 [id:80 2b AIP + x4b AFL] and format 2 [id:77 TLV]
652 if (buf[0] == 0x80) {
653 if (decodeTLV){
654 PrintAndLog("GPO response format1:");
655 TLVPrintFromBuffer(buf, len);
656 }
657
658 if (len < 4 || (len - 4) % 4) {
659 PrintAndLog("ERROR: GPO response format1 parsing error. length=%d", len);
660 } else {
661 // AIP
662 struct tlvdb * f1AIP = tlvdb_fixed(0x82, 2, buf + 2);
663 tlvdb_add(tlvRoot, f1AIP);
664 if (decodeTLV){
665 PrintAndLog("\n* * Decode response format 1 (0x80) AIP and AFL:");
666 TLVPrintFromTLV(f1AIP);
667 }
668
669 // AFL
670 struct tlvdb * f1AFL = tlvdb_fixed(0x94, len - 4, buf + 2 + 2);
671 tlvdb_add(tlvRoot, f1AFL);
672 if (decodeTLV)
673 TLVPrintFromTLV(f1AFL);
674 }
675 } else {
676 if (decodeTLV)
677 TLVPrintFromBuffer(buf, len);
678 }
679
680 // extract PAN from track2
681 {
682 const struct tlv *track2 = tlvdb_get(tlvRoot, 0x57, NULL);
683 if (!tlvdb_get(tlvRoot, 0x5a, NULL) && track2 && track2->len >= 8) {
684 struct tlvdb *pan = GetPANFromTrack2(track2);
685 if (pan) {
686 tlvdb_add(tlvRoot, pan);
687
688 const struct tlv *pantlv = tlvdb_get(tlvRoot, 0x5a, NULL);
689 PrintAndLog("\n* * Extracted PAN from track2: %s", sprint_hex(pantlv->value, pantlv->len));
690 } else {
691 PrintAndLog("\n* * WARNING: Can't extract PAN from track2.");
692 }
693 }
694 }
695
696 PrintAndLog("\n* Read records from AFL.");
697 const struct tlv *AFL = tlvdb_get(tlvRoot, 0x94, NULL);
698 if (!AFL || !AFL->len) {
699 PrintAndLog("WARNING: AFL not found.");
700 }
701
702 while(AFL && AFL->len) {
703 if (AFL->len % 4) {
704 PrintAndLog("ERROR: Wrong AFL length: %d", AFL->len);
705 break;
706 }
707
708 for (int i = 0; i < AFL->len / 4; i++) {
709 uint8_t SFI = AFL->value[i * 4 + 0] >> 3;
710 uint8_t SFIstart = AFL->value[i * 4 + 1];
711 uint8_t SFIend = AFL->value[i * 4 + 2];
712 uint8_t SFIoffline = AFL->value[i * 4 + 3];
713
714 PrintAndLog("* * SFI[%02x] start:%02x end:%02x offline:%02x", SFI, SFIstart, SFIend, SFIoffline);
715 if (SFI == 0 || SFI == 31 || SFIstart == 0 || SFIstart > SFIend) {
716 PrintAndLog("SFI ERROR! Skipped...");
717 continue;
718 }
719
720 for(int n = SFIstart; n <= SFIend; n++) {
721 PrintAndLog("* * * SFI[%02x] %d", SFI, n);
722
723 res = EMVReadRecord(true, SFI, n, buf, sizeof(buf), &len, &sw, tlvRoot);
724 if (res) {
725 PrintAndLog("ERROR SFI[%02x]. APDU error %4x", SFI, sw);
726 continue;
727 }
728
729 if (decodeTLV) {
730 TLVPrintFromBuffer(buf, len);
731 PrintAndLog("");
732 }
733
734 // Build Input list for Offline Data Authentication
735 // EMV 4.3 book3 10.3, page 96
736 if (SFIoffline) {
737 if (SFI < 11) {
738 const unsigned char *abuf = buf;
739 size_t elmlen = len;
740 struct tlv e;
741 if (tlv_parse_tl(&abuf, &elmlen, &e)) {
742 memcpy(&ODAiList[ODAiListLen], &buf[len - elmlen], elmlen);
743 ODAiListLen += elmlen;
744 } else {
745 PrintAndLog("ERROR SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI);
746 }
747 } else {
748 memcpy(&ODAiList[ODAiListLen], buf, len);
749 ODAiListLen += len;
750 }
751 }
752 }
753 }
754
755 break;
756 }
757
758 // copy Input list for Offline Data Authentication
759 if (ODAiListLen) {
760 struct tlvdb *oda = tlvdb_fixed(0x21, ODAiListLen, ODAiList); // not a standard tag
761 tlvdb_add(tlvRoot, oda);
762 PrintAndLog("* Input list for Offline Data Authentication added to TLV. len=%d \n", ODAiListLen);
763 }
764
765 // get AIP
766 const struct tlv *AIPtlv = tlvdb_get(tlvRoot, 0x82, NULL);
767 uint16_t AIP = AIPtlv->value[0] + AIPtlv->value[1] * 0x100;
768 PrintAndLog("* * AIP=%04x", AIP);
769
770 // SDA
771 if (AIP & 0x0040) {
772 PrintAndLog("\n* SDA");
773 trSDA(tlvRoot);
774 }
775
776 // DDA
777 if (AIP & 0x0020) {
778 PrintAndLog("\n* DDA");
779 trDDA(decodeTLV, tlvRoot);
780 }
781
782 // transaction check
783
784 // qVSDC
785 if (TrType == TT_QVSDCMCHIP|| TrType == TT_CDA){
786 // 9F26: Application Cryptogram
787 const struct tlv *AC = tlvdb_get(tlvRoot, 0x9F26, NULL);
788 if (AC) {
789 PrintAndLog("\n--> qVSDC transaction.");
790 PrintAndLog("* AC path");
791
792 // 9F36: Application Transaction Counter (ATC)
793 const struct tlv *ATC = tlvdb_get(tlvRoot, 0x9F36, NULL);
794 if (ATC) {
795
796 // 9F10: Issuer Application Data - optional
797 const struct tlv *IAD = tlvdb_get(tlvRoot, 0x9F10, NULL);
798
799 // print AC data
800 PrintAndLog("ATC: %s", sprint_hex(ATC->value, ATC->len));
801 PrintAndLog("AC: %s", sprint_hex(AC->value, AC->len));
802 if (IAD){
803 PrintAndLog("IAD: %s", sprint_hex(IAD->value, IAD->len));
804
805 if (IAD->len >= IAD->value[0] + 1) {
806 PrintAndLog("\tKey index: 0x%02x", IAD->value[1]);
807 PrintAndLog("\tCrypto ver: 0x%02x(%03d)", IAD->value[2], IAD->value[2]);
808 PrintAndLog("\tCVR:", sprint_hex(&IAD->value[3], IAD->value[0] - 2));
809 struct tlvdb * cvr = tlvdb_fixed(0x20, IAD->value[0] - 2, &IAD->value[3]);
810 TLVPrintFromTLVLev(cvr, 1);
811 }
812 } else {
813 PrintAndLog("WARNING: IAD not found.");
814 }
815
816 } else {
817 PrintAndLog("ERROR AC: Application Transaction Counter (ATC) not found.");
818 }
819 }
820 }
821
822 // Mastercard M/CHIP
823 if (GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD && (TrType == TT_QVSDCMCHIP || TrType == TT_CDA)){
824 const struct tlv *CDOL1 = tlvdb_get(tlvRoot, 0x8c, NULL);
825 if (CDOL1 && GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD) { // and m/chip transaction flag
826 PrintAndLog("\n--> Mastercard M/Chip transaction.");
827
828 PrintAndLog("* * Generate challenge");
829 res = EMVGenerateChallenge(true, buf, sizeof(buf), &len, &sw, tlvRoot);
830 if (res) {
831 PrintAndLog("ERROR GetChallenge. APDU error %4x", sw);
832 dreturn(6);
833 }
834 if (len < 4) {
835 PrintAndLog("ERROR GetChallenge. Wrong challenge length %d", len);
836 dreturn(6);
837 }
838
839 // ICC Dynamic Number
840 struct tlvdb * ICCDynN = tlvdb_fixed(0x9f4c, len, buf);
841 tlvdb_add(tlvRoot, ICCDynN);
842 if (decodeTLV){
843 PrintAndLog("\n* * ICC Dynamic Number:");
844 TLVPrintFromTLV(ICCDynN);
845 }
846
847 PrintAndLog("* * Calc CDOL1");
848 struct tlv *cdol_data_tlv = dol_process(tlvdb_get(tlvRoot, 0x8c, NULL), tlvRoot, 0x01); // 0x01 - dummy tag
849 if (!cdol_data_tlv){
850 PrintAndLog("ERROR: can't create CDOL1 TLV.");
851 dreturn(6);
852 }
853 PrintAndLog("CDOL1 data[%d]: %s", cdol_data_tlv->len, sprint_hex(cdol_data_tlv->value, cdol_data_tlv->len));
854
855 PrintAndLog("* * AC1");
856 // EMVAC_TC + EMVAC_CDAREQ --- to get SDAD
857 res = EMVAC(true, (TrType == TT_CDA) ? EMVAC_TC + EMVAC_CDAREQ : EMVAC_TC, (uint8_t *)cdol_data_tlv->value, cdol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot);
858
859 if (res) {
860 PrintAndLog("AC1 error(%d): %4x. Exit...", res, sw);
861 dreturn(7);
862 }
863
864 if (decodeTLV)
865 TLVPrintFromBuffer(buf, len);
866
867 // CDA
868 PrintAndLog("\n* CDA:");
869 struct tlvdb *ac_tlv = tlvdb_parse_multi(buf, len);
870 res = trCDA(tlvRoot, ac_tlv, pdol_data_tlv, cdol_data_tlv);
871 if (res) {
872 PrintAndLog("CDA error (%d)", res);
873 }
874 free(ac_tlv);
875 free(cdol_data_tlv);
876
877 PrintAndLog("\n* M/Chip transaction result:");
878 // 9F27: Cryptogram Information Data (CID)
879 const struct tlv *CID = tlvdb_get(tlvRoot, 0x9F27, NULL);
880 if (CID) {
881 emv_tag_dump(CID, stdout, 0);
882 PrintAndLog("------------------------------");
883 if (CID->len > 0) {
884 switch(CID->value[0] & EMVAC_AC_MASK){
885 case EMVAC_AAC:
886 PrintAndLog("Transaction DECLINED.");
887 break;
888 case EMVAC_TC:
889 PrintAndLog("Transaction approved OFFLINE.");
890 break;
891 case EMVAC_ARQC:
892 PrintAndLog("Transaction approved ONLINE.");
893 break;
894 default:
895 PrintAndLog("ERROR: CID transaction code error %2x", CID->value[0] & EMVAC_AC_MASK);
896 break;
897 }
898 } else {
899 PrintAndLog("ERROR: Wrong CID length %d", CID->len);
900 }
901 } else {
902 PrintAndLog("ERROR: CID(9F27) not found.");
903 }
904
905 }
906 }
907
908 // MSD
909 if (AIP & 0x8000 && TrType == TT_MSD) {
910 PrintAndLog("\n--> MSD transaction.");
911
912 PrintAndLog("* MSD dCVV path. Check dCVV");
913
914 const struct tlv *track2 = tlvdb_get(tlvRoot, 0x57, NULL);
915 if (track2) {
916 PrintAndLog("Track2: %s", sprint_hex(track2->value, track2->len));
917
918 struct tlvdb *dCVV = GetdCVVRawFromTrack2(track2);
919 PrintAndLog("dCVV raw data:");
920 TLVPrintFromTLV(dCVV);
921
922 if (GetCardPSVendor(AID, AIDlen) == CV_MASTERCARD) {
923 PrintAndLog("\n* Mastercard calculate UDOL");
924
925 // UDOL (9F69)
926 const struct tlv *UDOL = tlvdb_get(tlvRoot, 0x9F69, NULL);
927 // UDOL(9F69) default: 9F6A (Unpredictable number) 4 bytes
928 const struct tlv defUDOL = {
929 .tag = 0x01,
930 .len = 3,
931 .value = (uint8_t *)"\x9f\x6a\x04",
932 };
933 if (!UDOL)
934 PrintAndLog("Use default UDOL.");
935
936 struct tlv *udol_data_tlv = dol_process(UDOL ? UDOL : &defUDOL, tlvRoot, 0x01); // 0x01 - dummy tag
937 if (!udol_data_tlv){
938 PrintAndLog("ERROR: can't create UDOL TLV.");
939 dreturn(8);
940 }
941
942 PrintAndLog("UDOL data[%d]: %s", udol_data_tlv->len, sprint_hex(udol_data_tlv->value, udol_data_tlv->len));
943
944 PrintAndLog("\n* Mastercard compute cryptographic checksum(UDOL)");
945
946 res = MSCComputeCryptoChecksum(true, (uint8_t *)udol_data_tlv->value, udol_data_tlv->len, buf, sizeof(buf), &len, &sw, tlvRoot);
947 if (res) {
948 PrintAndLog("ERROR Compute Crypto Checksum. APDU error %4x", sw);
949 free(udol_data_tlv);
950 dreturn(9);
951 }
952
953 if (decodeTLV) {
954 TLVPrintFromBuffer(buf, len);
955 PrintAndLog("");
956 }
957 free(udol_data_tlv);
958
959 }
960 } else {
961 PrintAndLog("ERROR MSD: Track2 data not found.");
962 }
963 }
964
965 // DropField
966 DropField();
967
968 // Destroy TLV's
969 free(pdol_data_tlv);
970 tlvdb_free(tlvSelect);
971 tlvdb_free(tlvRoot);
972
973 PrintAndLog("\n* Transaction completed.");
974
975 return 0;
976 }
977
978 int UsageCmdHFEMVScan(void) {
979 PrintAndLog("HELP : Scan EMV card and save it contents to a file. \n");
980 PrintAndLog(" It executes EMV contactless transaction and saves result to a file which can be used for emulation.\n");
981 PrintAndLog("Usage: hf emv scan [-a][-t][-v][-c][-x][-g] <file_name>\n");
982 PrintAndLog(" Options:");
983 PrintAndLog(" -a : show APDU reqests and responses\n");
984 PrintAndLog(" -t : TLV decode results\n");
985 PrintAndLog(" -v : transaction type - qVSDC or M/Chip.\n");
986 PrintAndLog(" -c : transaction type - qVSDC or M/Chip plus CDA (SDAD generation).\n");
987 PrintAndLog(" -x : transaction type - VSDC. For test only. Not a standart behavior.\n");
988 PrintAndLog(" -g : VISA. generate AC from GPO\n");
989 PrintAndLog("By default : transaction type - MSD.\n");
990 PrintAndLog("Samples:");
991 PrintAndLog(" hf emv scan -a -t -> scan MSD transaction mode");
992 PrintAndLog(" hf emv scan -a -t -c -> scan CDA transaction mode");
993 return 0;
994 }
995
996 int CmdHFEMVScan(const char *cmd) {
997 UsageCmdHFEMVScan();
998
999 return 0;
1000 }
1001
1002 int CmdHFEMVTest(const char *cmd) {
1003 return ExecuteCryptoTests(true);
1004 }
1005
1006 int CmdHelp(const char *Cmd);
1007 static command_t CommandTable[] = {
1008 {"help", CmdHelp, 1, "This help"},
1009 {"exec", CmdHFEMVExec, 0, "Executes EMV contactless transaction."},
1010 {"pse", CmdHFEMVPPSE, 0, "Execute PPSE. It selects 2PAY.SYS.DDF01 or 1PAY.SYS.DDF01 directory."},
1011 {"search", CmdHFEMVSearch, 0, "Try to select all applets from applets list and print installed applets."},
1012 {"select", CmdHFEMVSelect, 0, "Select applet."},
1013 // {"scan", CmdHFEMVScan, 0, "Scan EMV card and save it contents to json file for emulator."},
1014 {"test", CmdHFEMVTest, 0, "Crypto logic test."},
1015 {NULL, NULL, 0, NULL}
1016 };
1017
1018 int CmdHFEMV(const char *Cmd) {
1019 CmdsParse(CommandTable, Cmd);
1020 return 0;
1021 }
1022
1023 int CmdHelp(const char *Cmd) {
1024 CmdsHelp(CommandTable);
1025 return 0;
1026 }
Impressum, Datenschutz