Branch data Line data Source code
1 : : /*
2 : : * Test general functionality of software emulated smart card
3 : : *
4 : : * Copyright 2018 - 2022 Red Hat, Inc.
5 : : *
6 : : * Authors:
7 : : * Marc-André Lureau <marcandre.lureau@redhat.com>
8 : : * Jakub Jelen <jjelen@redhat.com>
9 : : *
10 : : * This code is licensed under the GNU LGPL, version 2.1 or later.
11 : : * See the COPYING file in the top-level directory.
12 : : */
13 : : #include <glib.h>
14 : : #include <string.h>
15 : : #include "libcacard.h"
16 : : #include "simpletlv.h"
17 : : #include "common.h"
18 : : #include "src/common.h"
19 : :
20 : : #define ARGS "db=\"sql:%s\" use_hw=no soft=(,Test,CAC,,cert1,cert2,cert3)"
21 : :
22 : : static GMainLoop *loop;
23 : : static GThread *thread;
24 : : static guint nreaders;
25 : : static GMutex mutex;
26 : : static GCond cond;
27 : :
28 : : static gpointer
29 : 1 : events_thread(G_GNUC_UNUSED gpointer arg)
30 : : {
31 : : unsigned int reader_id;
32 : : VEvent *event;
33 : :
34 : : while (1) {
35 : 6 : event = vevent_wait_next_vevent();
36 [ + + ]: 6 : if (event->type == VEVENT_LAST) {
37 : 1 : vevent_delete(event);
38 : : break;
39 : : }
40 : 5 : reader_id = vreader_get_id(event->reader);
41 [ + + ]: 5 : if (reader_id == VSCARD_UNDEFINED_READER_ID) {
42 : 1 : g_mutex_lock(&mutex);
43 : 1 : vreader_set_id(event->reader, nreaders++);
44 : 1 : g_cond_signal(&cond);
45 : 1 : g_mutex_unlock(&mutex);
46 : 1 : reader_id = vreader_get_id(event->reader);
47 : : }
48 [ - + ]: 5 : switch (event->type) {
49 : : case VEVENT_READER_INSERT:
50 : : case VEVENT_READER_REMOVE:
51 : : case VEVENT_CARD_INSERT:
52 : : case VEVENT_CARD_REMOVE:
53 : : break;
54 : 0 : case VEVENT_LAST:
55 : : default:
56 : 0 : g_warn_if_reached();
57 : 0 : break;
58 : : }
59 : 5 : vevent_delete(event);
60 : : }
61 : :
62 : 1 : return NULL;
63 : : }
64 : :
65 : 1 : static void libcacard_init(void)
66 : : {
67 : : VCardEmulOptions *command_line_options = NULL;
68 : 1 : gchar *dbdir = g_test_build_filename(G_TEST_DIST, "db", NULL);
69 : 1 : gchar *args = g_strdup_printf(ARGS, dbdir);
70 : : VReader *r;
71 : : VCardEmulError ret;
72 : :
73 : 1 : thread = g_thread_new("test/events", events_thread, NULL);
74 : :
75 : 1 : command_line_options = vcard_emul_options(args);
76 : 1 : ret = vcard_emul_init(command_line_options);
77 [ - + ]: 1 : g_assert_cmpint(ret, ==, VCARD_EMUL_OK);
78 : :
79 : 1 : r = vreader_get_reader_by_name("Test");
80 [ - + ]: 1 : g_assert_nonnull(r);
81 : 1 : vreader_free(r); /* get by name ref */
82 : :
83 : 1 : g_mutex_lock(&mutex);
84 [ - + ]: 1 : while (nreaders == 0)
85 : 0 : g_cond_wait(&cond, &mutex);
86 : 1 : g_mutex_unlock(&mutex);
87 : :
88 : 1 : g_free(args);
89 : 1 : g_free(dbdir);
90 : 1 : }
91 : :
92 : 1 : static void test_hex_dump(void)
93 : : {
94 : : unsigned char binary_data[4000];
95 : : unsigned int i;
96 : 1 : const char expected_data[] = "0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07*";
97 : :
98 [ + + ]: 4001 : for (i = 0; i < G_N_ELEMENTS(binary_data); i++) {
99 : 4000 : binary_data[i] = i & 0xff;
100 : : }
101 : :
102 : 1 : g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, expected_data);
103 : 1 : g_debug("%s", hex_dump(binary_data, G_N_ELEMENTS(binary_data)));
104 : 1 : g_test_assert_expected_messages();
105 : :
106 : 1 : g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, expected_data);
107 : 1 : g_debug("%s", hex_dump(binary_data, 8));
108 : 1 : g_test_assert_expected_messages();
109 : 1 : }
110 : :
111 : 1 : static void test_list(void)
112 : : {
113 : 1 : VReaderList *list = vreader_get_reader_list();
114 : : VReaderListEntry *reader_entry;
115 : : int cards = 0;
116 : :
117 [ + + ]: 2 : for (reader_entry = vreader_list_get_first(list); reader_entry;
118 : 1 : reader_entry = vreader_list_get_next(reader_entry)) {
119 : 1 : VReader *r = vreader_list_get_reader(reader_entry);
120 : : vreader_id_t id;
121 : 1 : id = vreader_get_id(r);
122 [ - + ]: 1 : g_assert_cmpstr(vreader_get_name(r), ==, "Test");
123 [ - + ]: 1 : g_assert_cmpint(id, !=, VSCARD_UNDEFINED_READER_ID);
124 [ + - ]: 1 : if (vreader_card_is_present(r) == VREADER_OK) {
125 : 1 : cards++;
126 : : }
127 : 1 : vreader_free(r);
128 : : }
129 [ - + ]: 1 : g_assert_cmpint(cards, ==, 1);
130 : 1 : vreader_list_delete(list);
131 : 1 : }
132 : :
133 : 1 : static void test_card_remove_insert(void)
134 : : {
135 : 1 : VReader *reader = vreader_get_reader_by_id(0);
136 : : VCardEmulError error;
137 : :
138 [ - + ]: 1 : g_assert_nonnull(reader);
139 : :
140 : 1 : error = vcard_emul_force_card_remove(reader);
141 [ - + ]: 1 : g_assert_cmpint(error, ==, VCARD_EMUL_OK);
142 [ - + ]: 1 : g_assert_cmpint(vreader_card_is_present(reader), ==, VREADER_NO_CARD);
143 : :
144 : 1 : error = vcard_emul_force_card_remove(reader);
145 [ - + ]: 1 : g_assert_cmpint(error, ==, VCARD_EMUL_FAIL);
146 [ - + ]: 1 : g_assert_cmpint(vreader_card_is_present(reader), ==, VREADER_NO_CARD);
147 : :
148 : 1 : error = vcard_emul_force_card_insert(reader);
149 [ - + ]: 1 : g_assert_cmpint(error, ==, VCARD_EMUL_OK);
150 [ - + ]: 1 : g_assert_cmpint(vreader_card_is_present(reader), ==, VREADER_OK);
151 : :
152 : 1 : error = vcard_emul_force_card_insert(reader);
153 [ - + ]: 1 : g_assert_cmpint(error, ==, VCARD_EMUL_FAIL);
154 [ - + ]: 1 : g_assert_cmpint(vreader_card_is_present(reader), ==, VREADER_OK);
155 : :
156 : 1 : vreader_free(reader); /* get by id ref */
157 : 1 : }
158 : :
159 : 1 : static void test_xfer(void)
160 : : {
161 : 1 : VReader *reader = vreader_get_reader_by_id(0);
162 : : VReaderStatus status;
163 : 1 : int dwRecvLength = APDUBufSize;
164 : : uint8_t pbRecvBuffer[APDUBufSize];
165 : 1 : uint8_t pbSendBuffer[] = {
166 : : /* Select Applet that is not there */
167 : : 0x00, 0xa4, 0x04, 0x00, 0x07, 0x62, 0x76, 0x01, 0xff, 0x00, 0x00, 0x00,
168 : : };
169 : :
170 [ - + ]: 1 : g_assert_nonnull(reader);
171 : 1 : status = vreader_xfr_bytes(reader,
172 : : pbSendBuffer, sizeof(pbSendBuffer),
173 : : pbRecvBuffer, &dwRecvLength);
174 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
175 : 1 : vreader_free(reader); /* get by id ref */
176 : 1 : }
177 : :
178 : 6 : static void parse_acr(uint8_t *buf, int buflen)
179 : : {
180 : : uint8_t *p, *p_end;
181 : : int have_applet_information = 0;
182 : : int num_entries = 0, num_entries_expected = -1;
183 : :
184 : 6 : p = buf;
185 : 6 : p_end = p + buflen - 2;
186 [ + + ]: 47 : while (p < p_end) {
187 : : uint8_t tag;
188 : : size_t vlen;
189 [ - + ]: 41 : if (simpletlv_read_tag(&p, p_end - p, &tag, &vlen) < 0) {
190 : 0 : g_debug("The generated SimpleTLV can not be parsed");
191 : 0 : g_assert_not_reached();
192 : : }
193 [ - + ]: 41 : g_assert_cmpint(vlen, <=, p_end - p);
194 : 41 : g_debug("Tag: 0x%02x, Len: %" G_GSIZE_FORMAT, tag, vlen);
195 [ + + + - : 41 : switch (tag) {
+ ]
196 : 6 : case 0x01: /* Applet Information */
197 [ - + ]: 6 : g_assert_cmpint(vlen, ==, 5);
198 [ - + ]: 6 : g_assert_cmphex(*p, ==, 0x10); /* Applet family */
199 [ - + ]: 6 : g_assert_cmpint(have_applet_information, ==, 0);
200 : : have_applet_information = 1;
201 : : break;
202 : :
203 : 3 : case 0xA1: /* Num ACR Entries */
204 : : case 0x81: /* Num Applet/Objects */
205 : : case 0x91: /* Num AMP Entries */
206 : : case 0x94: /* Num Service Applet Entries */
207 [ - + ]: 3 : g_assert_cmpint(num_entries_expected, ==, -1);
208 [ - + ]: 3 : g_assert_cmpint(num_entries, ==, 0);
209 : 3 : num_entries_expected = *p;
210 : 3 : break;
211 : :
212 : 31 : case 0xA0: /* ACR Entry */
213 : : case 0x80: /* Aplet Entry */
214 : : case 0x90: /* AMP Entry */
215 : : case 0x93: /* Service Entry */
216 : 31 : num_entries++;
217 : 31 : break;
218 : :
219 : : case 0x82: /* Object ACR Entry */
220 : : /* this is only single entry without preceeding tags */
221 : : break;
222 : :
223 : 0 : default:
224 : 0 : g_debug("Unknown tag in object: 0x%02x", tag);
225 : 0 : g_assert_not_reached();
226 : : }
227 : 41 : p += vlen;
228 : : }
229 : :
230 : : /* Every response needs to have exactly one applet information tag */
231 [ - + ]: 6 : g_assert_cmpint(have_applet_information, ==, 1);
232 : : /* The number of entries in the second tag matches the number of entries later */
233 [ + + ]: 6 : if (num_entries_expected != -1) {
234 [ - + ]: 3 : g_assert_cmpint(num_entries, ==, num_entries_expected);
235 : : }
236 : : /* nothing left to read */
237 [ - + ]: 6 : g_assert_true(p == p_end);
238 : 6 : }
239 : :
240 : 1 : static void get_acr(VReader *reader)
241 : : {
242 : 1 : int dwRecvLength = APDUBufSize;
243 : : VReaderStatus status;
244 : : uint8_t pbRecvBuffer[APDUBufSize];
245 : 1 : uint8_t get_acr[] = {
246 : : /* Get ACR [TYPE] [ 0 ] [Le] */
247 : : 0x80, 0x4c, 0x00, 0x00, 0x00
248 : : };
249 : 1 : uint8_t get_acr_arg[] = {
250 : : /* Get ACR [TYPE] [ 0 ] [Lc] [data] [Le] */
251 : : 0x80, 0x4c, 0x01, 0x00, 0x01, 0x0A, 0x00
252 : : };
253 : 1 : uint8_t get_acr_coid[] = {
254 : : /* Get ACR [TYPE] [ 0 ] [Lc] [ data ] [Le] */
255 : : 0x80, 0x4c, 0x12, 0x00, 0x02, 0xDB, 0x00, 0x00
256 : : };
257 : 1 : uint8_t get_acr_aid[] = {
258 : : /* Get ACR [TYPE] [ 0 ] [Lc] [ data ] [Le]*/
259 : : 0x80, 0x4c, 0x11, 0x00, 0x07, 0xA0, 0x00, 0x00, 0x00, 0x79, 0x12, 0x02, 0x00
260 : : };
261 : 1 : uint8_t getresp[] = {
262 : : /* Get Response (max we can get) */
263 : : 0x00, 0xc0, 0x00, 0x00, 0x00
264 : : };
265 : :
266 : : /* P1=0x00: ACR table */
267 : : dwRecvLength = APDUBufSize;
268 : 1 : status = vreader_xfr_bytes(reader,
269 : : get_acr, sizeof(get_acr),
270 : : pbRecvBuffer, &dwRecvLength);
271 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
272 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, >, 2);
273 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
274 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
275 : :
276 : : /* parse the response */
277 : 1 : parse_acr(pbRecvBuffer, dwRecvLength);
278 : :
279 : :
280 : : /* P1=0x01: ACR table by ACRID=0x0A */
281 : 1 : dwRecvLength = APDUBufSize;
282 : 1 : status = vreader_xfr_bytes(reader,
283 : : get_acr_arg, sizeof(get_acr_arg),
284 : : pbRecvBuffer, &dwRecvLength);
285 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
286 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, >, 2);
287 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
288 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
289 : :
290 : : /* parse the response */
291 : 1 : parse_acr(pbRecvBuffer, dwRecvLength);
292 : :
293 : :
294 : : /* P1=0x01: ACR table by ACRID=0x0F (non-existing) */
295 : 1 : get_acr_arg[5] = 0x0F;
296 : 1 : dwRecvLength = APDUBufSize;
297 : 1 : status = vreader_xfr_bytes(reader,
298 : : get_acr_arg, sizeof(get_acr_arg),
299 : : pbRecvBuffer, &dwRecvLength);
300 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
301 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
302 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, 0x6a);
303 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x88);
304 : :
305 : :
306 : : /* P1=0x10: Applet/Object ACR table */
307 : 1 : get_acr[2] = 0x10;
308 : 1 : dwRecvLength = APDUBufSize;
309 : 1 : status = vreader_xfr_bytes(reader,
310 : : get_acr, sizeof(get_acr),
311 : : pbRecvBuffer, &dwRecvLength);
312 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
313 : : /* This one is big, so we will get SW1 = 0x61 without the actual response */
314 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
315 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_RESPONSE_BYTES);
316 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
317 : :
318 : : /* fetch the actual response */
319 : 1 : dwRecvLength = APDUBufSize;
320 : 1 : status = vreader_xfr_bytes(reader,
321 : : getresp, sizeof(getresp),
322 : : pbRecvBuffer, &dwRecvLength);
323 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
324 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, >, 2);
325 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_RESPONSE_BYTES);
326 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], >, 0x00);
327 : :
328 : : /* ignore the rest for now */
329 : :
330 : :
331 : : /* P1=0x11: Applet/Object ACR table by AID */
332 : 1 : dwRecvLength = APDUBufSize;
333 : 1 : status = vreader_xfr_bytes(reader,
334 : : get_acr_aid, sizeof(get_acr_aid),
335 : : pbRecvBuffer, &dwRecvLength);
336 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
337 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, >, 2);
338 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
339 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
340 : :
341 : : /* parse the response */
342 : 1 : parse_acr(pbRecvBuffer, dwRecvLength);
343 : :
344 : :
345 : : /* P1=0x11: unknown AID should fail */
346 : 1 : get_acr_aid[11] = 0x11;
347 : 1 : dwRecvLength = APDUBufSize;
348 : 1 : status = vreader_xfr_bytes(reader,
349 : : get_acr_aid, sizeof(get_acr_aid),
350 : : pbRecvBuffer, &dwRecvLength);
351 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
352 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
353 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_P1_P2_ERROR);
354 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x88);
355 : :
356 : :
357 : : /* P1=0x12: Applet/Object ACR table by OID */
358 : 1 : dwRecvLength = APDUBufSize;
359 : 1 : status = vreader_xfr_bytes(reader,
360 : : get_acr_coid, sizeof(get_acr_coid),
361 : : pbRecvBuffer, &dwRecvLength);
362 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
363 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, >, 2);
364 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
365 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
366 : :
367 : : /* parse the response */
368 : 1 : parse_acr(pbRecvBuffer, dwRecvLength);
369 : :
370 : :
371 : : /* P1=0x12: unknown OID should fail */
372 : 1 : get_acr_coid[6] = 0xDB;
373 : 1 : dwRecvLength = APDUBufSize;
374 : 1 : status = vreader_xfr_bytes(reader,
375 : : get_acr_coid, sizeof(get_acr_coid),
376 : : pbRecvBuffer, &dwRecvLength);
377 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
378 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
379 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_P1_P2_ERROR);
380 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x80);
381 : :
382 : :
383 : : /* P1=0x20: Access Method Provider table */
384 : 1 : get_acr[2] = 0x20;
385 : 1 : dwRecvLength = APDUBufSize;
386 : 1 : status = vreader_xfr_bytes(reader,
387 : : get_acr, sizeof(get_acr),
388 : : pbRecvBuffer, &dwRecvLength);
389 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
390 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, >, 2);
391 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
392 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
393 : :
394 : : /* parse the response */
395 : 1 : parse_acr(pbRecvBuffer, dwRecvLength);
396 : :
397 : :
398 : : /* P1=0x21: Service Applet Table */
399 : 1 : get_acr[2] = 0x21;
400 : 1 : dwRecvLength = APDUBufSize;
401 : 1 : status = vreader_xfr_bytes(reader,
402 : : get_acr, sizeof(get_acr),
403 : : pbRecvBuffer, &dwRecvLength);
404 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
405 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, >, 2);
406 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
407 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
408 : :
409 : : /* parse the response */
410 : 1 : parse_acr(pbRecvBuffer, dwRecvLength);
411 : :
412 : : /* Undocumented 0x40 returns ACR in different encoding */
413 : 1 : get_acr[2] = 0x40;
414 : 1 : dwRecvLength = APDUBufSize;
415 : 1 : status = vreader_xfr_bytes(reader,
416 : : get_acr, sizeof(get_acr),
417 : : pbRecvBuffer, &dwRecvLength);
418 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
419 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, >, 2);
420 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
421 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
422 : :
423 : : /* parse the response */
424 : : //parse_acr(pbRecvBuffer, dwRecvLength);
425 : :
426 : : /* Undocumented 0x50 returns Applet/Object ACR in different encoding */
427 : 1 : get_acr[2] = 0x50;
428 : 1 : dwRecvLength = APDUBufSize;
429 : 1 : status = vreader_xfr_bytes(reader,
430 : : get_acr, sizeof(get_acr),
431 : : pbRecvBuffer, &dwRecvLength);
432 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
433 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
434 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_RESPONSE_BYTES);
435 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
436 : :
437 : : /* parse the response */
438 : : //parse_acr(pbRecvBuffer, dwRecvLength);
439 : :
440 : : /* Undocumented 0x60 returns AMP in different encoding */
441 : 1 : get_acr[2] = 0x60;
442 : 1 : dwRecvLength = APDUBufSize;
443 : 1 : status = vreader_xfr_bytes(reader,
444 : : get_acr, sizeof(get_acr),
445 : : pbRecvBuffer, &dwRecvLength);
446 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
447 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, >, 2);
448 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
449 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
450 : :
451 : : /* parse the response */
452 : : //parse_acr(pbRecvBuffer, dwRecvLength);
453 : :
454 : : /* Undocumented 0x61 returns Service Applet in different encoding */
455 : 1 : get_acr[2] = 0x61;
456 : 1 : dwRecvLength = APDUBufSize;
457 : 1 : status = vreader_xfr_bytes(reader,
458 : : get_acr, sizeof(get_acr),
459 : : pbRecvBuffer, &dwRecvLength);
460 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
461 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, >, 2);
462 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-2], ==, VCARD7816_SW1_SUCCESS);
463 [ - + ]: 1 : g_assert_cmphex(pbRecvBuffer[dwRecvLength-1], ==, 0x00);
464 : :
465 : : /* parse the response */
466 : : //parse_acr(pbRecvBuffer, dwRecvLength);
467 : 1 : }
468 : :
469 : 4 : static void do_login(VReader *reader)
470 : : {
471 : : VReaderStatus status;
472 : 4 : int dwRecvLength = APDUBufSize;
473 : : uint8_t pbRecvBuffer[APDUBufSize];
474 : 4 : uint8_t login[] = {
475 : : /* VERIFY [p1,p2=0 ] [Lc] [empty pin padded to 6 chars ] */
476 : : 0x00, 0x20, 0x00, 0x00, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
477 : : };
478 : 4 : uint8_t login_check[] = {
479 : : /* VERIFY [p1,p2=0 ] [Lc] */
480 : : 0x00, 0x20, 0x00, 0x00, 0x00
481 : : };
482 [ - + ]: 4 : g_assert_nonnull(reader);
483 : 4 : status = vreader_xfr_bytes(reader,
484 : : login, sizeof(login),
485 : : pbRecvBuffer, &dwRecvLength);
486 [ - + ]: 4 : g_assert_cmpint(status, ==, VREADER_OK);
487 [ - + ]: 4 : g_assert_cmphex(pbRecvBuffer[0], ==, VCARD7816_SW1_SUCCESS);
488 [ - + ]: 4 : g_assert_cmphex(pbRecvBuffer[1], ==, 0x00);
489 : :
490 : : /* Check the login status now */
491 : 4 : status = vreader_xfr_bytes(reader,
492 : : login_check, sizeof(login_check),
493 : : pbRecvBuffer, &dwRecvLength);
494 [ - + ]: 4 : g_assert_cmpint(status, ==, VREADER_OK);
495 [ - + ]: 4 : g_assert_cmphex(pbRecvBuffer[0], ==, VCARD7816_SW1_SUCCESS);
496 [ - + ]: 4 : g_assert_cmphex(pbRecvBuffer[1], ==, 0x00);
497 : 4 : }
498 : :
499 : 1 : static void test_cac_pki(void)
500 : : {
501 : 1 : VReader *reader = vreader_get_reader_by_id(0);
502 : :
503 : : /* select the first PKI applet */
504 : 1 : select_applet(reader, TEST_PKI);
505 : :
506 : : /* get properties */
507 : 1 : get_properties(reader, TEST_PKI);
508 : :
509 : : /* get the TAG buffer length */
510 : 1 : read_buffer(reader, CAC_FILE_TAG, TEST_PKI);
511 : :
512 : : /* get the VALUE buffer length */
513 : 1 : read_buffer(reader, CAC_FILE_VALUE, TEST_PKI);
514 : :
515 : 1 : vreader_free(reader); /* get by id ref */
516 : 1 : }
517 : :
518 : 1 : static void test_cac_pki_2(void)
519 : : {
520 : 1 : VReader *reader = vreader_get_reader_by_id(0);
521 : :
522 : : /* select the first PKI applet */
523 : 1 : select_applet(reader, TEST_PKI_2);
524 : :
525 : : /* get properties */
526 : 1 : get_properties(reader, TEST_PKI_2);
527 : :
528 : : /* get the TAG buffer length */
529 : 1 : read_buffer(reader, CAC_FILE_TAG, TEST_PKI_2);
530 : :
531 : : /* get the VALUE buffer length */
532 : 1 : read_buffer(reader, CAC_FILE_VALUE, TEST_PKI_2);
533 : :
534 : 1 : vreader_free(reader); /* get by id ref */
535 : 1 : }
536 : :
537 : 1 : static void test_cac_ccc(void)
538 : : {
539 : 1 : VReader *reader = vreader_get_reader_by_id(0);
540 : :
541 : : /* select the CCC */
542 : 1 : select_applet(reader, TEST_CCC);
543 : :
544 : : /* get properties */
545 : 1 : get_properties(reader, TEST_CCC);
546 : :
547 : : /* get the TAG buffer length */
548 : 1 : read_buffer(reader, CAC_FILE_TAG, TEST_CCC);
549 : :
550 : : /* get the VALUE buffer length */
551 : 1 : read_buffer(reader, CAC_FILE_VALUE, TEST_CCC);
552 : :
553 : 1 : vreader_free(reader); /* get by id ref */
554 : 1 : }
555 : :
556 : 1 : static void test_cac_aca(void)
557 : : {
558 : 1 : VReader *reader = vreader_get_reader_by_id(0);
559 : :
560 : : /* select the ACA */
561 : 1 : select_applet(reader, TEST_ACA);
562 : :
563 : : /* get properties */
564 : 1 : get_properties(reader, TEST_ACA);
565 : :
566 : : /* get ACR */
567 : 1 : get_acr(reader);
568 : :
569 : 1 : vreader_free(reader); /* get by id ref */
570 : 1 : }
571 : :
572 : 1 : static void test_login(void)
573 : : {
574 : 1 : VReader *reader = vreader_get_reader_by_id(0);
575 : :
576 : : /* select the ACA */
577 : 1 : select_applet(reader, TEST_ACA);
578 : :
579 : 1 : do_login(reader);
580 : :
581 : 1 : vreader_free(reader); /* get by id ref */
582 : 1 : }
583 : :
584 : 1 : static void test_sign(void)
585 : : {
586 : 1 : VReader *reader = vreader_get_reader_by_id(0);
587 : :
588 : : /* select the ACA */
589 : 1 : select_applet(reader, TEST_ACA);
590 : :
591 : 1 : do_login(reader);
592 : :
593 : : /* select the PKI */
594 : 1 : select_applet(reader, TEST_PKI);
595 : :
596 : 1 : do_sign(reader, 0);
597 : :
598 : : /* test also multipart signatures */
599 : 1 : do_sign(reader, 1);
600 : :
601 : : /* select the second PKI */
602 : 1 : select_applet(reader, TEST_PKI_2);
603 : :
604 : 1 : do_sign(reader, 0);
605 : :
606 : : /* test also multipart signatures */
607 : 1 : do_sign(reader, 1);
608 : :
609 : 1 : vreader_free(reader); /* get by id ref */
610 : 1 : }
611 : :
612 : 1 : static void test_decipher(void)
613 : : {
614 : 1 : VReader *reader = vreader_get_reader_by_id(0);
615 : :
616 : : /* select the ACA */
617 : 1 : select_applet(reader, TEST_ACA);
618 : :
619 : 1 : do_login(reader);
620 : :
621 : : /* select the PKI */
622 : 1 : select_applet(reader, TEST_PKI);
623 : :
624 : 1 : do_decipher(reader, TEST_PKI);
625 : :
626 : : /* select the PKI */
627 : 1 : select_applet(reader, TEST_PKI_2);
628 : :
629 : 1 : do_decipher(reader, TEST_PKI_2);
630 : :
631 : 1 : vreader_free(reader); /* get by id ref */
632 : 1 : }
633 : :
634 : 1 : static void test_remove(void)
635 : : {
636 : 1 : VReader *reader = vreader_get_reader_by_id(0);
637 : : VReaderStatus status;
638 : :
639 [ - + ]: 1 : g_assert_nonnull(reader);
640 : :
641 : 1 : status = vreader_remove_reader(reader);
642 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
643 : 1 : vreader_free(reader); /* get by id ref */
644 : :
645 : 1 : reader = vreader_get_reader_by_id(0);
646 [ - + ]: 1 : g_assert_null(reader);
647 : 1 : }
648 : :
649 : 1 : static void test_select_coid(void)
650 : : {
651 : 1 : VReader *reader = vreader_get_reader_by_id(0);
652 : 1 : unsigned char coid[] = "\xDB\x00";
653 : 1 : uint8_t acf_aid[] = {
654 : : 0xA0, 0x00, 0x00, 0x01, 0x16, 0x30, 0x00
655 : : };
656 : :
657 : : /* select the CCC */
658 : 1 : select_applet(reader, TEST_CCC);
659 : :
660 : : /* get properties */
661 : 1 : get_properties(reader, TEST_CCC);
662 : :
663 : : /* select existing OID */
664 : 1 : select_coid_good(reader, coid);
665 : :
666 : : /* select non-existing OID */
667 : 1 : coid[1] = 0xDB;
668 : 1 : select_coid_bad(reader, coid);
669 : :
670 : : /* select the ACF */
671 : 1 : select_aid(reader, acf_aid, sizeof(acf_aid));
672 : :
673 : : /* select existing default OID */
674 : 1 : coid[0] = 0x30;
675 : 1 : coid[1] = 0x00;
676 : 1 : select_coid_good(reader, coid);
677 : :
678 : : /* select existing non-default OID */
679 : 1 : coid[0] = 0x90;
680 : 1 : select_coid_good(reader, coid);
681 : :
682 : : /* select non-existing OID */
683 : 1 : coid[1] = 0x90;
684 : 1 : select_coid_bad(reader, coid);
685 : :
686 : 1 : vreader_free(reader); /* get by id ref */
687 : 1 : }
688 : :
689 : 1 : static void test_invalid_apdu(void)
690 : : {
691 : 1 : VReader *reader = vreader_get_reader_by_id(0);
692 : : VReaderStatus status;
693 : 1 : int dwRecvLength = APDUBufSize;
694 : : uint8_t pbRecvBuffer[APDUBufSize];
695 : 1 : uint8_t apdu[] = {
696 : : 0x00, 0x00, 0x01
697 : : };
698 : : size_t apdu_len = 3;
699 : :
700 [ - + ]: 1 : g_assert_nonnull(reader);
701 : :
702 : 1 : dwRecvLength = APDUBufSize;
703 : 1 : status = vreader_xfr_bytes(reader,
704 : : apdu, apdu_len,
705 : : pbRecvBuffer, &dwRecvLength);
706 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
707 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
708 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, 0x67);
709 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x00);
710 : :
711 : 1 : vreader_free(reader); /* get by id ref */
712 : 1 : }
713 : :
714 : 1 : static void test_invalid_properties(void)
715 : : {
716 : 1 : VReader *reader = vreader_get_reader_by_id(0);
717 : : VReaderStatus status;
718 : 1 : int dwRecvLength = APDUBufSize;
719 : : uint8_t pbRecvBuffer[APDUBufSize];
720 : 1 : uint8_t get_properties[] = {
721 : : /* Get properties [Le] [RFU] */
722 : : 0x80, 0x56, 0x01, 0x00, 0x00, 0x00, 0x00
723 : : };
724 : : size_t get_properties_len = 5;
725 : :
726 [ - + ]: 1 : g_assert_nonnull(reader);
727 : :
728 : 1 : select_applet(reader, TEST_CCC);
729 : :
730 : : /* P1 = 0x00 is not supported */
731 : 1 : get_properties[2] = 0x00;
732 : 1 : dwRecvLength = APDUBufSize;
733 : 1 : status = vreader_xfr_bytes(reader,
734 : : get_properties, get_properties_len,
735 : : pbRecvBuffer, &dwRecvLength);
736 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
737 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
738 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_P1_P2_ERROR);
739 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x86);
740 : 1 : get_properties[2] = 0x01;
741 : :
742 : : /* P1 = 0x01 fails with additional data provided */
743 : : get_properties[2] = 0x01;
744 : 1 : get_properties[4] = 0x02;
745 : 1 : dwRecvLength = APDUBufSize;
746 : 1 : status = vreader_xfr_bytes(reader,
747 : : get_properties, sizeof(get_properties),
748 : : pbRecvBuffer, &dwRecvLength);
749 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
750 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
751 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
752 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x84);
753 : 1 : get_properties[2] = 0x01;
754 : :
755 : : /* P2 needs to be zero */
756 : 1 : get_properties[3] = 0x01;
757 : 1 : get_properties[4] = 0x00;
758 : 1 : dwRecvLength = APDUBufSize;
759 : 1 : status = vreader_xfr_bytes(reader,
760 : : get_properties, get_properties_len,
761 : : pbRecvBuffer, &dwRecvLength);
762 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
763 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
764 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_P1_P2_ERROR);
765 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x86);
766 : 1 : get_properties[3] = 0x00;
767 : :
768 : : /* P1 = 0x02 requires some data (empty is invalid) */
769 : 1 : get_properties[2] = 0x02;
770 : 1 : dwRecvLength = APDUBufSize;
771 : 1 : status = vreader_xfr_bytes(reader,
772 : : get_properties, get_properties_len,
773 : : pbRecvBuffer, &dwRecvLength);
774 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
775 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
776 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
777 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x84);
778 : :
779 : : /* P1 = 0x02 with invalid data fails */
780 : 1 : get_properties[4] = 0x02;
781 : 1 : get_properties[6] = 0xFF;
782 : 1 : dwRecvLength = APDUBufSize;
783 : 1 : status = vreader_xfr_bytes(reader,
784 : : get_properties, sizeof(get_properties),
785 : : pbRecvBuffer, &dwRecvLength);
786 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
787 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
788 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_P1_P2_ERROR);
789 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x88);
790 : :
791 : : /* P1 = 0x88 is invalid */
792 : 1 : get_properties[2] = 0x88;
793 : 1 : dwRecvLength = APDUBufSize;
794 : 1 : status = vreader_xfr_bytes(reader,
795 : : get_properties, get_properties_len,
796 : : pbRecvBuffer, &dwRecvLength);
797 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
798 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
799 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_P1_P2_ERROR);
800 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x86);
801 : :
802 : 1 : vreader_free(reader); /* get by id ref */
803 : 1 : }
804 : :
805 : 1 : static void test_invalid_select(void)
806 : : {
807 : 1 : VReader *reader = vreader_get_reader_by_id(0);
808 : : VReaderStatus status;
809 : 1 : int dwRecvLength = APDUBufSize;
810 : : uint8_t pbRecvBuffer[APDUBufSize];
811 : 1 : uint8_t selfile[] = {
812 : : 0x00, 0xa4, 0x02, 0x00, 0x07, 0xa0, 0x00, 0x00, 0x00, 0x79, 0x01, 0x00
813 : : };
814 : :
815 [ - + ]: 1 : g_assert_nonnull(reader);
816 : :
817 : 1 : select_applet(reader, TEST_CCC);
818 : :
819 : : /* CAC applets handle only the P1 = 0x02: Empty OID is not valid */
820 : 1 : selfile[4] = 0x00;
821 : 1 : dwRecvLength = APDUBufSize;
822 : 1 : status = vreader_xfr_bytes(reader,
823 : : selfile, 5,
824 : : pbRecvBuffer, &dwRecvLength);
825 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
826 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
827 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
828 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x84);
829 : :
830 : : /* CAC applets handle only the P1 = 0x02: 7B OID is not valid */
831 : 1 : selfile[4] = 0x07;
832 : 1 : dwRecvLength = APDUBufSize;
833 : 1 : status = vreader_xfr_bytes(reader,
834 : : selfile, sizeof(selfile),
835 : : pbRecvBuffer, &dwRecvLength);
836 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
837 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
838 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
839 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x84);
840 : :
841 : : /* The generic code handles only P1 = 0x04 */
842 : 1 : select_gp(reader);
843 : :
844 : 1 : selfile[2] = 0xff;
845 : 1 : dwRecvLength = APDUBufSize;
846 : 1 : status = vreader_xfr_bytes(reader,
847 : : selfile, sizeof(selfile),
848 : : pbRecvBuffer, &dwRecvLength);
849 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
850 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
851 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, 0x6a);
852 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x81);
853 : :
854 : : /* TODO check the iso7816 code handling the remaining SELECT APDUs */
855 : :
856 : 1 : vreader_free(reader); /* get by id ref */
857 : 1 : }
858 : :
859 : 1 : static void test_invalid_instruction(void)
860 : : {
861 : 1 : VReader *reader = vreader_get_reader_by_id(0);
862 : : VReaderStatus status;
863 : 1 : int dwRecvLength = APDUBufSize;
864 : : uint8_t pbRecvBuffer[APDUBufSize];
865 : 1 : uint8_t apdu[] = {
866 : : 0x00, 0xff, 0x00, 0x00, 0x00
867 : : };
868 : :
869 [ - + ]: 1 : g_assert_nonnull(reader);
870 : :
871 : : /* Card Capability Container */
872 : 1 : select_applet(reader, TEST_CCC);
873 : :
874 : : /* 0xFF is invalid instruction everywhere */
875 : 1 : dwRecvLength = APDUBufSize;
876 : 1 : status = vreader_xfr_bytes(reader,
877 : : apdu, sizeof(apdu),
878 : : pbRecvBuffer, &dwRecvLength);
879 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
880 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
881 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_INS_ERROR);
882 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x00);
883 : :
884 : : /* CCC Applet does not know GET ACR instruction */
885 : 1 : apdu[1] = 0x4c;
886 : 1 : dwRecvLength = APDUBufSize;
887 : 1 : status = vreader_xfr_bytes(reader,
888 : : apdu, sizeof(apdu),
889 : : pbRecvBuffer, &dwRecvLength);
890 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
891 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
892 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_INS_ERROR);
893 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x00);
894 : :
895 : : /* TODO check the iso7816 code handling the remaining SELECT APDUs */
896 : :
897 : : /* GP applet sends most of the instructions to the generic ISO handling */
898 : 1 : select_gp(reader);
899 : :
900 : : /* Secure messaging instructions not supported */
901 : 1 : apdu[1] = 0x70;
902 : 1 : dwRecvLength = APDUBufSize;
903 : 1 : status = vreader_xfr_bytes(reader,
904 : : apdu, sizeof(apdu),
905 : : pbRecvBuffer, &dwRecvLength);
906 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
907 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
908 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
909 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x00);
910 : :
911 : : /* 0xFF is invalid instruction also in the global APDU processing */
912 : 1 : apdu[1] = 0xff;
913 : 1 : dwRecvLength = APDUBufSize;
914 : 1 : status = vreader_xfr_bytes(reader,
915 : : apdu, sizeof(apdu),
916 : : pbRecvBuffer, &dwRecvLength);
917 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
918 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
919 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, 0x69);
920 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x00);
921 : 1 : vreader_free(reader); /* get by id ref */
922 : 1 : }
923 : :
924 : 5 : static void test_invalid_read_buffer_applet(VReader *reader, enum TestObjectType object_type)
925 : : {
926 : :
927 : : VReaderStatus status;
928 : 5 : int dwRecvLength = APDUBufSize;
929 : : uint8_t pbRecvBuffer[APDUBufSize];
930 : 5 : uint8_t apdu[] = {
931 : : 0x00, 0x52, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
932 : : };
933 : : int apdu_len;
934 : :
935 : 5 : select_applet(reader, object_type);
936 : :
937 : : /* Empty body is not accepted */
938 : 5 : apdu[4] = 0x00;
939 : : apdu_len = 5;
940 : 5 : dwRecvLength = APDUBufSize;
941 : 5 : status = vreader_xfr_bytes(reader,
942 : : apdu, apdu_len,
943 : : pbRecvBuffer, &dwRecvLength);
944 [ - + ]: 5 : g_assert_cmpint(status, ==, VREADER_OK);
945 [ - + ]: 5 : g_assert_cmpint(dwRecvLength, ==, 2);
946 [ - + ]: 5 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
947 [ - + ]: 5 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x84);
948 : :
949 : : /* 4B is too much */
950 : 5 : apdu[4] = 0x04;
951 : : apdu_len = 9;
952 : 5 : dwRecvLength = APDUBufSize;
953 : 5 : status = vreader_xfr_bytes(reader,
954 : : apdu, apdu_len,
955 : : pbRecvBuffer, &dwRecvLength);
956 [ - + ]: 5 : g_assert_cmpint(status, ==, VREADER_OK);
957 [ - + ]: 5 : g_assert_cmpint(dwRecvLength, ==, 2);
958 [ - + ]: 5 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
959 [ - + ]: 5 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x84);
960 : :
961 : : /* The first byte is invalid (nor tag, nor value) */
962 : 5 : apdu[4] = 0x02;
963 : 5 : apdu[5] = 0x06;
964 : : apdu_len = 7;
965 : 5 : dwRecvLength = APDUBufSize;
966 : 5 : status = vreader_xfr_bytes(reader,
967 : : apdu, apdu_len,
968 : : pbRecvBuffer, &dwRecvLength);
969 [ - + ]: 5 : g_assert_cmpint(status, ==, VREADER_OK);
970 [ - + ]: 5 : g_assert_cmpint(dwRecvLength, ==, 2);
971 [ - + ]: 5 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
972 [ - + ]: 5 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x84);
973 : :
974 : : /* Read tag: P1 and P2 defines offset -- overunning the buffer should fail */
975 : 5 : apdu[2] = 0x08;
976 : 5 : apdu[3] = 0x08; /* <- Large enough */
977 : 5 : apdu[5] = 0x01;
978 : 5 : dwRecvLength = APDUBufSize;
979 : 5 : status = vreader_xfr_bytes(reader,
980 : : apdu, apdu_len,
981 : : pbRecvBuffer, &dwRecvLength);
982 [ - + ]: 5 : g_assert_cmpint(status, ==, VREADER_OK);
983 [ - + ]: 5 : g_assert_cmpint(dwRecvLength, ==, 2);
984 [ - + ]: 5 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_P1_P2_ERROR);
985 [ - + ]: 5 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x86);
986 : :
987 : : /* Read value: P1 and P2 defines offset -- overunning the buffer should fail */
988 : 5 : apdu[5] = 0x02;
989 : 5 : dwRecvLength = APDUBufSize;
990 : 5 : status = vreader_xfr_bytes(reader,
991 : : apdu, apdu_len,
992 : : pbRecvBuffer, &dwRecvLength);
993 [ - + ]: 5 : g_assert_cmpint(status, ==, VREADER_OK);
994 [ - + ]: 5 : g_assert_cmpint(dwRecvLength, ==, 2);
995 [ - + ]: 5 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_P1_P2_ERROR);
996 [ - + ]: 5 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x86);
997 : 5 : }
998 : :
999 : 1 : static void test_invalid_read_buffer(void)
1000 : : {
1001 : 1 : VReader *reader = vreader_get_reader_by_id(0);
1002 : :
1003 [ - + ]: 1 : g_assert_nonnull(reader);
1004 : :
1005 : 1 : test_invalid_read_buffer_applet(reader, TEST_CCC);
1006 : 1 : test_invalid_read_buffer_applet(reader, TEST_PKI);
1007 : 1 : test_invalid_read_buffer_applet(reader, TEST_PKI_2);
1008 : 1 : test_invalid_read_buffer_applet(reader, TEST_PASSTHROUGH);
1009 : 1 : test_invalid_read_buffer_applet(reader, TEST_EMPTY);
1010 : :
1011 : 1 : vreader_free(reader); /* get by id ref */
1012 : 1 : }
1013 : :
1014 : 5 : static void test_invalid_update_buffer_applet(VReader *reader, enum TestObjectType object_type)
1015 : : {
1016 : :
1017 : : VReaderStatus status;
1018 : 5 : int dwRecvLength = APDUBufSize;
1019 : : uint8_t pbRecvBuffer[APDUBufSize];
1020 : 5 : uint8_t apdu[] = {
1021 : : 0x00, 0x58, 0x00, 0x00, 0x00
1022 : : };
1023 : : int apdu_len = 5;
1024 : :
1025 : 5 : select_applet(reader, object_type);
1026 : :
1027 : : /* Update buffer is not supported */
1028 : 5 : status = vreader_xfr_bytes(reader,
1029 : : apdu, apdu_len,
1030 : : pbRecvBuffer, &dwRecvLength);
1031 [ - + ]: 5 : g_assert_cmpint(status, ==, VREADER_OK);
1032 [ - + ]: 5 : g_assert_cmpint(dwRecvLength, ==, 2);
1033 [ + + ]: 5 : if (object_type == TEST_PKI || object_type == TEST_PKI_2) {
1034 [ - + ]: 2 : g_assert_cmpint(pbRecvBuffer[0], ==, 0x69);
1035 [ - + ]: 2 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x85);
1036 : : } else {
1037 [ - + ]: 3 : g_assert_cmpint(pbRecvBuffer[0], ==, 0x69);
1038 [ - + ]: 3 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x00);
1039 : : }
1040 : 5 : }
1041 : :
1042 : 1 : static void test_invalid_update_buffer(void)
1043 : : {
1044 : 1 : VReader *reader = vreader_get_reader_by_id(0);
1045 : :
1046 [ - + ]: 1 : g_assert_nonnull(reader);
1047 : :
1048 : 1 : test_invalid_update_buffer_applet(reader, TEST_CCC);
1049 : 1 : test_invalid_update_buffer_applet(reader, TEST_PKI);
1050 : 1 : test_invalid_update_buffer_applet(reader, TEST_PKI_2);
1051 : 1 : test_invalid_update_buffer_applet(reader, TEST_PASSTHROUGH);
1052 : 1 : test_invalid_update_buffer_applet(reader, TEST_EMPTY);
1053 : :
1054 : 1 : vreader_free(reader); /* get by id ref */
1055 : 1 : }
1056 : :
1057 : 1 : static void test_invalid_sign(void)
1058 : : {
1059 : 1 : VReader *reader = vreader_get_reader_by_id(0);
1060 : : VReaderStatus status;
1061 : 1 : int dwRecvLength = APDUBufSize;
1062 : : uint8_t pbRecvBuffer[APDUBufSize];
1063 : 1 : uint8_t apdu[] = {
1064 : : 0x00, 0x42, 0x00, 0xff, 0x00
1065 : : };
1066 : : int apdu_len = 5;
1067 : :
1068 [ - + ]: 1 : g_assert_nonnull(reader);
1069 : :
1070 : 1 : select_applet(reader, TEST_PKI);
1071 : :
1072 : : /* Sign/Decipher requires P2 = 0 */
1073 : 1 : status = vreader_xfr_bytes(reader,
1074 : : apdu, apdu_len,
1075 : : pbRecvBuffer, &dwRecvLength);
1076 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
1077 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
1078 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, 0x6a);
1079 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x86);
1080 : :
1081 : : /* Sign/Decipher requires P1 = 0x00 or 0x80 */
1082 : 1 : apdu[3] = 0xff;
1083 : 1 : apdu[4] = 0x00;
1084 : 1 : status = vreader_xfr_bytes(reader,
1085 : : apdu, apdu_len,
1086 : : pbRecvBuffer, &dwRecvLength);
1087 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
1088 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
1089 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, 0x6a);
1090 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x86);
1091 : :
1092 : 1 : vreader_free(reader); /* get by id ref */
1093 : 1 : }
1094 : :
1095 : 1 : static void test_invalid_class(void)
1096 : : {
1097 : 1 : VReader *reader = vreader_get_reader_by_id(0);
1098 : : VReaderStatus status;
1099 : 1 : int dwRecvLength = APDUBufSize;
1100 : : uint8_t pbRecvBuffer[APDUBufSize];
1101 : 1 : uint8_t apdu[] = {
1102 : : 0xfe, 0x42, 0x00, 0xff, 0x00
1103 : : };
1104 : : int apdu_len = 5;
1105 : :
1106 [ - + ]: 1 : g_assert_nonnull(reader);
1107 : :
1108 : 1 : select_gp(reader);
1109 : :
1110 : : /* Only ISO 7816 class(es) supported. Anything else should fail */
1111 : 1 : status = vreader_xfr_bytes(reader,
1112 : : apdu, apdu_len,
1113 : : pbRecvBuffer, &dwRecvLength);
1114 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
1115 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
1116 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, 0x69);
1117 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x00);
1118 : :
1119 : : /* ISO 7816 PTS class is even more special -- it should just reply with the "APDU" sent */
1120 : 1 : apdu[0] = 0xff;
1121 : 1 : dwRecvLength = APDUBufSize;
1122 : 1 : status = vreader_xfr_bytes(reader,
1123 : : apdu, apdu_len,
1124 : : pbRecvBuffer, &dwRecvLength);
1125 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
1126 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 5);
1127 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, 0xff);
1128 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x42);
1129 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[2], ==, 0x00);
1130 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[3], ==, 0xff);
1131 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[4], ==, 0x00);
1132 : :
1133 : : /* 0x0e should be unsupported secure messaging */
1134 : 1 : apdu[0] = 0x0e;
1135 : 1 : status = vreader_xfr_bytes(reader,
1136 : : apdu, apdu_len,
1137 : : pbRecvBuffer, &dwRecvLength);
1138 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
1139 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
1140 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, 0x68);
1141 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x82);
1142 : :
1143 : 1 : vreader_free(reader); /* get by id ref */
1144 : 1 : }
1145 : :
1146 : 1 : static void test_invalid_acr(void)
1147 : : {
1148 : 1 : VReader *reader = vreader_get_reader_by_id(0);
1149 : : VReaderStatus status;
1150 : 1 : int dwRecvLength = APDUBufSize;
1151 : : uint8_t pbRecvBuffer[APDUBufSize];
1152 : 1 : uint8_t apdu[] = {
1153 : : 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00
1154 : : };
1155 : : size_t apdu_len = 5;
1156 : :
1157 [ - + ]: 1 : g_assert_nonnull(reader);
1158 : :
1159 : 1 : select_applet(reader, TEST_ACA);
1160 : :
1161 : : /* P2 needs to be zero */
1162 : 1 : apdu[3] = 0xff;
1163 : 1 : dwRecvLength = APDUBufSize;
1164 : 1 : status = vreader_xfr_bytes(reader,
1165 : : apdu, apdu_len,
1166 : : pbRecvBuffer, &dwRecvLength);
1167 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
1168 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
1169 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_P1_P2_ERROR);
1170 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x86);
1171 : 1 : apdu[3] = 0x00;
1172 : :
1173 : : /* For P1 = 0x00 we can not send any data */
1174 : 1 : apdu[4] = 0x02;
1175 : 1 : dwRecvLength = APDUBufSize;
1176 : 1 : status = vreader_xfr_bytes(reader,
1177 : : apdu, sizeof(apdu),
1178 : : pbRecvBuffer, &dwRecvLength);
1179 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
1180 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
1181 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
1182 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x84);
1183 : :
1184 : : /* For P1 = 0x01 we need to send exactly one byte */
1185 : 1 : apdu[2] = 0x01;
1186 : 1 : dwRecvLength = APDUBufSize;
1187 : 1 : status = vreader_xfr_bytes(reader,
1188 : : apdu, sizeof(apdu),
1189 : : pbRecvBuffer, &dwRecvLength);
1190 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
1191 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
1192 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
1193 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x84);
1194 : :
1195 : : /* For P1 = 0x10 we can not send any data */
1196 : 1 : apdu[2] = 0x10;
1197 : 1 : apdu[4] = 0x02;
1198 : 1 : dwRecvLength = APDUBufSize;
1199 : 1 : status = vreader_xfr_bytes(reader,
1200 : : apdu, sizeof(apdu),
1201 : : pbRecvBuffer, &dwRecvLength);
1202 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
1203 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
1204 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
1205 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x84);
1206 : :
1207 : : /* For P1 = 0x11 we need to send exactly 7B (2 are not enough) */
1208 : 1 : apdu[2] = 0x11;
1209 : 1 : dwRecvLength = APDUBufSize;
1210 : 1 : status = vreader_xfr_bytes(reader,
1211 : : apdu, sizeof(apdu),
1212 : : pbRecvBuffer, &dwRecvLength);
1213 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
1214 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
1215 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
1216 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x84);
1217 : :
1218 : : /* For P1 = 0x12 we need to send exactly 2B (1 is not enough) */
1219 : 1 : apdu[2] = 0x12;
1220 : 1 : apdu[4] = 0x01;
1221 : 1 : dwRecvLength = APDUBufSize;
1222 : 1 : status = vreader_xfr_bytes(reader,
1223 : : apdu, 6,
1224 : : pbRecvBuffer, &dwRecvLength);
1225 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
1226 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
1227 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
1228 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x84);
1229 : :
1230 : : /* For P1 = 0x20 we can not send any data */
1231 : 1 : apdu[2] = 0x20;
1232 : 1 : dwRecvLength = APDUBufSize;
1233 : 1 : status = vreader_xfr_bytes(reader,
1234 : : apdu, 6,
1235 : : pbRecvBuffer, &dwRecvLength);
1236 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
1237 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
1238 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
1239 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x84);
1240 : :
1241 : : /* For P1 = 0x21 we can not send any data */
1242 : 1 : apdu[2] = 0x21;
1243 : 1 : dwRecvLength = APDUBufSize;
1244 : 1 : status = vreader_xfr_bytes(reader,
1245 : : apdu, 6,
1246 : : pbRecvBuffer, &dwRecvLength);
1247 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
1248 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
1249 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
1250 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x84);
1251 : :
1252 : : /* Any other P1 is invalid */
1253 : 1 : apdu[2] = 0x42;
1254 : 1 : dwRecvLength = APDUBufSize;
1255 : 1 : status = vreader_xfr_bytes(reader,
1256 : : apdu, 6,
1257 : : pbRecvBuffer, &dwRecvLength);
1258 [ - + ]: 1 : g_assert_cmpint(status, ==, VREADER_OK);
1259 [ - + ]: 1 : g_assert_cmpint(dwRecvLength, ==, 2);
1260 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[0], ==, VCARD7816_SW1_COMMAND_ERROR);
1261 [ - + ]: 1 : g_assert_cmpint(pbRecvBuffer[1], ==, 0x00);
1262 : :
1263 : 1 : vreader_free(reader); /* get by id ref */
1264 : 1 : }
1265 : :
1266 : 1 : static void test_passthrough_applet(void)
1267 : : {
1268 : 1 : uint8_t person_coid[2] = {0x02, 0x00};
1269 : :
1270 : 1 : VReader *reader = vreader_get_reader_by_id(0);
1271 : :
1272 : : /* select the passthrough applet */
1273 : 1 : select_applet(reader, TEST_PASSTHROUGH);
1274 : :
1275 : : /* get properties */
1276 : 1 : get_properties_coid(reader, person_coid, TEST_GENERIC);
1277 : :
1278 : : /* These objects requires a PIN to read the value buffer */
1279 : 1 : do_login(reader);
1280 : :
1281 : : /* get the TAG buffer length */
1282 : 1 : read_buffer(reader, CAC_FILE_TAG, TEST_EMPTY_BUFFER);
1283 : :
1284 : : /* get the VALUE buffer length */
1285 : 1 : read_buffer(reader, CAC_FILE_VALUE, TEST_EMPTY_BUFFER);
1286 : :
1287 : : /* the buffers are empty without physical card */
1288 : :
1289 : 1 : vreader_free(reader); /* get by id ref */
1290 : 1 : }
1291 : :
1292 : : #define MAX_ATR_LEN 100
1293 : : #define CAC_ATR "\x3B\x7A\x18\x00\x00\x73\x66\x74\x65\x20\x63\x64\x31\x34\x34"
1294 : : #define CAC_ATR_LEN (sizeof(CAC_ATR) - 1)
1295 : 1 : static void test_atr(void)
1296 : : {
1297 : 1 : VReader *reader = vreader_get_reader_by_id(0);
1298 : 1 : unsigned char *atr = g_malloc0(MAX_ATR_LEN);
1299 : 1 : int atr_len = MAX_ATR_LEN;
1300 : :
1301 : : /* Cycle off and on to get the ATR from the card */
1302 : 1 : vreader_power_off(reader);
1303 : 1 : vreader_power_on(reader, atr, &atr_len);
1304 : :
1305 [ - + - + : 1 : g_assert_cmpmem(atr, atr_len, CAC_ATR, CAC_ATR_LEN);
- + ]
1306 : :
1307 : 1 : vreader_free(reader); /* get by id ref */
1308 : 1 : g_free(atr);
1309 : 1 : }
1310 : :
1311 : 1 : static void libcacard_finalize(void)
1312 : : {
1313 : 1 : VReader *reader = vreader_get_reader_by_id(0);
1314 : :
1315 : : /* This actually still generates events */
1316 [ - + ]: 1 : if (reader) /*if /remove didn't run */
1317 : 0 : vreader_remove_reader(reader);
1318 : :
1319 : : /* This probably supposed to be a event that terminates the loop */
1320 : 1 : vevent_queue_vevent(vevent_new(VEVENT_LAST, reader, NULL));
1321 : :
1322 : : /* join */
1323 : 1 : g_thread_join(thread);
1324 : :
1325 : : /* Clean up */
1326 : 1 : vreader_free(reader);
1327 : :
1328 : 1 : vcard_emul_finalize();
1329 : 1 : }
1330 : :
1331 : 1 : int main(int argc, char *argv[])
1332 : : {
1333 : : int ret;
1334 : :
1335 : 1 : g_test_init(&argc, &argv, NULL);
1336 : :
1337 : 1 : loop = g_main_loop_new(NULL, TRUE);
1338 : :
1339 : 1 : libcacard_init();
1340 : :
1341 : 1 : g_test_add_func("/libcacard/hexdump", test_hex_dump);
1342 : 1 : g_test_add_func("/libcacard/list", test_list);
1343 : 1 : g_test_add_func("/libcacard/card-remove-insert", test_card_remove_insert);
1344 : 1 : g_test_add_func("/libcacard/xfer", test_xfer);
1345 : 1 : g_test_add_func("/libcacard/select-coid", test_select_coid);
1346 : 1 : g_test_add_func("/libcacard/cac-pki", test_cac_pki);
1347 : 1 : g_test_add_func("/libcacard/cac-pki-2", test_cac_pki_2);
1348 : 1 : g_test_add_func("/libcacard/cac-ccc", test_cac_ccc);
1349 : 1 : g_test_add_func("/libcacard/cac-aca", test_cac_aca);
1350 : 1 : g_test_add_func("/libcacard/get-response", test_get_response);
1351 : 1 : g_test_add_func("/libcacard/check-login-count", check_login_count);
1352 : 1 : g_test_add_func("/libcacard/login", test_login);
1353 : 1 : g_test_add_func("/libcacard/sign", test_sign);
1354 : 1 : g_test_add_func("/libcacard/decipher", test_decipher);
1355 : 1 : g_test_add_func("/libcacard/empty-applets", test_empty_applets);
1356 : 1 : g_test_add_func("/libcacard/gp-applet", test_gp_applet);
1357 : 1 : g_test_add_func("/libcacard/msft-applet", test_msft_applet);
1358 : 1 : g_test_add_func("/libcacard/invalid-apdu", test_invalid_apdu);
1359 : 1 : g_test_add_func("/libcacard/invalid-properties-apdu", test_invalid_properties);
1360 : 1 : g_test_add_func("/libcacard/invalid-select-apdu", test_invalid_select);
1361 : 1 : g_test_add_func("/libcacard/invalid-instruction", test_invalid_instruction);
1362 : 1 : g_test_add_func("/libcacard/invalid-read-buffer", test_invalid_read_buffer);
1363 : 1 : g_test_add_func("/libcacard/invalid-update-buffer", test_invalid_update_buffer);
1364 : 1 : g_test_add_func("/libcacard/invalid-sign", test_invalid_sign);
1365 : 1 : g_test_add_func("/libcacard/invalid-acr", test_invalid_acr);
1366 : 1 : g_test_add_func("/libcacard/invalid-class", test_invalid_class);
1367 : 1 : g_test_add_func("/libcacard/get-atr", test_atr);
1368 : : /* Even without the card, the passthrough applets are present */
1369 : 1 : g_test_add_func("/libcacard/passthrough-applet", test_passthrough_applet);
1370 : : /* TODO: Card/reader resets */
1371 : 1 : g_test_add_func("/libcacard/remove", test_remove);
1372 : :
1373 : 1 : ret = g_test_run();
1374 : :
1375 : 1 : g_main_loop_unref(loop);
1376 : :
1377 : 1 : libcacard_finalize();
1378 : : return ret;
1379 : : }
1380 : :
1381 : : /* vim: set ts=4 sw=4 tw=0 noet expandtab: */
|