2
2
* @file emv_ttl_pcsc_test.c
3
3
* @brief Unit tests for EMV TTL APDU cases using typical PC/SC APDUs
4
4
*
5
- * Copyright (c) 2021 Leon Lynch
5
+ * Copyright (c) 2021, 2024 Leon Lynch
6
6
*
7
7
* This program is free software; you can redistribute it and/or
8
8
* modify it under the terms of the GNU Lesser General Public
20
20
*/
21
21
22
22
#include "emv_ttl.h"
23
+ #include "emv_cardreader_emul.h"
23
24
24
25
#include <stdint.h>
25
26
#include <stdio.h>
26
27
#include <string.h>
27
28
28
29
// For debug output
30
+ #include "emv_debug.h"
29
31
#include "print_helpers.h"
30
32
31
- struct apdu_t {
32
- size_t c_apdu_len ;
33
- const uint8_t * c_apdu ;
34
- size_t r_apdu_len ;
35
- const uint8_t * r_apdu ;
36
- };
37
-
38
33
// PC/SC exchanges for case 1 normal processing
39
34
// See EMV 4.3 Book 1, Annex A1
40
- static const struct apdu_t test_pcsc_case_1_normal [] = {
35
+ static const struct xpdu_t test_pcsc_case_1_normal [] = {
41
36
{
42
37
4 , (uint8_t []){ 0x12 , 0x34 , 0x56 , 0x78 },
43
38
2 , (uint8_t []){ 0x90 , 0x00 },
@@ -48,7 +43,7 @@ static const uint8_t test_pcsc_case_1_normal_data[] = { 0x90, 0x00 };
48
43
49
44
// PC/SC exchanges for case 1 error processing
50
45
// See EMV 4.3 Book 1, Annex A1
51
- static const struct apdu_t test_pcsc_case_1_error [] = {
46
+ static const struct xpdu_t test_pcsc_case_1_error [] = {
52
47
{
53
48
4 , (uint8_t []){ 0x12 , 0x34 , 0x56 , 0x78 },
54
49
2 , (uint8_t []){ 0x6A , 0x81 }, // Function not supported
@@ -59,7 +54,7 @@ static const uint8_t test_pcsc_case_1_error_data[] = { 0x6A, 0x81 };
59
54
60
55
// PC/SC exchanges for case 2 normal processing
61
56
// See EMV 4.3 Book 1, Annex A2
62
- static const struct apdu_t test_pcsc_case_2_normal [] = {
57
+ static const struct xpdu_t test_pcsc_case_2_normal [] = {
63
58
{
64
59
5 , (uint8_t []){ 0x00 , 0xB2 , 0x01 , 0x0C , 0x00 }, // READ RECORD 1,1
65
60
2 , (uint8_t []){ 0x6C , 0x1C },
@@ -76,7 +71,7 @@ static const uint8_t test_pcsc_case_2_normal_data[] = {
76
71
77
72
// PC/SC exchanges for case 2 error processing (early)
78
73
// See EMV 4.3 Book 1, Annex A2
79
- static const struct apdu_t test_pcsc_case_2_error_early [] = {
74
+ static const struct xpdu_t test_pcsc_case_2_error_early [] = {
80
75
{
81
76
5 , (uint8_t []){ 0x00 , 0xB2 , 0x01 , 0x0C , 0x00 }, // READ RECORD 1,1
82
77
2 , (uint8_t []){ 0x6A , 0x81 }, // Function not supported
@@ -87,7 +82,7 @@ static const uint8_t test_pcsc_case_2_error_early_data[] = { 0x6A, 0x81 };
87
82
88
83
// PC/SC exchanges for case 2 error processing (late)
89
84
// See EMV 4.3 Book 1, Annex A2
90
- static const struct apdu_t test_pcsc_case_2_error_late [] = {
85
+ static const struct xpdu_t test_pcsc_case_2_error_late [] = {
91
86
{
92
87
5 , (uint8_t []){ 0x00 , 0xB2 , 0x01 , 0x0C , 0x00 }, // READ RECORD 1,1
93
88
2 , (uint8_t []){ 0x6C , 0x1C },
@@ -102,7 +97,7 @@ static const uint8_t test_pcsc_case_2_error_late_data[] = { 0x65, 0x81 };
102
97
103
98
// PC/SC exchanges for case 3 normal processing
104
99
// See EMV 4.3 Book 1, Annex A3
105
- static const struct apdu_t test_pcsc_case_3_normal [] = {
100
+ static const struct xpdu_t test_pcsc_case_3_normal [] = {
106
101
{
107
102
9 , (uint8_t []){ 0x00 , 0x82 , 0x00 , 0x00 , 0x04 , 0xde , 0xad , 0xbe , 0xef }, // EXTERNAL AUTHENTICATE
108
103
2 , (uint8_t []){ 0x90 , 0x00 },
@@ -113,7 +108,7 @@ static const uint8_t test_pcsc_case_3_normal_data[] = { 0x90, 0x00 };
113
108
114
109
// PC/SC exchanges for case 3 error processing
115
110
// See EMV 4.3 Book 1, Annex A3
116
- static const struct apdu_t test_pcsc_case_3_error [] = {
111
+ static const struct xpdu_t test_pcsc_case_3_error [] = {
117
112
{
118
113
9 , (uint8_t []){ 0x00 , 0x82 , 0x00 , 0x00 , 0x04 , 0xde , 0xad , 0xbe , 0xef }, // EXTERNAL AUTHENTICATE
119
114
2 , (uint8_t []){ 0x6A , 0x81 }, // Function not supported
@@ -123,7 +118,7 @@ static const uint8_t test_pcsc_case_3_error_data[] = { 0x6A, 0x81 };
123
118
124
119
// PC/SC exchanges for case 4 normal processing
125
120
// See EMV 4.3 Book 1, Annex A4
126
- static const struct apdu_t test_pcsc_case_4_normal [] = {
121
+ static const struct xpdu_t test_pcsc_case_4_normal [] = {
127
122
{
128
123
20 , (uint8_t []){ 0x00 , 0xA4 , 0x04 , 0x00 , 0x0E , 0x31 , 0x50 , 0x41 , 0x59 , 0x2E , 0x53 , 0x59 , 0x53 , 0x2E , 0x44 , 0x44 , 0x46 , 0x30 , 0x31 , 0x00 }, // SELECT
129
124
2 , (uint8_t []){ 0x61 , 0x26 },
@@ -140,7 +135,7 @@ static const uint8_t test_pcsc_case_4_normal_data[] = {
140
135
141
136
// PC/SC exchanges for case 4 error processing
142
137
// See EMV 4.3 Book 1, Annex A4
143
- static const struct apdu_t test_pcsc_case_4_error_early [] = {
138
+ static const struct xpdu_t test_pcsc_case_4_error_early [] = {
144
139
{
145
140
20 , (uint8_t []){ 0x00 , 0xA4 , 0x04 , 0x00 , 0x0E , 0x31 , 0x50 , 0x41 , 0x59 , 0x2E , 0x53 , 0x59 , 0x53 , 0x2E , 0x44 , 0x44 , 0x46 , 0x30 , 0x31 , 0x00 }, // SELECT
146
141
2 , (uint8_t []){ 0x6A , 0x82 }, // File or application not found
@@ -151,7 +146,7 @@ static const uint8_t test_pcsc_case_4_error_early_data[] = { 0x6A, 0x82 };
151
146
152
147
// PC/SC exchanges for case 4 error processing (late)
153
148
// See EMV 4.3 Book 1, Annex A4
154
- static const struct apdu_t test_pcsc_case_4_error_late [] = {
149
+ static const struct xpdu_t test_pcsc_case_4_error_late [] = {
155
150
{
156
151
20 , (uint8_t []){ 0x00 , 0xA4 , 0x04 , 0x00 , 0x0E , 0x31 , 0x50 , 0x41 , 0x59 , 0x2E , 0x53 , 0x59 , 0x53 , 0x2E , 0x44 , 0x44 , 0x46 , 0x30 , 0x31 , 0x00 }, // SELECT
157
152
2 , (uint8_t []){ 0x61 , 0x26 },
@@ -166,7 +161,7 @@ static const uint8_t test_pcsc_case_4_error_late_data[] = { 0x65, 0x81 };
166
161
167
162
// PC/SC exchanges for case 2 using both '61' and '6C' procedure bytes
168
163
// See EMV 4.3 Book 1, Annex A5
169
- static const struct apdu_t test_pcsc_case_2_normal_advanced [] = {
164
+ static const struct xpdu_t test_pcsc_case_2_normal_advanced [] = {
170
165
{
171
166
5 , (uint8_t []){ 0x00 , 0xB2 , 0x01 , 0x0C , 0x00 }, // READ RECORD 1,1
172
167
2 , (uint8_t []){ 0x6C , 0x1C },
@@ -193,7 +188,7 @@ static const uint8_t test_pcsc_case_2_normal_advanced_data[] = {
193
188
194
189
// PC/SC exchanges for case 4 (using multiple '61' procedure bytes)
195
190
// See EMV 4.3 Book 1, Annex A6
196
- static const struct apdu_t test_pcsc_case_4_normal_advanced [] = {
191
+ static const struct xpdu_t test_pcsc_case_4_normal_advanced [] = {
197
192
{
198
193
20 , (uint8_t []){ 0x00 , 0xA4 , 0x04 , 0x00 , 0x0E , 0x31 , 0x50 , 0x41 , 0x59 , 0x2E , 0x53 , 0x59 , 0x53 , 0x2E , 0x44 , 0x44 , 0x46 , 0x30 , 0x31 , 0x00 }, // SELECT
199
194
2 , (uint8_t []){ 0x61 , 0x26 },
@@ -214,7 +209,7 @@ static const uint8_t test_pcsc_case_4_normal_advanced_data[] = {
214
209
215
210
// PC/SC exchanges for case 4 warning processing
216
211
// See EMV 4.3 Book 1, Annex A4
217
- static const struct apdu_t test_pcsc_case_4_warning [] = {
212
+ static const struct xpdu_t test_pcsc_case_4_warning [] = {
218
213
{
219
214
20 , (uint8_t []){ 0x00 , 0xA4 , 0x04 , 0x00 , 0x0E , 0x31 , 0x50 , 0x41 , 0x59 , 0x2E , 0x53 , 0x59 , 0x53 , 0x2E , 0x44 , 0x44 , 0x46 , 0x30 , 0x31 , 0x00 }, // SELECT
220
215
2 , (uint8_t []){ 0x62 , 0x86 }, // No input available from a sensor on the card
@@ -233,50 +228,12 @@ static const uint8_t test_pcsc_case_4_warning_data[] = {
233
228
0x6F , 0x24 , 0x84 , 0x0E , 0x31 , 0x50 , 0x41 , 0x59 , 0x2E , 0x53 , 0x59 , 0x53 , 0x2E , 0x44 , 0x44 , 0x46 , 0x30 , 0x31 , 0xA5 , 0x12 , 0x88 , 0x01 , 0x01 , 0x5F , 0x2D , 0x08 , 0x65 , 0x6E , 0x65 , 0x73 , 0x66 , 0x72 , 0x64 , 0x65 , 0x9F , 0x11 , 0x01 , 0x01 ,
234
229
};
235
230
236
- struct emv_cardreader_ctx_t {
237
- const struct apdu_t * apdu_list ;
238
- const struct apdu_t * apdu_current ;
239
- };
240
-
241
- static int emv_cardreader_emul (
242
- void * ctx ,
243
- const void * tx_buf ,
244
- size_t tx_buf_len ,
245
- void * rx_buf ,
246
- size_t * rx_buf_len
247
- ) {
248
- struct emv_cardreader_ctx_t * emul_ctx = ctx ;
249
- const struct apdu_t * apdu ;
250
-
251
- if (!emul_ctx -> apdu_current ) {
252
- emul_ctx -> apdu_current = emul_ctx -> apdu_list ;
253
- }
254
- if (!emul_ctx -> apdu_current -> c_apdu_len ) {
255
- return -101 ;
256
- }
257
- apdu = emul_ctx -> apdu_current ;
258
-
259
- if (tx_buf_len != apdu -> c_apdu_len ) {
260
- return -102 ;
261
- }
262
- if (memcmp (tx_buf , apdu -> c_apdu , apdu -> c_apdu_len ) != 0 ) {
263
- return -103 ;
264
- }
265
-
266
- memcpy (rx_buf , apdu -> r_apdu , apdu -> r_apdu_len );
267
- * rx_buf_len = apdu -> r_apdu_len ;
268
-
269
- emul_ctx -> apdu_current ++ ;
270
-
271
- return 0 ;
272
- }
273
-
274
231
int main (void )
275
232
{
276
233
int r ;
277
234
278
235
struct emv_ttl_t ttl ;
279
- struct emv_cardreader_ctx_t emul_ctx ;
236
+ struct emv_cardreader_emul_ctx_t emul_ctx ;
280
237
ttl .cardreader .mode = EMV_CARDREADER_MODE_APDU ;
281
238
ttl .cardreader .ctx = & emul_ctx ;
282
239
ttl .cardreader .trx = & emv_cardreader_emul ;
@@ -287,10 +244,17 @@ int main(void)
287
244
size_t data_len ;
288
245
uint16_t sw1sw2 ;
289
246
247
+ // Enable debug output
248
+ r = emv_debug_init (EMV_DEBUG_SOURCE_ALL , EMV_DEBUG_ALL , & print_emv_debug );
249
+ if (r ) {
250
+ fprintf (stderr , "emv_debug_init() failed; r=%d\n" , r );
251
+ return 1 ;
252
+ }
253
+
290
254
// Test APDU case 1; normal processing
291
255
printf ("\nTesting APDU case 1 (PC/SC mode); normal processing...\n" );
292
- emul_ctx .apdu_list = test_pcsc_case_1_normal ;
293
- emul_ctx .apdu_current = NULL ;
256
+ emul_ctx .xpdu_list = test_pcsc_case_1_normal ;
257
+ emul_ctx .xpdu_current = NULL ;
294
258
r_apdu_len = sizeof (r_apdu );
295
259
296
260
r = emv_ttl_trx (
@@ -322,8 +286,8 @@ int main(void)
322
286
323
287
// Test APDU case 1; error processing
324
288
printf ("\nTesting APDU case 1 (PC/SC mode); error processing...\n" );
325
- emul_ctx .apdu_list = test_pcsc_case_1_error ;
326
- emul_ctx .apdu_current = NULL ;
289
+ emul_ctx .xpdu_list = test_pcsc_case_1_error ;
290
+ emul_ctx .xpdu_current = NULL ;
327
291
r_apdu_len = sizeof (r_apdu );
328
292
329
293
r = emv_ttl_trx (
@@ -355,8 +319,8 @@ int main(void)
355
319
356
320
// Test APDU case 2; normal processing
357
321
printf ("\nTesting APDU case 2 (PC/SC mode); normal processing...\n" );
358
- emul_ctx .apdu_list = test_pcsc_case_2_normal ;
359
- emul_ctx .apdu_current = NULL ;
322
+ emul_ctx .xpdu_list = test_pcsc_case_2_normal ;
323
+ emul_ctx .xpdu_current = NULL ;
360
324
data_len = sizeof (data );
361
325
362
326
r = emv_ttl_read_record (
@@ -388,8 +352,8 @@ int main(void)
388
352
389
353
// Test APDU case 2; error processing (early)
390
354
printf ("\nTesting APDU case 2 (PC/SC mode); error processing (early)...\n" );
391
- emul_ctx .apdu_list = test_pcsc_case_2_error_early ;
392
- emul_ctx .apdu_current = NULL ;
355
+ emul_ctx .xpdu_list = test_pcsc_case_2_error_early ;
356
+ emul_ctx .xpdu_current = NULL ;
393
357
data_len = sizeof (data );
394
358
395
359
r = emv_ttl_read_record (
@@ -421,8 +385,8 @@ int main(void)
421
385
422
386
// Test APDU case 2; error processing (late)
423
387
printf ("\nTesting APDU case 2 (PC/SC mode); error processing (late)...\n" );
424
- emul_ctx .apdu_list = test_pcsc_case_2_error_late ;
425
- emul_ctx .apdu_current = NULL ;
388
+ emul_ctx .xpdu_list = test_pcsc_case_2_error_late ;
389
+ emul_ctx .xpdu_current = NULL ;
426
390
data_len = sizeof (data );
427
391
428
392
r = emv_ttl_read_record (
@@ -454,8 +418,8 @@ int main(void)
454
418
455
419
// Test APDU case 3; normal processing
456
420
printf ("\nTesting APDU case 3 (PC/SC mode); normal processing...\n" );
457
- emul_ctx .apdu_list = test_pcsc_case_3_normal ;
458
- emul_ctx .apdu_current = NULL ;
421
+ emul_ctx .xpdu_list = test_pcsc_case_3_normal ;
422
+ emul_ctx .xpdu_current = NULL ;
459
423
r_apdu_len = sizeof (r_apdu );
460
424
461
425
r = emv_ttl_trx (
@@ -487,8 +451,8 @@ int main(void)
487
451
488
452
// Test APDU case 3; error processing
489
453
printf ("\nTesting APDU case 3 (PC/SC mode); error processing...\n" );
490
- emul_ctx .apdu_list = test_pcsc_case_3_error ;
491
- emul_ctx .apdu_current = NULL ;
454
+ emul_ctx .xpdu_list = test_pcsc_case_3_error ;
455
+ emul_ctx .xpdu_current = NULL ;
492
456
r_apdu_len = sizeof (r_apdu );
493
457
494
458
r = emv_ttl_trx (
@@ -520,8 +484,8 @@ int main(void)
520
484
521
485
// Test APDU case 4; normal processing
522
486
printf ("\nTesting APDU case 4 (PC/SC mode); normal processing...\n" );
523
- emul_ctx .apdu_list = test_pcsc_case_4_normal ;
524
- emul_ctx .apdu_current = NULL ;
487
+ emul_ctx .xpdu_list = test_pcsc_case_4_normal ;
488
+ emul_ctx .xpdu_current = NULL ;
525
489
data_len = sizeof (data );
526
490
527
491
const uint8_t PSE [] = "1PAY.SYS.DDF01" ;
@@ -554,8 +518,8 @@ int main(void)
554
518
555
519
// Test APDU case 4; error processing (early)
556
520
printf ("\nTesting APDU case 4 (PC/SC mode); error processing (early)...\n" );
557
- emul_ctx .apdu_list = test_pcsc_case_4_error_early ;
558
- emul_ctx .apdu_current = NULL ;
521
+ emul_ctx .xpdu_list = test_pcsc_case_4_error_early ;
522
+ emul_ctx .xpdu_current = NULL ;
559
523
data_len = sizeof (data );
560
524
561
525
r = emv_ttl_select_by_df_name (
@@ -587,8 +551,8 @@ int main(void)
587
551
588
552
// Test APDU case 4; error processing (late)
589
553
printf ("\nTesting APDU case 4 (PC/SC mode); error processing (late)...\n" );
590
- emul_ctx .apdu_list = test_pcsc_case_4_error_late ;
591
- emul_ctx .apdu_current = NULL ;
554
+ emul_ctx .xpdu_list = test_pcsc_case_4_error_late ;
555
+ emul_ctx .xpdu_current = NULL ;
592
556
data_len = sizeof (data );
593
557
594
558
r = emv_ttl_select_by_df_name (
@@ -620,8 +584,8 @@ int main(void)
620
584
621
585
// Test APDU case 2; normal processing (using both '61' and '6C' procedure bytes)
622
586
printf ("\nTesting APDU case 2 (PC/SC mode); normal processing (using both '61' and '6C' procedure bytes)...\n" );
623
- emul_ctx .apdu_list = test_pcsc_case_2_normal_advanced ;
624
- emul_ctx .apdu_current = NULL ;
587
+ emul_ctx .xpdu_list = test_pcsc_case_2_normal_advanced ;
588
+ emul_ctx .xpdu_current = NULL ;
625
589
data_len = sizeof (data );
626
590
627
591
r = emv_ttl_read_record (
@@ -653,8 +617,8 @@ int main(void)
653
617
654
618
// Test APDU case 4; normal processing (using multiple '61' procedure bytes)
655
619
printf ("\nTesting APDU case 4 (PC/SC mode); normal processing (using multiple '61' procedure bytes)...\n" );
656
- emul_ctx .apdu_list = test_pcsc_case_4_normal_advanced ;
657
- emul_ctx .apdu_current = NULL ;
620
+ emul_ctx .xpdu_list = test_pcsc_case_4_normal_advanced ;
621
+ emul_ctx .xpdu_current = NULL ;
658
622
data_len = sizeof (data );
659
623
660
624
r = emv_ttl_select_by_df_name (
@@ -686,8 +650,8 @@ int main(void)
686
650
687
651
// Test APDU case 4; warning processing
688
652
printf ("\nTesting APDU case 4 (PC/SC mode); warning processing...\n" );
689
- emul_ctx .apdu_list = test_pcsc_case_4_warning ;
690
- emul_ctx .apdu_current = NULL ;
653
+ emul_ctx .xpdu_list = test_pcsc_case_4_warning ;
654
+ emul_ctx .xpdu_current = NULL ;
691
655
data_len = sizeof (data );
692
656
693
657
r = emv_ttl_select_by_df_name (
0 commit comments