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