Branch data Line data Source code
1 : : /*
2 : : * implement the applets for the CAC card.
3 : : *
4 : : * Adaptation to GSC-IS 2.1:
5 : : * https://nvlpubs.nist.gov/nistpubs/Legacy/IR/nistir6887e2003.pdf
6 : : *
7 : : * and NIST SP 800-73-4
8 : : * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-73-4.pdf
9 : : *
10 : : * Copyright 2010 - 2018 Red Hat, Inc.
11 : : *
12 : : * Authors: Robert Relyea <rrelyea@redhat.com>
13 : : * Alon Levy <alevy@redhat.com>
14 : : * Jakub Jelen <jjelen@redhat.com>
15 : : *
16 : : * This code is licensed under the GNU LGPL, version 2.1 or later.
17 : : * See the COPYING file in the top-level directory.
18 : : */
19 : :
20 : : #include <glib.h>
21 : :
22 : : #include <string.h>
23 : : #include <stdbool.h>
24 : :
25 : : #include "cac.h"
26 : : #include "cac-aca.h"
27 : : #include "vcard.h"
28 : : #include "vcard_emul.h"
29 : : #include "vcardt_internal.h"
30 : : #include "card_7816.h"
31 : : #include "simpletlv.h"
32 : : #include "common.h"
33 : :
34 : : static const unsigned char cac_aca_aid[] = {
35 : : 0xa0, 0x00, 0x00, 0x00, 0x79, 0x03, 0x00 };
36 : : static const unsigned char cac_ccc_aid[] = {
37 : : 0xa0, 0x00, 0x00, 0x01, 0x16, 0xDB, 0x00 };
38 : : static const unsigned char cac_02fb_aid[] = {
39 : : 0xa0, 0x00, 0x00, 0x00, 0x79, 0x02, 0xFB };
40 : : static const unsigned char cac_1201_aid[] = {
41 : : 0xa0, 0x00, 0x00, 0x00, 0x79, 0x12, 0x01 };
42 : : static const unsigned char cac_1202_aid[] = {
43 : : 0xa0, 0x00, 0x00, 0x00, 0x79, 0x12, 0x02 };
44 : : static const unsigned char cac_02f0_aid[] = {
45 : : 0xa0, 0x00, 0x00, 0x00, 0x79, 0x02, 0xF0 };
46 : : static const unsigned char cac_02f1_aid[] = {
47 : : 0xa0, 0x00, 0x00, 0x00, 0x79, 0x02, 0xF1 };
48 : : static const unsigned char cac_02f2_aid[] = {
49 : : 0xa0, 0x00, 0x00, 0x00, 0x79, 0x02, 0xF2 };
50 : : static const unsigned char cac_access_control_aid[] = {
51 : : 0xa0, 0x00, 0x00, 0x01, 0x16, 0x30, 0x00 };
52 : : static const unsigned char cac_pki_certificate_aid[] = {
53 : : 0xa0, 0x00, 0x00, 0x00, 0x79, 0x02, 0xFE };
54 : : static const unsigned char cac_pki_credential_aid[] = {
55 : : 0xa0, 0x00, 0x00, 0x00, 0x79, 0x02, 0xFD };
56 : : static const unsigned char cac_person_instance_aid[] = {
57 : : 0xa0, 0x00, 0x00, 0x00, 0x79, 0x02, 0x00 };
58 : : static const unsigned char cac_personnel_aid[] = {
59 : : 0xa0, 0x00, 0x00, 0x00, 0x79, 0x02, 0x01 };
60 : :
61 : :
62 : : /* private data for PKI applets */
63 : : typedef struct CACPKIAppletDataStruct {
64 : : unsigned char *sign_buffer;
65 : : int sign_buffer_len;
66 : : VCardKey *key;
67 : : } CACPKIAppletData;
68 : :
69 : : /* private data for CCC container */
70 : : typedef struct CACCCCAppletDataStruct {
71 : : } CACCCCAppletData;
72 : :
73 : : /* private data for ACA container */
74 : : typedef struct CACACAAppletDataStruct {
75 : : unsigned int pki_applets;
76 : : /* At the moment mostly in cac-aca.c */
77 : : } CACACAAppletData;
78 : :
79 : : /* private data for passthrough applets */
80 : : typedef struct CACPTAppletDataStruct {
81 : : char *label;
82 : : } CACPTAppletData;
83 : :
84 : : struct coid {
85 : : unsigned char v[2];
86 : : };
87 : :
88 : : /*
89 : : * CAC applet private data
90 : : */
91 : : struct VCardAppletPrivateStruct {
92 : : /* common attributes */
93 : : unsigned char *tag_buffer;
94 : : int tag_buffer_len;
95 : : unsigned char *val_buffer;
96 : : int val_buffer_len;
97 : : struct simpletlv_member *properties;
98 : : unsigned int properties_len;
99 : : unsigned int long_properties_len;
100 : : /* TODO we should also keep a state, which OID is selected,
101 : : * but it does not matter now, because we do not have anything different
102 : : * in either buffer
103 : : */
104 : : struct coid *coids;
105 : : unsigned int coids_len;
106 : : /* applet-specific */
107 : : union {
108 : : CACPKIAppletData pki_data;
109 : : CACCCCAppletData ccc_data;
110 : : CACACAAppletData aca_data;
111 : : CACPTAppletData pt_data;
112 : : void *reserved;
113 : : } u;
114 : : };
115 : :
116 : : /*
117 : : * Encode SimpleTLV structures to file expected to be returned by the card.
118 : : * This means, data in SimpleTLV prefixed with 2B encoding the length of
119 : : * the whole buffer.
120 : : */
121 : : static int
122 : 44 : cac_create_file(struct simpletlv_member *tlv, size_t tlv_len,
123 : : unsigned char **out, int type)
124 : : {
125 : : int len, length;
126 : : unsigned char *buffer = NULL, *start;
127 : :
128 : 44 : len = simpletlv_get_length(tlv, tlv_len, type);
129 [ - + ]: 44 : if (len < 0)
130 : 0 : goto failure;
131 : :
132 : 44 : buffer = g_malloc(2 /*2B length*/ + len);
133 : :
134 : 44 : start = buffer + 2;
135 [ + + ]: 44 : if (type == SIMPLETLV_TL)
136 : 22 : length = simpletlv_encode_tl(tlv, tlv_len, &start, len, NULL);
137 [ + - ]: 22 : else if (type == SIMPLETLV_VALUE)
138 : 22 : length = simpletlv_encode_val(tlv, tlv_len, &start, len, NULL);
139 : : else
140 : 0 : goto failure;
141 : :
142 [ - + ]: 44 : if (length <= 0)
143 : 0 : goto failure;
144 : :
145 : 44 : ushort2lebytes(buffer, length);
146 : :
147 : 44 : *out = buffer;
148 : 44 : return len + 2;
149 : :
150 : 0 : failure:
151 : 0 : *out = NULL;
152 : 0 : g_free(buffer);
153 : 0 : return 0;
154 : : }
155 : :
156 : : static inline int
157 : : cac_create_tl_file(struct simpletlv_member *tlv, size_t tlv_len,
158 : : unsigned char **out)
159 : : {
160 : 22 : return cac_create_file(tlv, tlv_len, out, SIMPLETLV_TL);
161 : : }
162 : :
163 : : static inline int
164 : : cac_create_val_file(struct simpletlv_member *tlv, size_t tlv_len,
165 : : unsigned char **out)
166 : : {
167 : 22 : return cac_create_file(tlv, tlv_len, out, SIMPLETLV_VALUE);
168 : : }
169 : :
170 : : static inline int
171 : : cac_create_empty_file(unsigned char **out)
172 : : {
173 : 6 : *out = g_malloc_n(2, sizeof(unsigned char));
174 : :
175 : 12 : (*out)[0] = 0x00;
176 : 12 : (*out)[1] = 0x00;
177 : : return 2;
178 : : }
179 : :
180 : : /*
181 : : * This function returns properties of an applet encoded as SimpleTLV.
182 : : * If the tags argument is provided, only the tags in the passed list
183 : : * with respective values are returned.
184 : : * Otherwise, all the tags are returned.
185 : : */
186 : : static VCardResponse *
187 : 277 : get_properties(VCard *card,
188 : : struct simpletlv_member *properties, unsigned int properties_len,
189 : : unsigned char *tags, unsigned int tags_len,
190 : : unsigned int a_Le)
191 : : {
192 : : VCardResponse *r = NULL;
193 : : struct simpletlv_member *cp = NULL;
194 : : unsigned int cp_len = 0;
195 : 277 : unsigned char *properties_buffer = NULL;
196 : : unsigned int properties_buffer_len = 0;
197 : :
198 [ + + ]: 277 : if (tags_len > 0 && tags) {
199 : : unsigned int i, j, k = 0;
200 : :
201 : 93 : cp = g_malloc_n(tags_len, sizeof(struct simpletlv_member));
202 : :
203 : : /* show only matching */
204 [ + + ]: 277 : for (j = 0; j < tags_len; j++) {
205 : : int match = 0;
206 [ + + ]: 188 : for (i = 0; i < properties_len; i++) {
207 [ + + ]: 187 : if (properties[i].tag == tags[j]) {
208 : 184 : memcpy(&cp[k], &properties[i],
209 : : sizeof(struct simpletlv_member));
210 : : match++;
211 : 184 : k++;
212 : : break; // XXX do not allow more tags of the same ID
213 : : }
214 : : }
215 : : /* if this tag was not found, return */
216 : : if (!match) {
217 : 1 : r = vcard_make_response(VCARD7816_STATUS_ERROR_DATA_NOT_FOUND);
218 : 1 : goto cleanup;
219 : : }
220 : : }
221 : : cp_len = tags_len;
222 : : } else {
223 : : cp = properties;
224 : : cp_len = properties_len;
225 : : }
226 : :
227 : : /* Encode the SimpleTLV structure */
228 : 276 : properties_buffer_len = simpletlv_encode(cp, cp_len,
229 : : &properties_buffer, 0, NULL);
230 [ - + ]: 276 : if (properties_buffer_len <= 0) {
231 : 0 : g_debug("%s: Failed to encode properties buffer", __func__);
232 : 0 : goto cleanup;
233 : : }
234 : :
235 [ + + ]: 276 : if (a_Le > properties_buffer_len) {
236 : 138 : r = vcard_response_new_status_bytes(
237 : : VCARD7816_SW1_LE_ERROR, properties_buffer_len);
238 : 138 : goto cleanup;
239 : : }
240 : 138 : r = vcard_response_new(card, properties_buffer, properties_buffer_len,
241 : : a_Le, VCARD7816_STATUS_SUCCESS);
242 : :
243 : 277 : cleanup:
244 : 277 : g_free(properties_buffer);
245 [ + + ]: 277 : if (tags_len > 0 && tags)
246 : 93 : g_free(cp);
247 [ - + ]: 277 : if (r == NULL)
248 : 0 : r = vcard_make_response(VCARD7816_STATUS_ERROR_GENERAL);
249 : 277 : return r;
250 : : }
251 : :
252 : : /*
253 : : * handle all the APDU's that are common to all CAC applets
254 : : */
255 : : static VCardStatus
256 : 455 : cac_common_process_apdu(VCard *card, VCardAPDU *apdu, VCardResponse **response)
257 : : {
258 : : VCardAppletPrivate *applet_private;
259 : : VCardStatus ret = VCARD_FAIL;
260 : : int found = 0;
261 : : unsigned int i;
262 : :
263 : 455 : applet_private = vcard_get_current_applet_private(card, apdu->a_channel);
264 [ - + - + ]: 455 : g_assert(applet_private);
265 : :
266 [ + + + + ]: 455 : switch (apdu->a_ins) {
267 : : case CAC_GET_PROPERTIES:
268 : : /* 5.3.3.4: Get Properties APDU */
269 : : g_assert(applet_private);
270 : :
271 [ + + ]: 282 : if (apdu->a_p2 != 0x00) {
272 : : /* P2 needs to be 0x00 */
273 : 1 : *response = vcard_make_response(
274 : : VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
275 : : ret = VCARD_DONE;
276 : 1 : break;
277 : : }
278 : :
279 [ + + + + : 281 : switch (apdu->a_p1) {
+ ]
280 : 1 : case 0x00:
281 : : /* Get a GSC-IS v2.0 compatible properties response message. */
282 : : /* If P1 = 0x00 cannot be supported by the smart card, SW1 = 0x6A and SW2 = 86. */
283 : 1 : *response = vcard_make_response(
284 : : VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
285 : : ret = VCARD_DONE;
286 : 1 : break;
287 : 93 : case 0x01:
288 : : /* Get all the properties. */
289 [ + + ]: 93 : if (apdu->a_Lc != 0) {
290 : 1 : *response = vcard_make_response(
291 : : VCARD7816_STATUS_ERROR_DATA_INVALID);
292 : : ret = VCARD_DONE;
293 : 1 : break;
294 : : }
295 : : /* TODO the properties buffer should be shorter for P1 = 0x01 */
296 : :
297 : 184 : *response = get_properties(card, applet_private->properties,
298 : 92 : applet_private->properties_len, NULL, 0, apdu->a_Le);
299 : : ret = VCARD_DONE;
300 : :
301 : 92 : break;
302 : 94 : case 0x02:
303 : : /* Get the properties of the tags provided in list of tags in
304 : : * the command data field. */
305 [ + + ]: 94 : if (apdu->a_Lc == 0) {
306 : 1 : *response = vcard_make_response(
307 : : VCARD7816_STATUS_ERROR_DATA_INVALID);
308 : : ret = VCARD_DONE;
309 : 1 : break;
310 : : }
311 : 186 : *response = get_properties(card, applet_private->properties,
312 : 93 : applet_private->properties_len, apdu->a_body, apdu->a_Lc, apdu->a_Le);
313 : : ret = VCARD_DONE;
314 : 93 : break;
315 : 92 : case 0x40:
316 : : /* XXX This is undocumented P1 argument, which returns properties
317 : : * extended with some more values of unknown meaning.
318 : : */
319 : 184 : *response = get_properties(card, applet_private->properties,
320 : 92 : applet_private->long_properties_len, NULL, 0, apdu->a_Le);
321 : : ret = VCARD_DONE;
322 : 92 : break;
323 : 1 : default:
324 : : /* unknown params returns (SW1=0x6A, SW2=0x86) */
325 : 1 : *response = vcard_make_response(
326 : : VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
327 : : ret = VCARD_DONE;
328 : 1 : break;
329 : : }
330 : :
331 : : break;
332 : 87 : case VCARD7816_INS_SELECT_FILE:
333 [ + + ]: 87 : if (apdu->a_p1 != 0x02) {
334 : : /* let the 7816 code handle applet switches */
335 : : ret = VCARD_NEXT;
336 : : break;
337 : : }
338 : :
339 : : g_assert(applet_private);
340 : :
341 : : /* handle file id setting */
342 [ + + ]: 7 : if (apdu->a_Lc != 2) {
343 : 2 : *response = vcard_make_response(
344 : : VCARD7816_STATUS_ERROR_DATA_INVALID);
345 : : ret = VCARD_DONE;
346 : 2 : break;
347 : : }
348 : : /* CAC 2 Card Object ID needs to match one of the COID defined
349 : : * in the applet
350 : : */
351 [ + + ]: 19 : for (i = 0; i < applet_private->coids_len; i++) {
352 [ + + ]: 14 : if (memcmp(apdu->a_body, applet_private->coids[i].v, 2) == 0) {
353 : : found = 1;
354 : : }
355 : : }
356 [ + + ]: 5 : if (!found) {
357 : 2 : *response = vcard_make_response(
358 : : VCARD7816_STATUS_ERROR_FILE_NOT_FOUND);
359 : : ret = VCARD_DONE;
360 : 2 : break;
361 : : }
362 : 3 : *response = vcard_make_response(VCARD7816_STATUS_SUCCESS);
363 : : ret = VCARD_DONE;
364 : 3 : break;
365 : : case VCARD7816_INS_GET_RESPONSE:
366 : : case VCARD7816_INS_VERIFY:
367 : : /* let the 7816 code handle these */
368 : : ret = VCARD_NEXT;
369 : : break;
370 : 2 : default:
371 : 2 : *response = vcard_make_response(
372 : : VCARD7816_STATUS_ERROR_INS_CODE_INVALID);
373 : : ret = VCARD_DONE;
374 : 2 : break;
375 : : }
376 : 455 : return ret;
377 : : }
378 : :
379 : : /*
380 : : * Handle READ BUFFER APDU and other common APDUs for CAC applets
381 : : */
382 : : static VCardStatus
383 : 472 : cac_common_process_apdu_read(VCard *card, VCardAPDU *apdu,
384 : : VCardResponse **response)
385 : : {
386 : : VCardAppletPrivate *applet_private;
387 : : VCardStatus ret = VCARD_FAIL;
388 : : int size, offset;
389 : :
390 : 472 : applet_private = vcard_get_current_applet_private(card, apdu->a_channel);
391 [ - + - + ]: 472 : g_assert(applet_private);
392 : :
393 [ + + + ]: 472 : switch (apdu->a_ins) {
394 : 74 : case CAC_READ_BUFFER:
395 : : /* Body contains exactly two bytes */
396 [ + + + + ]: 74 : if (!apdu->a_body || apdu->a_Lc != 2) {
397 : 10 : *response = vcard_make_response(
398 : : VCARD7816_STATUS_ERROR_DATA_INVALID);
399 : : ret = VCARD_DONE;
400 : 10 : break;
401 : : }
402 : :
403 : : /* Second byte defines how many bytes should be read */
404 : 64 : size = apdu->a_body[1];
405 : :
406 : : /* P1 | P2 defines offset to read from */
407 : 64 : offset = (apdu->a_p1 << 8) | apdu->a_p2;
408 : 64 : g_debug("%s: Requested offset: %d bytes", __func__, offset);
409 : :
410 : : /* First byte selects TAG+LEN or VALUE buffer */
411 [ + + + ]: 64 : switch (apdu->a_body[0]) {
412 : 25 : case CAC_FILE_VALUE:
413 : 25 : size = MIN(size, applet_private->val_buffer_len - offset);
414 [ + + ]: 25 : if (size < 0) { /* Overrun returns (SW1=0x6A, SW2=0x86) */
415 : 5 : *response = vcard_make_response(
416 : : VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
417 : 5 : break;
418 : : }
419 : 40 : *response = vcard_response_new_bytes(
420 : 20 : card, applet_private->val_buffer + offset, size,
421 : : apdu->a_Le, VCARD7816_SW1_SUCCESS, 0);
422 : 20 : break;
423 : 34 : case CAC_FILE_TAG:
424 : 34 : g_debug("%s: Requested: %d bytes", __func__, size);
425 : 34 : size = MIN(size, applet_private->tag_buffer_len - offset);
426 [ + + ]: 34 : if (size < 0) { /* Overrun returns (SW1=0x6A, SW2=0x86) */
427 : 5 : *response = vcard_make_response(
428 : : VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
429 : 5 : break;
430 : : }
431 : 29 : g_debug("%s: Returning: %d bytes (have %d)", __func__, size,
432 : : applet_private->tag_buffer_len);
433 : 58 : *response = vcard_response_new_bytes(
434 : 29 : card, applet_private->tag_buffer + offset, size,
435 : : apdu->a_Le, VCARD7816_SW1_SUCCESS, 0);
436 : 29 : break;
437 : 5 : default:
438 : 5 : *response = vcard_make_response(
439 : : VCARD7816_STATUS_ERROR_DATA_INVALID);
440 : 5 : break;
441 : : }
442 [ + - ]: 64 : if (*response == NULL) {
443 : 0 : *response = vcard_make_response(
444 : : VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
445 : : }
446 : : ret = VCARD_DONE;
447 : : break;
448 : 3 : case CAC_UPDATE_BUFFER:
449 : 3 : *response = vcard_make_response(
450 : : VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
451 : : ret = VCARD_DONE;
452 : 3 : break;
453 : 395 : default:
454 : 395 : ret = cac_common_process_apdu(card, apdu, response);
455 : 395 : break;
456 : : }
457 : 472 : return ret;
458 : : }
459 : :
460 : :
461 : : /*
462 : : * reset the inter call state between applet selects
463 : : */
464 : : static VCardStatus
465 : 29 : cac_applet_pki_reset(VCard *card, int channel)
466 : : {
467 : : VCardAppletPrivate *applet_private;
468 : : CACPKIAppletData *pki_applet;
469 : 29 : applet_private = vcard_get_current_applet_private(card, channel);
470 [ - + - + ]: 29 : g_assert(applet_private);
471 : : pki_applet = &(applet_private->u.pki_data);
472 : :
473 : 29 : g_free(pki_applet->sign_buffer);
474 : 29 : pki_applet->sign_buffer = NULL;
475 : 29 : pki_applet->sign_buffer_len = 0;
476 : 29 : return VCARD_DONE;
477 : : }
478 : :
479 : : static VCardStatus
480 : 7 : cac_applet_passthrough_reset(VCard *card, int channel)
481 : : {
482 : : VCardAppletPrivate *applet_private;
483 : 7 : applet_private = vcard_get_current_applet_private(card, channel);
484 [ - + - + ]: 7 : g_assert(applet_private);
485 : :
486 : 7 : g_free(applet_private->tag_buffer);
487 : 7 : applet_private->tag_buffer = NULL;
488 : 7 : applet_private->tag_buffer_len = 0;
489 : 7 : g_free(applet_private->val_buffer);
490 : 7 : applet_private->val_buffer = NULL;
491 : 7 : applet_private->val_buffer_len = 0;
492 : 7 : return VCARD_DONE;
493 : : }
494 : :
495 : : static VCardStatus
496 : 253 : cac_applet_pki_process_apdu(VCard *card, VCardAPDU *apdu,
497 : : VCardResponse **response)
498 : : {
499 : : CACPKIAppletData *pki_applet;
500 : : VCardAppletPrivate *applet_private;
501 : : int size;
502 : : unsigned char *sign_buffer = NULL;
503 : : bool retain_sign_buffer = FALSE;
504 : : vcard_7816_status_t status;
505 : : VCardStatus ret = VCARD_FAIL;
506 : :
507 : 253 : applet_private = vcard_get_current_applet_private(card, apdu->a_channel);
508 [ - + - + ]: 253 : g_assert(applet_private);
509 : : pki_applet = &(applet_private->u.pki_data);
510 : :
511 [ + + + ]: 253 : switch (apdu->a_ins) {
512 : 2 : case CAC_UPDATE_BUFFER:
513 : 2 : *response = vcard_make_response(
514 : : VCARD7816_STATUS_ERROR_CONDITION_NOT_SATISFIED);
515 : : ret = VCARD_DONE;
516 : 2 : break;
517 : 52 : case CAC_SIGN_DECRYPT:
518 [ + + ]: 52 : if (apdu->a_p2 != 0) {
519 : 2 : *response = vcard_make_response(
520 : : VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
521 : : ret = VCARD_DONE;
522 : 2 : break;
523 : : }
524 : 50 : size = apdu->a_Lc;
525 : :
526 : 50 : sign_buffer = g_realloc(pki_applet->sign_buffer,
527 : 50 : pki_applet->sign_buffer_len + size);
528 : 50 : memcpy(sign_buffer + pki_applet->sign_buffer_len, apdu->a_body, size);
529 : 50 : size += pki_applet->sign_buffer_len;
530 [ + + - ]: 50 : switch (apdu->a_p1) {
531 : 14 : case 0x80:
532 : : /* p1 == 0x80 means we haven't yet sent the whole buffer, wait for
533 : : * the rest */
534 : 14 : pki_applet->sign_buffer = sign_buffer;
535 : 14 : pki_applet->sign_buffer_len = size;
536 : 14 : *response = vcard_make_response(VCARD7816_STATUS_SUCCESS);
537 : : retain_sign_buffer = TRUE;
538 : : break;
539 : 36 : case 0x00:
540 : : /* we now have the whole buffer, do the operation, result will be
541 : : * in the sign_buffer */
542 : 36 : status = vcard_emul_rsa_op(card, pki_applet->key,
543 : : sign_buffer, size);
544 [ + + ]: 36 : if (status != VCARD7816_STATUS_SUCCESS) {
545 : 1 : *response = vcard_make_response(status);
546 : : break;
547 : : }
548 : 35 : *response = vcard_response_new(card, sign_buffer, size, apdu->a_Le,
549 : : VCARD7816_STATUS_SUCCESS);
550 [ - + ]: 35 : if (*response == NULL) {
551 : 0 : *response = vcard_make_response(
552 : : VCARD7816_STATUS_EXC_ERROR_MEMORY_FAILURE);
553 : : }
554 : : break;
555 : 0 : default:
556 : 0 : *response = vcard_make_response(
557 : : VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
558 : : break;
559 : : }
560 : : if (!retain_sign_buffer) {
561 : 36 : g_free(sign_buffer);
562 : 36 : pki_applet->sign_buffer = NULL;
563 : 36 : pki_applet->sign_buffer_len = 0;
564 : : }
565 : : ret = VCARD_DONE;
566 : : break;
567 : 199 : default:
568 : 199 : ret = cac_common_process_apdu_read(card, apdu, response);
569 : 199 : break;
570 : : }
571 : 253 : return ret;
572 : : }
573 : :
574 : : static VCardStatus
575 : 169 : cac_applet_aca_process_apdu(VCard *card, VCardAPDU *apdu,
576 : : VCardResponse **response)
577 : : {
578 : : VCardStatus ret = VCARD_FAIL;
579 : : CACACAAppletData *aca_applet;
580 : : VCardAppletPrivate *applet_private;
581 : : int format;
582 : :
583 : 169 : applet_private = vcard_get_current_applet_private(card, apdu->a_channel);
584 [ - + - + ]: 169 : g_assert(applet_private);
585 : : aca_applet = &(applet_private->u.aca_data);
586 : :
587 [ + + ]: 169 : switch (apdu->a_ins) {
588 : 109 : case CAC_GET_ACR:
589 : : /* generate some ACRs Chapter 5.3.3.5
590 : : * Works only on the ACA container, not the others!
591 : : */
592 [ + + ]: 109 : if (apdu->a_p2 != 0x00) {
593 : : /* P2 needs to be 0x00 */
594 : 1 : *response = vcard_make_response(
595 : : VCARD7816_STATUS_ERROR_P1_P2_INCORRECT);
596 : : ret = VCARD_DONE;
597 : 1 : break;
598 : : }
599 : :
600 : 108 : format = ((apdu->a_p1 & 0x40)
601 : : ? CAC_FORMAT_EXTENDED
602 [ + + ]: 108 : : CAC_FORMAT_SIMPLETLV);
603 : :
604 : : switch (apdu->a_p1) {
605 : 3 : case 0x00:
606 : : case 0x40:
607 : : case 0x41: /* This one returns the same as 0x40 for some reason */
608 : : /* All ACR table entries are to be extracted */
609 [ + + ]: 3 : if (apdu->a_Lc != 0) {
610 : 1 : *response = vcard_make_response(
611 : : VCARD7816_STATUS_ERROR_DATA_INVALID);
612 : 1 : break;
613 : : }
614 : 2 : *response = cac_aca_get_acr_response(card, apdu->a_Le, NULL,
615 : : format);
616 : 2 : break;
617 : :
618 : 3 : case 0x01:
619 : : /* Only one entry of the ACR table is extracted based on ACRID */
620 [ + + ]: 3 : if (apdu->a_Lc != 1) { /* ACRID is one byte */
621 : 1 : *response = vcard_make_response(
622 : : VCARD7816_STATUS_ERROR_DATA_INVALID);
623 : 1 : break;
624 : : }
625 : 2 : *response = cac_aca_get_acr_response(card, apdu->a_Le,
626 : : apdu->a_body, format);
627 : 2 : break;
628 : :
629 : 3 : case 0x10:
630 : : case 0x50:
631 : : case 0x51: /* returns the same as 0x50 for some reason */
632 : : case 0x52: /* returns the same as 0x50 for some reason */
633 : : /* All Applet/Object ACR table entries are to be extracted */
634 [ + + ]: 3 : if (apdu->a_Lc != 0) {
635 : 1 : *response = vcard_make_response(
636 : : VCARD7816_STATUS_ERROR_DATA_INVALID);
637 : 1 : break;
638 : : }
639 : 2 : *response = cac_aca_get_applet_acr_response(card, apdu->a_Le,
640 : : aca_applet->pki_applets, NULL, 0, NULL, format);
641 : 2 : break;
642 : :
643 : 3 : case 0x11:
644 : : /* Only the entries of the Applet/Object ACR table for
645 : : * one applet are extracted based on applet AID */
646 [ + + ]: 3 : if (apdu->a_Lc != 7) {
647 : 1 : *response = vcard_make_response(
648 : : VCARD7816_STATUS_ERROR_DATA_INVALID);
649 : 1 : break;
650 : : }
651 : 2 : *response = cac_aca_get_applet_acr_response(card, apdu->a_Le,
652 : : aca_applet->pki_applets, apdu->a_body, apdu->a_Lc, NULL,
653 : : format);
654 : 2 : break;
655 : :
656 : 3 : case 0x12:
657 : : /* Only one entry of the Applet/Object ACR table for
658 : : * an object is extracted based on object ID */
659 [ + + ]: 3 : if (apdu->a_Lc != 2) {
660 : 1 : *response = vcard_make_response(
661 : : VCARD7816_STATUS_ERROR_DATA_INVALID);
662 : 1 : break;
663 : : }
664 : 2 : *response = cac_aca_get_applet_acr_response(card, apdu->a_Le,
665 : : aca_applet->pki_applets, NULL, 0, apdu->a_body, format);
666 : 2 : break;
667 : :
668 : 3 : case 0x20:
669 : : case 0x60:
670 : : /* The Access Method Provider table is extracted. */
671 [ + + ]: 3 : if (apdu->a_Lc != 0) {
672 : 1 : *response = vcard_make_response(
673 : : VCARD7816_STATUS_ERROR_DATA_INVALID);
674 : 1 : break;
675 : : }
676 : 2 : *response = cac_aca_get_amp_response(card, apdu->a_Le, format);
677 : 2 : break;
678 : :
679 : 89 : case 0x21:
680 : : case 0x61:
681 : : /* The Service Applet table is extracted. */
682 [ + + ]: 89 : if (apdu->a_Lc != 0) {
683 : 1 : *response = vcard_make_response(
684 : : VCARD7816_STATUS_ERROR_DATA_INVALID);
685 : 1 : break;
686 : : }
687 : 88 : *response = cac_aca_get_service_response(card, apdu->a_Le,
688 : : aca_applet->pki_applets, format);
689 : 88 : break;
690 : :
691 : 1 : default:
692 : 1 : *response = vcard_make_response(
693 : : VCARD7816_STATUS_ERROR_COMMAND_NOT_SUPPORTED);
694 : 1 : break;
695 : : }
696 : : ret = VCARD_DONE;
697 : : break;
698 : 60 : default:
699 : 60 : ret = cac_common_process_apdu(card, apdu, response);
700 : 60 : break;
701 : : }
702 : 169 : return ret;
703 : : }
704 : :
705 : : static VCardStatus
706 : 56 : cac_passthrough_container_process_apdu(VCard *card, VCardAPDU *apdu,
707 : : VCardResponse **response)
708 : : {
709 : : VCardStatus ret = VCARD_FAIL;
710 : : CACPTAppletData *pt_applet;
711 : : VCardAppletPrivate *applet_private;
712 : :
713 : 56 : applet_private = vcard_get_current_applet_private(card, apdu->a_channel);
714 [ - + - + ]: 56 : g_assert(applet_private);
715 : : pt_applet = &(applet_private->u.pt_data);
716 : :
717 [ + + ]: 56 : switch (apdu->a_ins) {
718 : 15 : case CAC_READ_BUFFER:
719 : : /* The data were not yet retrieved from the card -- do it now */
720 [ + + - + ]: 15 : if (applet_private->tag_buffer == NULL || applet_private->val_buffer == NULL) {
721 : : unsigned char *data;
722 : : unsigned int data_len;
723 : : size_t tlv_len;
724 : : struct simpletlv_member *tlv;
725 : :
726 : 6 : data = vcard_emul_read_object(card, pt_applet->label, &data_len);
727 [ - + ]: 6 : if (data) {
728 : 0 : tlv = simpletlv_parse(data, data_len, &tlv_len);
729 : 0 : g_free(data);
730 : :
731 : : /* break the data buffer to TL and V buffers */
732 : 0 : applet_private->tag_buffer_len = cac_create_tl_file(tlv, tlv_len,
733 : : &applet_private->tag_buffer);
734 : 0 : applet_private->val_buffer_len = cac_create_val_file(tlv, tlv_len,
735 : : &applet_private->val_buffer);
736 : :
737 : 0 : simpletlv_free(tlv, tlv_len);
738 : : } else {
739 : : /* there is not a CAC card in a slot ? */
740 : : /* Return an empty buffer so far */
741 : : /* TODO try to emulate the expected structures here */
742 : 6 : applet_private->tag_buffer_len = cac_create_empty_file(
743 : : &applet_private->tag_buffer);
744 : 6 : applet_private->val_buffer_len = cac_create_empty_file(
745 : : &applet_private->val_buffer);
746 : : }
747 : : }
748 : : /* fallthrough */
749 : : default:
750 : 56 : ret = cac_common_process_apdu_read(card, apdu, response);
751 : : break;
752 : : }
753 : 56 : return ret;
754 : : }
755 : :
756 : : /*
757 : : * utilities for creating and destroying the private applet data
758 : : */
759 : : static void
760 : 13 : cac_delete_pki_applet_private(VCardAppletPrivate *applet_private)
761 : : {
762 : : CACPKIAppletData *pki_applet_data;
763 : :
764 [ + - ]: 13 : if (applet_private == NULL) {
765 : : return;
766 : : }
767 : : pki_applet_data = &(applet_private->u.pki_data);
768 : 13 : g_free(pki_applet_data->sign_buffer);
769 : 13 : g_free(applet_private->tag_buffer);
770 : 13 : g_free(applet_private->val_buffer);
771 : 13 : g_free(applet_private->coids);
772 : : /* this one is cloned so needs to be freed */
773 : 13 : simpletlv_free(applet_private->properties, applet_private->long_properties_len);
774 [ + - ]: 13 : if (pki_applet_data->key != NULL) {
775 : 13 : vcard_emul_delete_key(pki_applet_data->key);
776 : : }
777 : 13 : g_free(applet_private);
778 : : }
779 : :
780 : : static void
781 : 5 : cac_delete_ccc_applet_private(VCardAppletPrivate *applet_private)
782 : : {
783 [ + - ]: 5 : if (applet_private == NULL) {
784 : : return;
785 : : }
786 : 5 : g_free(applet_private->tag_buffer);
787 : 5 : g_free(applet_private->val_buffer);
788 : 5 : g_free(applet_private->coids);
789 : 5 : g_free(applet_private);
790 : : }
791 : :
792 : : static void
793 : 5 : cac_delete_aca_applet_private(VCardAppletPrivate *applet_private)
794 : : {
795 [ + - ]: 5 : if (applet_private == NULL) {
796 : : return;
797 : : }
798 : 5 : g_free(applet_private->coids);
799 : 5 : g_free(applet_private);
800 : : }
801 : :
802 : : static void
803 : 45 : cac_delete_empty_applet_private(VCardAppletPrivate *applet_private)
804 : : {
805 [ + - ]: 45 : if (applet_private == NULL) {
806 : : return;
807 : : }
808 : 45 : g_free(applet_private->coids);
809 : 45 : g_free(applet_private->tag_buffer);
810 : 45 : g_free(applet_private->val_buffer);
811 : : /* this one is cloned so needs to be freed */
812 : 45 : simpletlv_free(applet_private->properties, applet_private->properties_len);
813 : 45 : g_free(applet_private);
814 : : }
815 : :
816 : : static void
817 : 10 : cac_delete_passthrough_applet_private(VCardAppletPrivate *applet_private)
818 : : {
819 : : CACPTAppletData *pt_applet_data;
820 : :
821 [ + - ]: 10 : if (applet_private == NULL) {
822 : : return;
823 : : }
824 : : pt_applet_data = &(applet_private->u.pt_data);
825 : 10 : g_free(pt_applet_data->label);
826 : 10 : g_free(applet_private->tag_buffer);
827 : 10 : g_free(applet_private->val_buffer);
828 : 10 : g_free(applet_private->coids);
829 : : /* this one is cloned so needs to be freed */
830 : 10 : simpletlv_free(applet_private->properties, applet_private->properties_len);
831 : 10 : g_free(applet_private);
832 : : }
833 : :
834 : : static VCardAppletPrivate *
835 : 16 : cac_new_pki_applet_private(int i, const unsigned char *cert,
836 : : int cert_len, VCardKey *key)
837 : : {
838 : : CACPKIAppletData *pki_applet_data = NULL;
839 : : VCardAppletPrivate *applet_private = NULL;
840 : : int bits;
841 : :
842 : : /* PKI applet Properies ex.:
843 : : * 01 Tag: Applet Information
844 : : * 05 Length
845 : : * 10 Applet family
846 : : * 02 06 02 03 Applet version
847 : : * 40 Tag: Number of objects managed by this instance
848 : : * 01 Length
849 : : * 01 One
850 : : * 51 Tag: First PKI object
851 : : * 11 Length
852 : : * 41 Tag: ObjectID
853 : : * 02 Length
854 : : * 01 01
855 : : * 42 Buffer properties
856 : : * 05 Length
857 : : * 00 Type of tag supported
858 : : * 1E 00 T-Buffer length (LSB, MSB)
859 : : * 54 05 V-Buffer length (LSB, MSB)
860 : : * 43 Tag: PKI properties
861 : : * 04 Length
862 : : * 06 Algorithm ID Table 5-6 in GSC-IS 2.1
863 : : * 10 Key length bytes /8
864 : : * 01 Private key initialized
865 : : * 01 Public key initialized
866 : : *
867 : : * Long Properties:
868 : : * PKI applet:
869 : : * 01 05 Applet Information
870 : : * 10 02 06 02 03
871 : : * 40 01 Number of objects
872 : : * 01
873 : : * 51 14 First PKI Object
874 : : * 41 02 Object ID
875 : : * 01 02
876 : : * 42 05 Buffer properties
877 : : * 00 1E 00 57 05
878 : : * 43 04 PKI Properties
879 : : * 06 10 01 00
880 : : * 26 01 ???
881 : : * 01
882 : : * 39 01
883 : : * 00
884 : : * 3A 07 ACA ???
885 : : * A0 00 00 00 79 03 00
886 : : */
887 : 16 : unsigned char object_id[] = "\x01\x00";
888 : 16 : unsigned char buffer_properties[] = "\x00\x00\x00\x00\x00";
889 : 16 : unsigned char pki_properties[] = "\x06\x10\x01\x01";
890 : 16 : unsigned char buffer_26[] = "\x01";
891 : : static struct simpletlv_member pki_object[] = {
892 : : {CAC_PROPERTIES_OBJECT_ID, 2, {/*.value = object_id*/},
893 : : SIMPLETLV_TYPE_LEAF},
894 : : {CAC_PROPERTIES_BUFFER_PROPERTIES, 5, {/*.value = buffer_properties*/},
895 : : SIMPLETLV_TYPE_LEAF},
896 : : {CAC_PROPERTIES_PKI_PROPERTIES, 4, {/*.value = pki_properties*/},
897 : : SIMPLETLV_TYPE_LEAF},
898 : : {0x26, 0x01, {/*.child = buffer_26*/}, SIMPLETLV_TYPE_LEAF},
899 : : };
900 : 16 : unsigned char applet_information[] = "\x10\x02\x06\x02\x03";
901 : 16 : unsigned char number_objects[] = "\x01";
902 : 16 : unsigned char buffer_39[] = "\x00";
903 : 16 : unsigned char aca_aid[] = "\xA0\x00\x00\x00\x79\x03\x00";
904 : : static struct simpletlv_member properties[] = {
905 : : {CAC_PROPERTIES_APPLET_INFORMATION, 5, {/*.value = applet_information*/},
906 : : SIMPLETLV_TYPE_LEAF},
907 : : {CAC_PROPERTIES_NUMBER_OBJECTS, 1, {/*.value = number_objects */},
908 : : SIMPLETLV_TYPE_LEAF},
909 : : {CAC_PROPERTIES_PKI_OBJECT, 4, {/*.child = pki_object*/},
910 : : SIMPLETLV_TYPE_COMPOUND},
911 : : {0x39, 0x01, {/*.child = buffer_39*/}, SIMPLETLV_TYPE_LEAF},
912 : : {0x3A, 0x07, {/*.child = aca_aid*/}, SIMPLETLV_TYPE_LEAF},
913 : : };
914 : : size_t properties_len = sizeof(properties)/sizeof(struct simpletlv_member);
915 : : /* if this would be 1, the certificate would be compressed */
916 : 16 : unsigned char certinfo[] = "\x00";
917 : 16 : struct simpletlv_member buffer[] = {
918 : : {CAC_PKI_TAG_CERTINFO, 1, {/*.value = certinfo*/},
919 : : SIMPLETLV_TYPE_LEAF},
920 : : {CAC_PKI_TAG_CERTIFICATE, cert_len, {/*.value = cert*/},
921 : : SIMPLETLV_TYPE_LEAF},
922 : : {CAC_PKI_TAG_MSCUID, 0, {/*.value = NULL*/}, SIMPLETLV_TYPE_LEAF},
923 : : {CAC_PKI_TAG_ERROR_DETECTION_CODE, 0, {/*.value = NULL*/},
924 : : SIMPLETLV_TYPE_LEAF},
925 : : };
926 : : size_t buffer_len = sizeof(buffer)/sizeof(struct simpletlv_member);
927 : :
928 : 16 : applet_private = g_new0(VCardAppletPrivate, 1);
929 : : pki_applet_data = &(applet_private->u.pki_data);
930 : : /*
931 : : * if we want to support compression, then we simply change the 0 to a 1
932 : : * in certinfo and compress the cert data with libz
933 : : */
934 : :
935 : : /* prepare the buffers to when READ_BUFFER will be called.
936 : : * Assuming VM card with (LSB first if > 255)
937 : : * separate Tag+Length, Value buffers as described in 8.4:
938 : : * 2 B 1 B 1-3 B 1 B 1-3 B
939 : : * [ T-Len ] [ Tag1 ] [ Len1 ] [ Tag2] [ Len2 ] [...]
940 : : *
941 : : * 2 B Len1 B Len2 B
942 : : * [ V-Len ] [ Value 1 ] [ Value 2 ] [...]
943 : : * */
944 : :
945 : : /* Tag+Len buffer */
946 : 16 : buffer[0].value.value = certinfo;
947 : 16 : buffer[1].value.value = (unsigned char *)cert;
948 : 16 : buffer[2].value.value = NULL;
949 : 16 : buffer[3].value.value = NULL;
950 : : /* Ex:
951 : : * 0A 00 Length of whole buffer
952 : : * 71 Tag: CertInfo
953 : : * 01 Length: 1B
954 : : * 70 Tag: Certificate
955 : : * FF B2 03 Length: (\x03 << 8) || \xB2
956 : : * 72 Tag: MSCUID
957 : : * 26 Length
958 : : */
959 : 16 : applet_private->tag_buffer_len = cac_create_tl_file(buffer, buffer_len,
960 : : &applet_private->tag_buffer);
961 [ - + ]: 16 : if (applet_private->tag_buffer_len == 0) {
962 : 0 : goto failure;
963 : : }
964 : 16 : g_debug("%s: applet_private->tag_buffer = %s", __func__,
965 : : hex_dump(applet_private->tag_buffer, applet_private->tag_buffer_len));
966 : :
967 : : /* Value buffer */
968 : : /* Ex:
969 : : * DA 03 Length of complete buffer
970 : : * 01 Value of CertInfo
971 : : * 78 [..] 6C Cert Value
972 : : * 7B 63 37 35 62 62 61 64 61 2D 35 32 39 38 2D 31
973 : : * 37 35 62 2D 39 32 64 63 2D 39 38 35 30 36 62 65
974 : : * 30 30 30 30 30 7D MSCUID Value
975 : : */
976 : 16 : applet_private->val_buffer_len = cac_create_val_file(buffer, buffer_len,
977 : : &applet_private->val_buffer);
978 [ - + ]: 16 : if (applet_private->val_buffer_len == 0) {
979 : 0 : goto failure;
980 : : }
981 : 16 : g_debug("%s: applet_private->val_buffer = %s", __func__,
982 : : hex_dump(applet_private->val_buffer, applet_private->val_buffer_len));
983 : :
984 : : /* Inject Object ID */
985 : 16 : object_id[1] = i;
986 : 16 : pki_object[0].value.value = object_id;
987 : :
988 : : /* Create Object ID list */
989 : 16 : applet_private->coids = g_malloc(sizeof(struct coid));
990 : 16 : memcpy(applet_private->coids[0].v, object_id, 2);
991 : 16 : applet_private->coids_len = 1;
992 : :
993 : : /* Inject T-Buffer and V-Buffer lengths in the properties buffer */
994 : 16 : ushort2lebytes(&buffer_properties[1], applet_private->tag_buffer_len);
995 : 16 : ushort2lebytes(&buffer_properties[3], applet_private->val_buffer_len);
996 : 16 : pki_object[1].value.value = buffer_properties;
997 : :
998 : : /* PKI properties needs adjustments based on the key sizes */
999 : 16 : bits = vcard_emul_rsa_bits(key);
1000 : 16 : g_debug("RSA bits = %d", bits);
1001 [ + - ]: 16 : if (bits > 0)
1002 : 16 : pki_properties[1] = 0xff & (bits / 8 / 8);
1003 : 16 : pki_object[2].value.value = pki_properties;
1004 : 16 : pki_object[3].value.value = buffer_26;
1005 : :
1006 : : /* Inject Applet Version */
1007 : 16 : properties[0].value.value = applet_information;
1008 : 16 : properties[1].value.value = number_objects;
1009 : 16 : properties[2].value.child = pki_object;
1010 : 16 : properties[3].value.value = buffer_39;
1011 : 16 : properties[4].value.value = aca_aid;
1012 : :
1013 : : /* Clone the properties */
1014 : 16 : applet_private->properties_len = 3;
1015 : 16 : applet_private->long_properties_len = properties_len;
1016 : 16 : applet_private->properties = simpletlv_clone(properties,
1017 : : applet_private->long_properties_len);
1018 [ - + ]: 16 : if (applet_private->properties == NULL) {
1019 : 0 : goto failure;
1020 : : }
1021 : 16 : pki_applet_data->key = key;
1022 : 16 : return applet_private;
1023 : :
1024 : 0 : failure:
1025 : 0 : cac_delete_pki_applet_private(applet_private);
1026 : 0 : return NULL;
1027 : : }
1028 : :
1029 : : /*
1030 : : * Other applets breakdown:
1031 : : *
1032 : : * A00000007902FB: ??? (generic container ??)
1033 : : * $ opensc-tool -s 00A4040007A00000007902FB -s 8056010000
1034 : : * PROPERTIES:
1035 : : * 01 05
1036 : : * 10 02 06 01 00
1037 : : * 40 01
1038 : : * 01
1039 : : * 50 0B
1040 : : * 41 02
1041 : : * 02 FB
1042 : : * 42 05
1043 : : * 01 <-- Inidicates that this is not SimpleTLV ?
1044 : : * 62 00 60 01
1045 : : * $ opensc-tool -s 00A4040007A00000007902FB -s 8052000002010202
1046 : : * $ opensc-tool -s 00A4040007A00000007902FB -s 8052000002020202
1047 : : * TAG, VALUE BUFFER:
1048 : : * empty
1049 : : *
1050 : : * A00000007902FE: PKI Certificate
1051 : : * $ opensc-tool -s 00A4040007A00000007902FE -s 8056010000
1052 : : * PROPERTIES:
1053 : : * 01 05
1054 : : * 10 02 06 02 03
1055 : : * 40 01
1056 : : * 01
1057 : : * 50 0B
1058 : : * 41 02
1059 : : * 02 FE
1060 : : * 42 05
1061 : : * 01 <-- Indicates that this is not SimpleTLV, but what?
1062 : : * B2 00 30 02
1063 : : * $ opensc-tool -s 00A4040007A00000007902FE -s 8052000002010202
1064 : : * $ opensc-tool -s 00A4040007A00000007902FE -s 8052000002020202
1065 : : * TAG BUFFER:
1066 : : * 36 00 <-- length
1067 : : * 00 00 14 01 DC 0B 00 00 14 01 DD 03 00 00 14 01 72 29
1068 : : * 01 00 14 01 DC 0B 01 00 14 01 DD 03 01 00 14 01 72 29
1069 : : * 02 00 14 01 DC 0B 02 00 14 01 DD 03 02 00 14 01 72 29
1070 : : * [ID?][same] [ID?][same] [ID?][same]
1071 : : *
1072 : : * VALUE BUFFER:
1073 : : * A5 00
1074 : : * 00 C8 C8 CE <-- same
1075 : : * A0 00 00 00 79 01 00 <-- PKI Applet AID
1076 : : * 00 01 00 <-- OID ???
1077 : : * 00 01 01 <-- same
1078 : : * 7B 62 30 37 39 32 32 64 61 2D 35 30 30 30 2D 31
1079 : : * 30 37 39 2D 39 32 64 39 2D 39 38 35 30 36 62 65
1080 : : * 30 30 30 30 30 7D <-- MSCUID ???
1081 : : *
1082 : : * 00 C8 C8 CE
1083 : : * A0 00 00 00 79 01 01
1084 : : * 00 01 01
1085 : : * 00 01 01
1086 : : * 7B 63 35 36 33 65 35 31 38 2D 34 32 63 31 2D 31
1087 : : * 35 36 33 2D 39 32 64 62 2D 39 38 35 30 36 62 65
1088 : : * 30 30 30 30 30 7D
1089 : : *
1090 : : * 00 C8 C8 CE
1091 : : * A0 00 00 00 79 01 02
1092 : : * 00 01 02
1093 : : * 00 01 01
1094 : : * 7B 64 37 62 33 63 38 63 38 2D 31 32 63 38 2D 31
1095 : : * 37 62 33 2D 39 32 64 64 2D 39 38 35 30 36 62 65
1096 : : * 30 30 30 30 30 7D
1097 : : *
1098 : : * Read from OpenSC PKCS#11:
1099 : : * XXX TODO OpenSC criples the data while attempting to parse it as a SimpleTLV buffers
1100 : : * 1401 << TL
1101 : : * 00 << V
1102 : : * DC0B << TL
1103 : : * C8 << V
1104 : : * C8CE << TL
1105 : : * A000000079010000140101DD03000001
1106 : : * 14010172297B62303739323264612D35
1107 : : * 3030302D313037392D393264392D3938
1108 : : * 353036626530303030307D00C8C80100
1109 : : * 1401CEDC0BA000000079010100010100
1110 : : * 0100140101DD03017B63010014013572
1111 : : * 293633653531382D343263312D313536
1112 : : * 332D393264622D393835303662653030
1113 : : * 3030307D00C8C8CEA0000200140100DC
1114 : : * 0B007901020001020001017B02001401
1115 : : * 64DD0337623302001401630000000000
1116 : : * 00000000000000000000000000000000
1117 : : * 00000000000000000000000000000000
1118 : : * 000000 << V
1119 : : *
1120 : : *
1121 : : * A00000007902FD: PKI Credential
1122 : : * $ opensc-tool -s 00A4040007A00000007902FD -s 8056010000
1123 : : * PROPERTIES:
1124 : : * 01 05
1125 : : * 10 02 06 02 03
1126 : : * 40 01
1127 : : * 01
1128 : : * 50 0B
1129 : : * 41 02
1130 : : * 02 FD
1131 : : * 42 05
1132 : : * 01 <-- Inidicates that this is not SimpleTLV ?
1133 : : * B2 00 58 07
1134 : : * $ opensc-tool -s 00A4040007A00000007902FD -s 8052000002010202
1135 : : * $ opensc-tool -s 00A4040007A00000007902FD -s00200000083737373737373737 -s 8052000002020202
1136 : : * TAG BUFFER:
1137 : : * 12 00
1138 : : * 00 00 14 01 64 A5
1139 : : * 01 00 14 01 64 A5
1140 : : * 02 00 14 01 64 B9
1141 : : *
1142 : : * VALUE BUFFER (after login):
1143 : : * 03 02
1144 : : * 00 02 01 00 00 14 00 00 00 CF 12 87 F7 D0 6B 10
1145 : : * 09 EF D5 A7 01 50 48 0D 44 60 7A 2E EC 20 01 00
1146 : : * 00 80 00 00 00 A9 A3 31 FA 76 D2 19 03 89 B8 6A
1147 : : * 7F 3C 06 EE DC 50 44 18 79 F1 F6 8B B1 A3 29 E8
1148 : : * 71 7A 39 4D 25 F6 0D 97 15 C6 D9 A3 34 AC E3 6B
1149 : : * 36 F6 F9 50 0C A9 ED 99 8B A9 0A EF EC 47 0B 46
1150 : : * 17 FE 4E 71 08 57 88 5D 76 F1 42 8F B9 77 43 2F
1151 : : * C7 80 AC F6 57 58 CB 1F 6F 3A 72 A3 8C 8A E2 8E
1152 : : * 63 5B C6 65 5F 37 9A 75 18 39 3B 32 35 A0 19 6E
1153 : : * 95 1D 86 A8 C4 AF E9 FC 0F 89 5D B0 98 EF C7 57
1154 : : * A5 8E A6 A7 39
1155 : : * 00 02 01 00 00 14 00 00 00 17 61 A8 36 F7 6D C8
1156 : : * 91 2D 8B 45 95 02 D7 8F E0 5C 5B A3 2A 20 01 00
1157 : : * 00 80 00 00 00 BF 8C CB 0B D0 9E 6A 70 18 45 1B
1158 : : * A8 2D B5 09 17 8B 1F AF 73 75 23 7B 33 A0 6D 5A
1159 : : * 8D 50 38 E8 1E 7B 5D 27 BD 72 A7 9A 60 BD F6 07
1160 : : * 19 C2 92 7A 64 F1 EF A6 AC AD 1A 12 6F 46 94 DA
1161 : : * D9 C4 BC B0 23 31 BC 29 88 19 3C E3 8F DB F2 64
1162 : : * 41 F2 B0 79 7B CC B1 AC E3 26 1D E3 7C 8C 3C 29
1163 : : * DD B2 41 58 F6 35 47 46 AE A8 D0 F2 AA 5F 7B 89
1164 : : * B5 D8 53 1C 5F FC EE 41 C8 5B B2 C6 64 33 63 30
1165 : : * F1 70 FA D4 C9
1166 : : * 00 02 01 00 00 28 00 00 00 37 36 30 33 31 37 43
1167 : : * 37 32 37 38 41 33 33 32 36 31 45 41 42 45 44 31
1168 : : * 34 44 39 37 31 42 37 34 46 32 31 46 45 43 45 45
1169 : : * 37 20 01 00 00 80 00 00 00 C6 18 34 B8 64 DF BF
1170 : : * 07 1D 1A 3C A2 81 2D 6E 63 FA 60 C2 D6 9F 28 8B
1171 : : * D8 FD 2B B4 E7 03 E2 75 D3 81 DB 24 A7 D5 14 D5
1172 : : * B6 C2 65 9F 14 40 A5 78 DB 15 79 A4 69 22 6F 9A
1173 : : * 83 A8 FC BF 39 D0 89 B5 21 1B 11 D7 31 2E 4C E9
1174 : : * B2 03 F8 74 3B EC B1 E1 6E 89 7D C1 32 82 16 B0
1175 : : * 53 36 90 B0 79 BF 4C F5 3E E1 9D 54 A9 AD 8B F5
1176 : : * 01 F1 39 55 D8 F3 AC 47 9A 7F 73 3D 3E C0 AE 65
1177 : : * F3 2B 60 F3 07 06 3D 61 5B
1178 : : *
1179 : : *
1180 : : * A0000000790200: Person Instance (D.1 CAC Data Model Specific)
1181 : : * $ opensc-tool -s 00A4040007A0000000790200 -s 8056010000
1182 : : * PROPERTIES:
1183 : : * 01 05
1184 : : * 10 02 06 02 03
1185 : : * 40 01
1186 : : * 01
1187 : : * 50 0B
1188 : : * 41 02
1189 : : * 02 00
1190 : : * 42 05
1191 : : * 00 42 00 42 01
1192 : : * $ opensc-tool -s 00A4040007A0000000790200 -s 8052000002010202
1193 : : * $ opensc-tool -s 00A4040007A0000000790200 -s 8052000002020202
1194 : : * TAG BUFFER:
1195 : : * 20 00
1196 : : * 01 05
1197 : : * 02 00
1198 : : * 03 06
1199 : : * 04 00
1200 : : * 05 09
1201 : : * 06 08
1202 : : * 07 01
1203 : : * 08 01
1204 : : * 11 01
1205 : : * 17 0A
1206 : : * 18 01
1207 : : * 62 08
1208 : : * 65 08
1209 : : * 63 08
1210 : : * 66 08
1211 : : * 67 01
1212 : : * VALUE BUFFER:
1213 : : * 4B 00
1214 : : * 4D 61 72 69 65 Person First Name
1215 : : * 54 75 72 6E 65 72 Person Last Name
1216 : : * 38 37 36 30 32 30 30 33 35 Person Identifier
1217 : : * 31 39 37 30 30 34 30 32 Date of Birth
1218 : : * 46 Sex Category Code
1219 : : * 54 Person Identifier Type Code
1220 : : * 39 Blood Type Code
1221 : : * 31 30 30 31 32 37 37 33 39 38 DoD EDI Person Identifier
1222 : : * 5A Organ Donor
1223 : : * 32 30 30 39 30 34 30 32 Identification Card Issue Date
1224 : : * 32 30 30 39 30 34 30 32 Date Demographic Data was Loaded on
1225 : : * 32 30 31 32 30 34 30 31 Identification Card Expiration Date
1226 : : * 32 30 31 32 30 34 30 31 Date Demographic Data on Chip Expires
1227 : : * 55 Card Instance Identifier
1228 : : *
1229 : : * For real cards, we could try to proxy this from original card,
1230 : : * OpenSC exposes this as a data object as SimpleLTV merged in one buffer
1231 : : * $ pkcs11-tool --login --read-object --application-label 'Person Instance' --type data
1232 : : * 01 05
1233 : : * 4d 61 72 69 65
1234 : : * 02 00
1235 : : * 03 06
1236 : : * 54 75 72 6e 65 72
1237 : : * 04 00
1238 : : * 05 09
1239 : : * 38 37 36 30 32 30 30 33 35
1240 : : * 06 08
1241 : : * 31 39 37 30 30 34 30 32
1242 : : * 07 01
1243 : : * 46
1244 : : * 08 01
1245 : : * 54
1246 : : * 11 01
1247 : : * 39
1248 : : * 17 0a
1249 : : * 31 30 30 31 32 37 37 33 39 38
1250 : : * 18 01
1251 : : * 5a
1252 : : * 62 08
1253 : : * 32 30 30 39 30 34 30 32
1254 : : * 65 08
1255 : : * 32 30 30 39 30 34 30 32
1256 : : * 63 08
1257 : : * 32 30 31 32 30 34 30 31
1258 : : * 66 08
1259 : : * 32 30 31 32 30 34 30 31
1260 : : * 2e 31 30 <-- this is also broken in OpenSC
1261 : : * should be
1262 : : * 67 01 55
1263 : : *
1264 : : *
1265 : : * A0000000790201: Personnel (D.1 CAC Data Model Specific)
1266 : : * $ opensc-tool -s 00A4040007A0000000790201 -s 8056010000
1267 : : * PROPERTIES:
1268 : : * 01 05
1269 : : * 10 02 06 02 03
1270 : : * 40 01
1271 : : * 01
1272 : : * 50 0B
1273 : : * 41 02
1274 : : * 02 01
1275 : : * 42 05
1276 : : * 00 22 00 62 00
1277 : : *
1278 : : * $ opensc-tool -s 00A4040007A0000000790201 -s 8052000002010202
1279 : : * $ opensc-tool -s 00A4040007A0000000790201 -s 8052000002020202
1280 : : * TAG BUFFER:
1281 : : * 16 00
1282 : : * 19 00
1283 : : * 20 00
1284 : : * 35 00
1285 : : * 24 01
1286 : : * 25 02
1287 : : * 26 04
1288 : : * 34 01
1289 : : * 36 02
1290 : : * D3 02
1291 : : * D4 00
1292 : : * D5 00
1293 : : * VALUE BUFFER:
1294 : : * 0C 00
1295 : : * 4E Branch of Service Code
1296 : : * 30 31 Pay Grade Code
1297 : : * 57 4F 2D 31 Rank Code
1298 : : * 41 Personnel Category Code
1299 : : * 4D 57 Pay Plan Code
1300 : : * 30 30 Personnel Entitlement Condition Code
1301 : : *
1302 : : * pkcs11-tool --pin 77777777 --read-object --application-label 'Personnel' --type data
1303 : : * OpenSC exposes this as a data object as SimpleLTV merged in one buffer:
1304 : : * 19 00
1305 : : * 20 00
1306 : : * 35 00
1307 : : * 24 01
1308 : : * 4e
1309 : : * 25 02
1310 : : * 30 31
1311 : : * 26 04
1312 : : * 57 4f 2d 31
1313 : : * 34 01
1314 : : * 41
1315 : : * 36 02
1316 : : * 4d 57
1317 : : * d3 02
1318 : : * 30 30
1319 : : * 00 00 fc bf <<< OpenSC bug (junk in the end instead of last encoded elements)
1320 : : *
1321 : : *
1322 : : *
1323 : : *
1324 : : * A0000000791201: Empty
1325 : : * $ opensc-tool -s 00A4040007A0000000791201 -s 8056010000
1326 : : * PROPERTIES:
1327 : : * 01 05
1328 : : * 10 02 06 02 03
1329 : : * 40 01
1330 : : * 01
1331 : : * 50 0B
1332 : : * 41 02
1333 : : * 12 01
1334 : : * 42 05
1335 : : * 00 42 02 C0 05
1336 : : * $ opensc-tool -s 00A4040007A0000000791201 -s 8052000002010202
1337 : : * $ opensc-tool -s 00A4040007A0000000791201 -s 8052000002020202
1338 : : * TAG, VALUE BUFFERS:
1339 : : * empty
1340 : : *
1341 : : * A0000000791202: Empty
1342 : : * $ opensc-tool -s 00A4040007A0000000791202 -s 8056010000
1343 : : * PROPERTIES:
1344 : : * 01 05
1345 : : * 10 02 06 02 03
1346 : : * 40 01
1347 : : * 01
1348 : : * 50 0B
1349 : : * 41 02
1350 : : * 12 02
1351 : : * 42 05
1352 : : * 00 42 01 40 06
1353 : : * $ opensc-tool -s 00A4040007A0000000791202 -s 8052000002010202
1354 : : * $ opensc-tool -s 00A4040007A0000000791202 -s 8052000002020202
1355 : : * TAG, VALUE BUFFERS:
1356 : : * empty
1357 : : *
1358 : : * A00000007902F0: Empty (no buffers)
1359 : : * $ opensc-tool -s 00A4040007A00000007902F0 -s 8056010000
1360 : : * PROPERTIES:
1361 : : * 01 05
1362 : : * 10 02 06 02 03
1363 : : * 40 01
1364 : : * 00
1365 : : *
1366 : : * A00000007902F1: Empty (no buffers)
1367 : : * $ opensc-tool -s 00A4040007A00000007902F1 -s 8056010000
1368 : : * PROPERTIES:
1369 : : * 01 05
1370 : : * 10 02 06 02 03
1371 : : * 40 01
1372 : : * 00
1373 : : *
1374 : : * A00000007902F2: Empty (no buffers)
1375 : : * $ opensc-tool -s 00A4040007A00000007902F2 -s 8056010000
1376 : : * PROPERTIES:
1377 : : * 01 05
1378 : : * 10 02 06 02 03
1379 : : * 40 01
1380 : : * 00
1381 : : *
1382 : : *
1383 : : * Access Control File
1384 : : * A0000001163000
1385 : : * PROPERTIES: shared among the OIDs
1386 : : * 01 05
1387 : : * 10 02 06 02 03
1388 : : * 40 01 Number of objects
1389 : : * 04
1390 : : * 50 0B TV Buffer
1391 : : * 41 02 Object ID
1392 : : * 30 00
1393 : : * 42 05
1394 : : * 00 <- These are SimpleTLV
1395 : : * 1A 00 D2 07
1396 : : * 50 0B TV Buffer
1397 : : * 41 02 Object ID
1398 : : * 60 10
1399 : : * 42 05
1400 : : * 00
1401 : : * 0E 00 BA 0B
1402 : : * 50 0B TV buffer
1403 : : * 41 02 Object ID
1404 : : * 60 30
1405 : : * 42 05
1406 : : * 00
1407 : : * 0A 00 EE 2C
1408 : : * 50 0B TV Buffer
1409 : : * 41 02 Object ID
1410 : : * 90 00
1411 : : * 42 05
1412 : : * 00
1413 : : * 0E 00 4E 04
1414 : : *
1415 : : * OID buffers (from NIST SP 800-73-4)
1416 : : * :3000: Card Holder Unique Identifier
1417 : : * Tag buffer:
1418 : : * 0C 00
1419 : : * 30 19 FASC
1420 : : * 34 10 GUID
1421 : : * 35 08 Expiration Date
1422 : : * 3E FF 1A 06 Issuer Asymmetric Signature
1423 : : * FE 00 Error detection code
1424 : : * Value buffer:
1425 : : * D4 F8 10 DA 08 26 6C 10 A2 04 E5 83 60 DA 01 0C
1426 : : * 11 CE 66 62 84 38 10 93 E1 <-- SEIWG data
1427 : : *
1428 : : * :6010: Cardholder Fingerprints
1429 : : * Tag buffer:
1430 : : * 06 00
1431 : : * BC FF CF 04 Fingerprint I & II
1432 : : * FE 00 Error Detection Code
1433 : : *
1434 : : * :6030: Cardholder Facial Image
1435 : : * Tag buffer:
1436 : : * 06 00
1437 : : * BC FF A9 29 Image for Visual Verification
1438 : : * FE 00 Error Detection Code
1439 : : *
1440 : : * :9000: Security Object
1441 : : * 08 00
1442 : : * BB FF 38 02 Security Object
1443 : : * BA 30 Mapping of DG to ContainerID
1444 : : * FE 00 Error Detectionc Code
1445 : : *
1446 : : * we should do this as passthrough too
1447 : : */
1448 : :
1449 : :
1450 : : static VCardAppletPrivate *
1451 : 6 : cac_new_ccc_applet_private(int cert_count)
1452 : : {
1453 : : VCardAppletPrivate *applet_private = NULL;
1454 : :
1455 : : /* CCC applet Properties ex.:
1456 : : * 01 Tag: Applet Information
1457 : : * 05 Length
1458 : : * 10 Applet family
1459 : : * 02 06 02 03 Applet version
1460 : : * 40 Tag: Number of objects managed by this instance
1461 : : * 01 Length
1462 : : * 01 One
1463 : : * 50 Tag: First TV-Buffer Object
1464 : : * 0B Length
1465 : : * 41 Tag: ObjectID
1466 : : * 02 Length
1467 : : * DB 00
1468 : : * 42 Tag: Buffer Properties
1469 : : * 05 Length
1470 : : * 00 Type of Tag Supported
1471 : : * F6 00 T-Buffer length (LSB, MSB)
1472 : : * 04 02 V-Buffer length (LSB, MSB)
1473 : : */
1474 : : static unsigned char object_id[] = "\xDB\x00";
1475 : : static unsigned char buffer_properties[] = "\x00\x00\x00\x00\x00";
1476 : : static unsigned char buffer_26[] = "\x01";
1477 : : static struct simpletlv_member tv_object[3] = {
1478 : : {CAC_PROPERTIES_OBJECT_ID, 2, {/*.value = object_id*/},
1479 : : SIMPLETLV_TYPE_LEAF},
1480 : : {CAC_PROPERTIES_BUFFER_PROPERTIES, 5, {/*.value = buffer_properties*/},
1481 : : SIMPLETLV_TYPE_LEAF},
1482 : : {0x26, 0x01, {/*.value = buffer_26*/}, SIMPLETLV_TYPE_LEAF},
1483 : : };
1484 : : static unsigned char applet_information[] = "\x10\x02\x06\x02\x03";
1485 : : static unsigned char number_objects[] = "\x01";
1486 : : static unsigned char buffer_39[] = "\x00";
1487 : : static unsigned char aca_aid[] = "\xA0\x00\x00\x00\x79\x03\x00";
1488 : : static struct simpletlv_member properties[] = {
1489 : : {CAC_PROPERTIES_APPLET_INFORMATION, 5, {/*.value = applet_information*/},
1490 : : SIMPLETLV_TYPE_LEAF},
1491 : : {CAC_PROPERTIES_NUMBER_OBJECTS, 1, {/*.value = number_objects */},
1492 : : SIMPLETLV_TYPE_LEAF},
1493 : : {CAC_PROPERTIES_TV_OBJECT, 2, {/*.child = tv_object*/},
1494 : : SIMPLETLV_TYPE_COMPOUND},
1495 : : {0x39, 0x01, {/*.child = buffer_39*/}, SIMPLETLV_TYPE_LEAF},
1496 : : {0x3A, 0x07, {/*.child = aca_aid*/}, SIMPLETLV_TYPE_LEAF},
1497 : : };
1498 : : size_t properties_len = sizeof(properties)/sizeof(struct simpletlv_member);
1499 : :
1500 : 6 : unsigned char card_identifier[] = "\xA0\x00\x00\x00\x79\x03\x02\x40\x70\x50"
1501 : : "\x72\x36\x0E\x00\x00\x58\xBD\x00\x2C\x19\xB5";
1502 : 6 : unsigned char cc_version[] = "\x21";
1503 : 6 : unsigned char cg_version[] = "\x21";
1504 : 6 : unsigned char cardurl[21][16] = {
1505 : : /* common CardURLs */
1506 : : "\xA0\x00\x00\x00\x79\x01\x02\xFB\x02\xFB\x00\x00\x00\x00\x00\x00", /* ??? */
1507 : : "\xA0\x00\x00\x00\x79\x01\x02\xFE\x02\xFE\x00\x00\x00\x00\x00\x00", /* PKI Certificate */
1508 : : "\xA0\x00\x00\x00\x79\x01\x02\xFD\x02\xFD\x00\x00\x00\x00\x00\x00", /* PKI Credential */
1509 : : "\xA0\x00\x00\x00\x79\x01\x02\x00\x02\x00\x00\x00\x00\x00\x00\x00", /* Person Instance */
1510 : : "\xA0\x00\x00\x00\x79\x01\x02\x01\x02\x01\x00\x00\x00\x00\x00\x00", /* Personel */
1511 : : "\xA0\x00\x00\x01\x16\x01\x30\x00\x30\x00\x00\x00\x00\x00\x00\x00", /* Access Control F. */
1512 : : "\xA0\x00\x00\x01\x16\x01\x60\x10\x30\x00\x00\x00\x00\x00\x00\x00", /* -//- */
1513 : : "\xA0\x00\x00\x01\x16\x01\x60\x30\x30\x00\x00\x00\x00\x00\x00\x00", /* -//- */
1514 : : "\xA0\x00\x00\x01\x16\x01\x90\x00\x30\x00\x00\x00\x00\x00\x00\x00", /* -//- */
1515 : : "\xA0\x00\x00\x00\x79\x01\x12\x01\x12\x01\x00\x00\x00\x00\x00\x00", /* ?? */
1516 : : "\xA0\x00\x00\x00\x79\x01\x12\x02\x12\x02\x00\x00\x00\x00\x00\x00", /* ?? */
1517 : : /* dynamic list of all possible PKI objects CardURLs */
1518 : : "\xA0\x00\x00\x00\x79\x04\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00", /* PKI */
1519 : : "\xA0\x00\x00\x00\x79\x04\x01\x01\x01\x01\x00\x00\x00\x00\x00\x00", /* PKI */
1520 : : "\xA0\x00\x00\x00\x79\x04\x01\x02\x01\x02\x00\x00\x00\x00\x00\x00", /* PKI */
1521 : : "\xA0\x00\x00\x00\x79\x04\x01\x03\x01\x03\x00\x00\x00\x00\x00\x00", /* PKI */
1522 : : "\xA0\x00\x00\x00\x79\x04\x01\x04\x01\x04\x00\x00\x00\x00\x00\x00", /* PKI */
1523 : : "\xA0\x00\x00\x00\x79\x04\x01\x05\x01\x05\x00\x00\x00\x00\x00\x00", /* PKI */
1524 : : "\xA0\x00\x00\x00\x79\x04\x01\x06\x01\x06\x00\x00\x00\x00\x00\x00", /* PKI */
1525 : : "\xA0\x00\x00\x00\x79\x04\x01\x07\x01\x07\x00\x00\x00\x00\x00\x00", /* PKI */
1526 : : "\xA0\x00\x00\x00\x79\x04\x01\x08\x01\x08\x00\x00\x00\x00\x00\x00", /* PKI */
1527 : : "\xA0\x00\x00\x00\x79\x04\x01\x09\x01\x09\x00\x00\x00\x00\x00\x00", /* PKI */
1528 : : /*
1529 : : * [ Empty for VM cards! ]
1530 : : * [ RID 5B ][T ][ OID ][ AID ] [ P][AccessKeyInfo ][ K]
1531 : : * CardApplicationType-^ ^ ^- Pin ID ^
1532 : : * AccessProfile is empty --------------' |
1533 : : * Key Crypto Algorithm ---------------------------------------'
1534 : : *
1535 : : * AID -- the "address" of the container
1536 : : * Object ID = object type
1537 : : *
1538 : : * 7.3 The Applications CardURL
1539 : : */
1540 : : };
1541 : 6 : unsigned char pkcs15[] = "\x00";
1542 : : /* NIST SP 800-73-4: The data model of the PIV Card Application shall
1543 : : * be identified by data model number 0x10 */
1544 : 6 : unsigned char reg_data_model[] = "\x10";
1545 : 6 : unsigned char acr_table[] = "\x07\xA0\x00\x00\x00\x79\x03\x00\x00\x00\x00"
1546 : : "\x00\x00\x00\x00\x00\x00";
1547 : : static struct simpletlv_member buffer[] = {
1548 : : {CAC_CCC_CARD_IDENTIFIER, 0x15, {/*.value = card_identifier*/},
1549 : : SIMPLETLV_TYPE_LEAF},
1550 : : {CAC_CCC_CAPABILITY_CONTAINER_VERSION, 1, {/*.value = cc_version*/},
1551 : : SIMPLETLV_TYPE_LEAF},
1552 : : {CAC_CCC_CAPABILITY_GRAMMAR_VERSION, 1, {/*.value = cg_version*/},
1553 : : SIMPLETLV_TYPE_LEAF},
1554 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[0]*/},
1555 : : SIMPLETLV_TYPE_LEAF},
1556 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[1]*/},
1557 : : SIMPLETLV_TYPE_LEAF},
1558 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[2]*/},
1559 : : SIMPLETLV_TYPE_LEAF},
1560 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[3]*/},
1561 : : SIMPLETLV_TYPE_LEAF},
1562 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[4]*/},
1563 : : SIMPLETLV_TYPE_LEAF},
1564 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[5]*/},
1565 : : SIMPLETLV_TYPE_LEAF},
1566 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[6]*/},
1567 : : SIMPLETLV_TYPE_LEAF},
1568 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[7]*/},
1569 : : SIMPLETLV_TYPE_LEAF},
1570 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[8]*/},
1571 : : SIMPLETLV_TYPE_LEAF},
1572 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[9]*/},
1573 : : SIMPLETLV_TYPE_LEAF},
1574 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[10]*/},
1575 : : SIMPLETLV_TYPE_LEAF},
1576 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[11]*/},
1577 : : SIMPLETLV_TYPE_NONE},
1578 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[12]*/},
1579 : : SIMPLETLV_TYPE_NONE},
1580 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[13]*/},
1581 : : SIMPLETLV_TYPE_NONE},
1582 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[14]*/},
1583 : : SIMPLETLV_TYPE_NONE},
1584 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[15]*/},
1585 : : SIMPLETLV_TYPE_NONE},
1586 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[16]*/},
1587 : : SIMPLETLV_TYPE_NONE},
1588 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[17]*/},
1589 : : SIMPLETLV_TYPE_NONE},
1590 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[18]*/},
1591 : : SIMPLETLV_TYPE_NONE},
1592 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[19]*/},
1593 : : SIMPLETLV_TYPE_NONE},
1594 : : {CAC_CCC_APPLICATION_CARDURL, 16, {/*.value = cardurl[20]*/},
1595 : : SIMPLETLV_TYPE_NONE},
1596 : : {CAC_CCC_PKCS15, 1, {/*.value = pkcs15 */},
1597 : : SIMPLETLV_TYPE_LEAF},
1598 : : {CAC_CCC_REGISTERED_DATA_MODEL_NUMBER, 1, {/*.value = reg_data_model */},
1599 : : SIMPLETLV_TYPE_LEAF},
1600 : : {CAC_CCC_ACCESS_CONTROL_RULE_TABLE, 17, {/*.value = acr_table */},
1601 : : SIMPLETLV_TYPE_LEAF},
1602 : : {CAC_CCC_CARD_APDUS, 0, {}, SIMPLETLV_TYPE_LEAF},
1603 : : {CAC_CCC_REDIRECTION_TAG, 0, {}, SIMPLETLV_TYPE_LEAF},
1604 : : {CAC_CCC_CAPABILITY_TUPLES, 0, {}, SIMPLETLV_TYPE_LEAF},
1605 : : {CAC_CCC_STATUS_TUPLES, 0, {}, SIMPLETLV_TYPE_LEAF},
1606 : : {CAC_CCC_NEXT_CCC, 0, {}, SIMPLETLV_TYPE_LEAF},
1607 : : {CAC_CCC_ERROR_DETECTION_CODE, 0, {}, SIMPLETLV_TYPE_LEAF},
1608 : : };
1609 : : size_t buffer_len = sizeof(buffer)/sizeof(struct simpletlv_member);
1610 : : int i;
1611 : :
1612 : 6 : applet_private = g_new0(VCardAppletPrivate, 1);
1613 : :
1614 : : /* prepare the buffers to when READ_BUFFER will be called.
1615 : : * Assuming VM card with (LSB first if > 255)
1616 : : * separate Tag+Length, Value buffers as described in 8.4:
1617 : : * 2 B 1 B 1-3 B 1 B 1-3 B
1618 : : * [ T-Len ] [ Tag1 ] [ Len1 ] [ Tag2] [ Len2 ] [...]
1619 : : *
1620 : : * 2 B Len1 B Len2 B
1621 : : * [ V-Len ] [ Value 1 ] [ Value 2 ] [...]
1622 : : * */
1623 : :
1624 : 6 : buffer[0].value.value = card_identifier;
1625 : 6 : buffer[1].value.value = cc_version;
1626 : 6 : buffer[2].value.value = cg_version;
1627 : : /* common CardURLs */
1628 [ + + ]: 72 : for (i = 0; i < 11; i++) {
1629 : 66 : buffer[3+i].value.value = cardurl[i];
1630 : : }
1631 : :
1632 [ - + ]: 6 : if (cert_count > 10) {
1633 : : // XXX too many objects for now
1634 : 0 : g_debug("Too many PKI objects");
1635 : 0 : return NULL;
1636 : : }
1637 : : /* Generate card URLs for PKI applets */
1638 [ + + ]: 22 : for (i = 0; i < cert_count; i++) {
1639 : 16 : buffer[i+14].value.value = cardurl[i+11];
1640 : 16 : buffer[i+14].type = SIMPLETLV_TYPE_LEAF;
1641 : : }
1642 : :
1643 : 6 : buffer[24].value.value = pkcs15;
1644 : 6 : buffer[25].value.value = reg_data_model;
1645 : 6 : buffer[26].value.value = acr_table;
1646 : : /* CCC Tag+Len buffer */
1647 : : /* Ex:
1648 : : * 34 00 Length of complete buffer
1649 : : * F0 15 Card Identifier
1650 : : * F1 01 Capability Container version number
1651 : : * F2 01 Capability Grammar version number
1652 : : * F3 10 Applications CardURL
1653 : : * F3 10 Applications CardURL
1654 : : * F3 10 Applications CardURL
1655 : : * F3 10 Applications CardURL
1656 : : * F3 10 Applications CardURL
1657 : : * F3 10 Applications CardURL
1658 : : * F3 10 Applications CardURL
1659 : : * F3 10 Applications CardURL
1660 : : * F3 10 Applications CardURL
1661 : : * F3 10 Applications CardURL
1662 : : * F3 10 Applications CardURL
1663 : : * F3 10 Applications CardURL
1664 : : * F3 10 Applications CardURL
1665 : : * F3 10 Applications CardURL
1666 : : * F4 01 PKCS#15
1667 : : * F5 01 Registered Data Model number
1668 : : * F6 11 Access Control Rule Table
1669 : : * F7 00 CARD APDUs
1670 : : * FA 00 Redirection Tag
1671 : : * FB 00 Capability Tuples (CTs)
1672 : : * FC 00 Status Tuples (STs)
1673 : : * FD 00 Next CCC
1674 : : * FE 00 Error Detection Code
1675 : : */
1676 : 6 : applet_private->tag_buffer_len = cac_create_tl_file(buffer, buffer_len,
1677 : : &applet_private->tag_buffer);
1678 [ - + ]: 6 : if (applet_private->tag_buffer_len == 0)
1679 : 0 : goto failure;
1680 : 6 : g_debug("%s: applet_private->tag_buffer = %s", __func__,
1681 : : hex_dump(applet_private->tag_buffer, applet_private->tag_buffer_len));
1682 : :
1683 : : /* Value buffer */
1684 : : /* Ex:
1685 : : * 0A 01 Length of complete buffer
1686 : : * A0 00 00 00 79 03 02 40 70 50 72 36 0E 00 00 58 BD 00 2C 19 B5
1687 : : * [ GSC-RID ] [] [] [ Card ID ]
1688 : : * Manufacturer ID-' '- Card Type = javaCard
1689 : : * Card Identifier
1690 : : * 21 CC version
1691 : : * 21 Capability Grammar version
1692 : : * A0 00 00 00 79 01 02 FB 02 FB 00 00 00 00 00 00
1693 : : * A0 00 00 00 79 01 02 FE 02 FE 00 00 00 00 00 00
1694 : : * A0 00 00 00 79 01 02 FD 02 FD 00 00 00 00 00 00
1695 : : * A0 00 00 00 79 01 02 00 02 00 00 00 00 00 00 00
1696 : : * A0 00 00 00 79 01 02 01 02 01 00 00 00 00 00 00
1697 : : * A0 00 00 00 79 04 01 00 01 00 00 00 00 00 00 00
1698 : : * A0 00 00 00 79 04 01 01 01 01 00 00 00 00 00 00
1699 : : * A0 00 00 00 79 04 01 02 01 02 00 00 00 00 00 00
1700 : : * A0 00 00 01 16 01 30 00 30 00 00 00 00 00 00 00
1701 : : * A0 00 00 01 16 01 60 10 30 00 00 00 00 00 00 00
1702 : : * A0 00 00 01 16 01 60 30 30 00 00 00 00 00 00 00
1703 : : * A0 00 00 01 16 01 90 00 30 00 00 00 00 00 00 00
1704 : : * A0 00 00 00 79 01 12 01 12 01 00 00 00 00 00 00
1705 : : * A0 00 00 00 79 01 12 02 12 02 00 00 00 00 00 00
1706 : : * [ RID ] [] [OID] [AID] [ unused in VM? ]
1707 : : * Appl. Type -'
1708 : : * 0x01 generic
1709 : : * 0x02 ski
1710 : : * 0x04 pki
1711 : : * CardURLs
1712 : : * 00 PKCS#15
1713 : : * 10 Reg. data model number
1714 : : * 07 A0 00 00 00 79 03 00 00 00 00 00 00 00 00 00 00
1715 : : * [] [ ACA AID ] [ ???? ]
1716 : : * Access Control Rule table
1717 : : */
1718 : 6 : applet_private->val_buffer_len = cac_create_val_file(buffer, buffer_len,
1719 : : &applet_private->val_buffer);
1720 [ - + ]: 6 : if (applet_private->val_buffer_len == 0)
1721 : 0 : goto failure;
1722 : 6 : g_debug("%s: applet_private->val_buffer = %s", __func__,
1723 : : hex_dump(applet_private->val_buffer, applet_private->val_buffer_len));
1724 : :
1725 : : /* Inject Object ID */
1726 : 6 : tv_object[0].value.value = object_id;
1727 : :
1728 : : /* Create Object ID list */
1729 : 6 : applet_private->coids = g_malloc(sizeof(struct coid));
1730 : 6 : memcpy(applet_private->coids[0].v, object_id, 2);
1731 : 6 : applet_private->coids_len = 1;
1732 : :
1733 : : /* Inject T-Buffer and V-Buffer lengths in the properties buffer */
1734 : 6 : ushort2lebytes(&buffer_properties[1], applet_private->tag_buffer_len);
1735 : 6 : ushort2lebytes(&buffer_properties[3], applet_private->val_buffer_len);
1736 : 6 : tv_object[1].value.value = buffer_properties;
1737 : 6 : tv_object[2].value.value = buffer_26;
1738 : :
1739 : : /* Inject Applet Version */
1740 : 6 : properties[0].value.value = applet_information;
1741 : 6 : properties[1].value.value = number_objects;
1742 : 6 : properties[2].value.child = tv_object;
1743 : 6 : properties[3].value.value = buffer_39;
1744 : 6 : properties[4].value.value = aca_aid;
1745 : :
1746 : : /* Link the properties */
1747 : 6 : applet_private->properties = properties;
1748 : 6 : applet_private->properties_len = 3;
1749 : 6 : applet_private->long_properties_len = properties_len;
1750 : :
1751 : 6 : return applet_private;
1752 : :
1753 : 0 : failure:
1754 : 0 : cac_delete_ccc_applet_private(applet_private);
1755 : 0 : return NULL;
1756 : : }
1757 : :
1758 : :
1759 : : /*
1760 : : * create a new CCC applet
1761 : : */
1762 : : static VCardApplet *
1763 : 6 : cac_new_ccc_applet(int cert_count)
1764 : : {
1765 : : VCardAppletPrivate *applet_private;
1766 : : VCardApplet *applet;
1767 : :
1768 : 6 : applet_private = cac_new_ccc_applet_private(cert_count);
1769 [ - + ]: 6 : if (applet_private == NULL) {
1770 : 0 : goto failure;
1771 : : }
1772 : 6 : applet = vcard_new_applet(cac_common_process_apdu_read, NULL,
1773 : : cac_ccc_aid, sizeof(cac_ccc_aid));
1774 [ - + ]: 6 : if (applet == NULL) {
1775 : 0 : goto failure;
1776 : : }
1777 : 6 : vcard_set_applet_private(applet, applet_private,
1778 : : cac_delete_ccc_applet_private);
1779 : : applet_private = NULL;
1780 : :
1781 : 6 : return applet;
1782 : :
1783 : : failure:
1784 : : if (applet_private != NULL) {
1785 : 0 : cac_delete_ccc_applet_private(applet_private);
1786 : : }
1787 : : return NULL;
1788 : : }
1789 : :
1790 : : static VCardAppletPrivate *
1791 : 6 : cac_new_aca_applet_private(int cert_count)
1792 : : {
1793 : : CACACAAppletData *aca_applet_data = NULL;
1794 : : VCardAppletPrivate *applet_private = NULL;
1795 : :
1796 : : /* ACA applet Properties ex.:
1797 : : * 01 Tag: Applet Information
1798 : : * 05 Length
1799 : : * 10 Applet family
1800 : : * 02 06 02 02 Applet version
1801 : : */
1802 : :
1803 : : /* 0x40 Long properties (?):
1804 : : * 01 05 Applet Information
1805 : : * 10 02 06 02 02
1806 : : * 23 0C
1807 : : * 20 11 00 00 00 00 00 00 00 00 00 58
1808 : : * 2A 02
1809 : : * 02 00
1810 : : * 2B 05 RID ???
1811 : : * A0 00 00 00 79
1812 : : * 22 10
1813 : : * 00 00 00 DA 01 B4 03 30 00 00 00 70 00 51 02 9D
1814 : : * 2C 01
1815 : : * 00
1816 : : * 20 02
1817 : : * 08 01
1818 : : * 21 01
1819 : : * 0F
1820 : : * 32 04
1821 : : * 03 03 03 03
1822 : : * 30 01
1823 : : * 08
1824 : : * 31 04
1825 : : * 06 08 00 00
1826 : : * 24 01
1827 : : * FF
1828 : : * 25 02
1829 : : * 01 00
1830 : : * 26 01
1831 : : * 01
1832 : : */
1833 : :
1834 : : static unsigned char applet_information[] = "\x10\x02\x06\x02\x02";
1835 : : static unsigned char buffer_23[] = "\x20\x11\x00\x00\x00\x00\x00\x00\x00"
1836 : : "\x00\x00\x58";
1837 : : static unsigned char buffer_2A[] = "\x02\x00";
1838 : : static unsigned char rid[] = "\xA0\x00\x00\x00\x79";
1839 : : static unsigned char buffer_22[] = "\x00\x00\x00\xDA\x01\xB4\x03\x30\x00"
1840 : : "\x00\x00\x70\x00\x51\x02\x9D";
1841 : : static unsigned char buffer_2C[] = "\x00";
1842 : : static unsigned char buffer_20[] = "\x08\x01";
1843 : : static unsigned char buffer_21[] = "\x0F";
1844 : : static unsigned char buffer_32[] = "\x03\x03\x03\x03";
1845 : : static unsigned char buffer_30[] = "\x08";
1846 : : static unsigned char buffer_31[] = "\x06\x08\x00\x00";
1847 : : static unsigned char buffer_24[] = "\xFF";
1848 : : static unsigned char buffer_25[] = "\x01\x00";
1849 : : static unsigned char buffer_26[] = "\x01";
1850 : : static struct simpletlv_member properties[] = {
1851 : : {CAC_PROPERTIES_APPLET_INFORMATION, 5, {/*.value = applet_information*/},
1852 : : SIMPLETLV_TYPE_LEAF},
1853 : : {0x23, 0x0C, {/*.value = buffer_23*/}, SIMPLETLV_TYPE_LEAF},
1854 : : {0x2A, 0x02, {/*.value = buffer_2A*/}, SIMPLETLV_TYPE_LEAF},
1855 : : {0x2B, 0x05, {/*.value = rid*/}, SIMPLETLV_TYPE_LEAF},
1856 : : {0x22, 0x10, {/*.value = buffer_22*/}, SIMPLETLV_TYPE_LEAF},
1857 : : {0x2C, 0x01, {/*.value = buffer_2C*/}, SIMPLETLV_TYPE_LEAF},
1858 : : {0x20, 0x02, {/*.value = buffer_20*/}, SIMPLETLV_TYPE_LEAF},
1859 : : {0x21, 0x01, {/*.value = buffer_21*/}, SIMPLETLV_TYPE_LEAF},
1860 : : {0x32, 0x04, {/*.value = buffer_32*/}, SIMPLETLV_TYPE_LEAF},
1861 : : {0x30, 0x01, {/*.value = buffer_30*/}, SIMPLETLV_TYPE_LEAF},
1862 : : {0x31, 0x04, {/*.value = buffer_31*/}, SIMPLETLV_TYPE_LEAF},
1863 : : {0x24, 0x01, {/*.value = buffer_24*/}, SIMPLETLV_TYPE_LEAF},
1864 : : {0x25, 0x02, {/*.value = buffer_25*/}, SIMPLETLV_TYPE_LEAF},
1865 : : {0x26, 0x01, {/*.value = buffer_26*/}, SIMPLETLV_TYPE_LEAF},
1866 : : };
1867 : :
1868 : : /* Inject Applet Version into Applet information */
1869 : 6 : properties[0].value.value = applet_information;
1870 : 6 : properties[1].value.value = buffer_23;
1871 : 6 : properties[2].value.value = buffer_2A;
1872 : 6 : properties[3].value.value = rid;
1873 : 6 : properties[4].value.value = buffer_22;
1874 : 6 : properties[5].value.value = buffer_2C;
1875 : 6 : properties[6].value.value = buffer_20;
1876 : 6 : properties[7].value.value = buffer_21;
1877 : 6 : properties[8].value.value = buffer_32;
1878 : 6 : properties[9].value.value = buffer_30;
1879 : 6 : properties[10].value.value = buffer_31;
1880 : 6 : properties[11].value.value = buffer_24;
1881 : 6 : properties[12].value.value = buffer_25;
1882 : 6 : properties[13].value.value = buffer_26;
1883 : :
1884 : : /* Create the private data structure */
1885 : 6 : applet_private = g_new0(VCardAppletPrivate, 1);
1886 : : aca_applet_data = &(applet_private->u.aca_data);
1887 : :
1888 : : /* store the applet OID */
1889 : 6 : applet_private->coids = g_malloc(sizeof(struct coid));
1890 : 6 : applet_private->coids[0].v[0] = 0x03;
1891 : 6 : applet_private->coids[0].v[1] = 0x00;
1892 : 6 : applet_private->coids_len = 1;
1893 : :
1894 : : /* Link the properties */
1895 : 6 : applet_private->properties = properties;
1896 : 6 : applet_private->properties_len = 1;
1897 : 6 : applet_private->long_properties_len = 14;
1898 : :
1899 : 6 : aca_applet_data->pki_applets = cert_count;
1900 : :
1901 : 6 : return applet_private;
1902 : : }
1903 : :
1904 : : static VCardAppletPrivate *
1905 : 54 : cac_new_empty_applet_private(unsigned char objects[][2], unsigned int objects_len)
1906 : : {
1907 : : VCardAppletPrivate *applet_private = NULL;
1908 : :
1909 : 54 : unsigned char object_id[] = "\x00\x00";
1910 : 54 : unsigned char buffer_properties[] = "\x00\x00\x00\x00\x00";
1911 : : static unsigned char buffer_26[] = "\x01";
1912 : : static struct simpletlv_member tv_buffer[] = {
1913 : : {CAC_PROPERTIES_OBJECT_ID, 2, {/*.value = object_id*/},
1914 : : SIMPLETLV_TYPE_LEAF},
1915 : : {CAC_PROPERTIES_BUFFER_PROPERTIES, 5, {/*.value = buffer_properties*/},
1916 : : SIMPLETLV_TYPE_LEAF},
1917 : : {0x26, 0x01, {/*.value = buffer_26*/}, SIMPLETLV_TYPE_LEAF},
1918 : : };
1919 : 54 : unsigned char applet_information[] = "\x10\x02\x06\x02\x03";
1920 : 54 : unsigned char number_objects = 0;
1921 : : static struct simpletlv_member properties[7] = {
1922 : : {CAC_PROPERTIES_APPLET_INFORMATION, 5, {/*.value = applet_information*/},
1923 : : SIMPLETLV_TYPE_LEAF},
1924 : : {CAC_PROPERTIES_NUMBER_OBJECTS, 1, {/*.value = number_objects*/},
1925 : : SIMPLETLV_TYPE_LEAF},
1926 : : {CAC_PROPERTIES_TV_OBJECT, 3, {.child = NULL},
1927 : : SIMPLETLV_TYPE_COMPOUND},
1928 : : {CAC_PROPERTIES_TV_OBJECT, 3, {.child = NULL},
1929 : : SIMPLETLV_TYPE_COMPOUND},
1930 : : {CAC_PROPERTIES_TV_OBJECT, 3, {.child = NULL},
1931 : : SIMPLETLV_TYPE_COMPOUND},
1932 : : {CAC_PROPERTIES_TV_OBJECT, 3, {.child = NULL},
1933 : : SIMPLETLV_TYPE_COMPOUND},
1934 : : {CAC_PROPERTIES_TV_OBJECT, 3, {.child = NULL},
1935 : : SIMPLETLV_TYPE_COMPOUND},
1936 : : };
1937 : : unsigned properties_len = 2;
1938 : : unsigned int i;
1939 : :
1940 [ + + ]: 108 : for (i = 0; i < objects_len; i++) {
1941 : : /* Adjust Object ID based on the AID */
1942 : 54 : object_id[0] = objects[i][0];
1943 : 54 : object_id[1] = objects[i][1];
1944 : :
1945 : : /* Create arbitrary sized buffers */
1946 : 54 : buffer_properties[0] = 0x01; // not a SimpleTLV
1947 : 54 : buffer_properties[1] = 0x60;
1948 : 54 : buffer_properties[2] = 0x00;
1949 : 54 : buffer_properties[3] = 0x60;
1950 : 54 : buffer_properties[4] = 0x00;
1951 : :
1952 : : /* Inject Object ID */
1953 : 54 : tv_buffer[0].value.value = object_id;
1954 : 54 : tv_buffer[1].value.value = buffer_properties;
1955 : 54 : tv_buffer[2].value.value = buffer_26;
1956 : :
1957 : : /* clone the object to the structure */
1958 : 54 : properties[2+i].value.child = simpletlv_clone(tv_buffer, 3);
1959 [ - + ]: 54 : if (properties[2+i].value.child == NULL)
1960 : 0 : goto failure;
1961 : :
1962 : 54 : properties_len++;
1963 : 54 : number_objects++;
1964 : : }
1965 : :
1966 : : /* Inject Applet Version */
1967 : 54 : properties[0].value.value = applet_information;
1968 : 54 : properties[1].value.value = &number_objects;
1969 : :
1970 : : /* Create the private data structure */
1971 : 54 : applet_private = g_new0(VCardAppletPrivate, 1);
1972 : :
1973 : : /* Create Object ID list */
1974 [ + + ]: 54 : if (objects_len > 0) {
1975 : 36 : applet_private->coids = g_memdup2(objects, sizeof(struct coid) * objects_len);
1976 : 36 : applet_private->coids_len = objects_len;
1977 : : }
1978 : :
1979 : : /* Clone the properties */
1980 : 54 : applet_private->properties_len = properties_len;
1981 : 54 : applet_private->long_properties_len = properties_len; /*TODO*/
1982 : 54 : applet_private->properties = simpletlv_clone(properties, properties_len);
1983 : :
1984 : : /* Avoid dangling pointers in the static structure */
1985 : 54 : properties[0].value.value = NULL;
1986 : 54 : properties[1].value.value = NULL;
1987 : :
1988 [ + - ]: 54 : if (applet_private->properties == NULL)
1989 : 0 : goto failure;
1990 : :
1991 : : /* clean up the allocated properties */
1992 [ + + ]: 108 : for (i = 0; i < number_objects; i++) {
1993 : 54 : simpletlv_free(properties[2+i].value.child, 3);
1994 : : }
1995 : :
1996 : : /* tag/value buffers */
1997 : 54 : applet_private->tag_buffer = g_malloc0(2);
1998 : 54 : applet_private->tag_buffer_len = 2;
1999 : 54 : applet_private->val_buffer = g_malloc0(2);
2000 : 54 : applet_private->val_buffer_len = 2;
2001 : :
2002 : 54 : return applet_private;
2003 : :
2004 : 0 : failure:
2005 [ # # ]: 0 : for (i = 0; i < number_objects; i++) {
2006 : 0 : simpletlv_free(properties[2+i].value.child, 3);
2007 : : }
2008 [ # # ]: 0 : if (applet_private != NULL) {
2009 : 0 : cac_delete_aca_applet_private(applet_private);
2010 : : }
2011 : : return NULL;
2012 : : }
2013 : :
2014 : : static VCardAppletPrivate *
2015 : 12 : cac_new_passthrough_applet_private(G_GNUC_UNUSED VCard *card, const char *label,
2016 : : const unsigned char *aid, unsigned int aid_len)
2017 : : {
2018 : : CACPTAppletData *pt_applet_data;
2019 : : VCardAppletPrivate *applet_private;
2020 : :
2021 : 12 : unsigned char object_id[] = "\x00\x00";
2022 : 12 : unsigned char buffer_properties[] = "\x00\x00\x00\x00\x00";
2023 : : static unsigned char buffer_26[] = "\x01";
2024 : : static struct simpletlv_member tv_buffer[3] = {
2025 : : {CAC_PROPERTIES_OBJECT_ID, 2, {/*.value = object_id*/},
2026 : : SIMPLETLV_TYPE_LEAF},
2027 : : {CAC_PROPERTIES_BUFFER_PROPERTIES, 5, {/*.value = buffer_properties*/},
2028 : : SIMPLETLV_TYPE_LEAF},
2029 : : {0x26, 0x01, {/*.value = buffer_26*/}, SIMPLETLV_TYPE_LEAF},
2030 : : };
2031 : 12 : unsigned char applet_information[] = "\x10\x02\x06\x02\x03";
2032 : 12 : unsigned char number_objects[] = "\x01";
2033 : : static struct simpletlv_member properties[3] = {
2034 : : {CAC_PROPERTIES_APPLET_INFORMATION, 5, {/*.value = applet_information*/},
2035 : : SIMPLETLV_TYPE_LEAF},
2036 : : {CAC_PROPERTIES_NUMBER_OBJECTS, 1, {/*.value = number_objects*/},
2037 : : SIMPLETLV_TYPE_LEAF},
2038 : : {CAC_PROPERTIES_TV_OBJECT, 3, {/*.child = tv_buffer*/},
2039 : : SIMPLETLV_TYPE_COMPOUND},
2040 : : };
2041 : :
2042 : : /* Adjust Object ID based on the AID */
2043 : 12 : object_id[0] = aid[aid_len-2];
2044 : 12 : object_id[1] = aid[aid_len-1];
2045 : :
2046 : : /* Create the private data structure */
2047 : 12 : applet_private = g_new0(VCardAppletPrivate, 1);
2048 : : pt_applet_data = &(applet_private->u.pt_data);
2049 [ - + ]: 12 : if (applet_private == NULL)
2050 : 0 : goto failure;
2051 : :
2052 : : /* Create Object ID list */
2053 : 12 : applet_private->coids = g_malloc(sizeof(struct coid));
2054 : 12 : memcpy(applet_private->coids[0].v, object_id, 2);
2055 : 12 : applet_private->coids_len = 1;
2056 : :
2057 : 12 : pt_applet_data->label = strdup(label);
2058 : :
2059 : : /* Create arbitrary sized buffers */
2060 : 12 : buffer_properties[0] = 0x00; // SimpleTLV
2061 : 12 : buffer_properties[1] = 0x60;
2062 : 12 : buffer_properties[2] = 0x00;
2063 : 12 : buffer_properties[3] = 0x60;
2064 : 12 : buffer_properties[4] = 0x00;
2065 : :
2066 : : /* Inject Object ID */
2067 : 12 : tv_buffer[0].value.value = object_id;
2068 : 12 : tv_buffer[1].value.value = buffer_properties;
2069 : 12 : tv_buffer[2].value.value = buffer_26;
2070 : :
2071 : : /* Inject Applet Version */
2072 : 12 : properties[0].value.value = applet_information;
2073 : 12 : properties[1].value.value = number_objects;
2074 : 12 : properties[2].value.child = tv_buffer;
2075 : :
2076 : : /* Clone the properties */
2077 : 12 : applet_private->properties_len = 3;
2078 : 12 : applet_private->long_properties_len = 3; /*TODO*/
2079 : 12 : applet_private->properties = simpletlv_clone(properties,
2080 : : applet_private->long_properties_len);
2081 [ - + ]: 12 : if (applet_private->properties == NULL)
2082 : 0 : goto failure;
2083 : :
2084 : : return applet_private;
2085 : :
2086 : : failure:
2087 : : if (applet_private != NULL) {
2088 : 0 : cac_delete_passthrough_applet_private(applet_private);
2089 : : }
2090 : : return NULL;
2091 : : }
2092 : :
2093 : : /*
2094 : : * create a new ACA applet
2095 : : */
2096 : : static VCardApplet *
2097 : 6 : cac_new_aca_applet(int cert_count)
2098 : : {
2099 : : VCardAppletPrivate *applet_private;
2100 : : VCardApplet *applet;
2101 : :
2102 : 6 : applet_private = cac_new_aca_applet_private(cert_count);
2103 [ - + ]: 6 : if (applet_private == NULL) {
2104 : 0 : goto failure;
2105 : : }
2106 : 6 : applet = vcard_new_applet(cac_applet_aca_process_apdu, NULL,
2107 : : cac_aca_aid, sizeof(cac_aca_aid));
2108 [ - + ]: 6 : if (applet == NULL) {
2109 : 0 : goto failure;
2110 : : }
2111 : 6 : vcard_set_applet_private(applet, applet_private,
2112 : : cac_delete_aca_applet_private);
2113 : : applet_private = NULL;
2114 : :
2115 : 6 : return applet;
2116 : :
2117 : : failure:
2118 : : if (applet_private != NULL) {
2119 : 0 : cac_delete_aca_applet_private(applet_private);
2120 : : }
2121 : : return NULL;
2122 : : }
2123 : :
2124 : :
2125 : : /*
2126 : : * create a new cac applet which links to a given cert
2127 : : */
2128 : : static VCardApplet *
2129 : 16 : cac_new_pki_applet(int i, const unsigned char *cert,
2130 : : int cert_len, VCardKey *key)
2131 : : {
2132 : : VCardAppletPrivate *applet_private;
2133 : : VCardApplet *applet;
2134 : 16 : unsigned char pki_aid[] = { 0xa0, 0x00, 0x00, 0x00, 0x79, 0x01, 0x00 };
2135 : : int pki_aid_len = sizeof(pki_aid);
2136 : :
2137 : 16 : g_debug("%s: called", __func__);
2138 : :
2139 : 16 : pki_aid[pki_aid_len-1] = i;
2140 : :
2141 : 16 : applet_private = cac_new_pki_applet_private(i, cert, cert_len, key);
2142 [ - + ]: 16 : if (applet_private == NULL) {
2143 : 0 : goto failure;
2144 : : }
2145 : 16 : applet = vcard_new_applet(cac_applet_pki_process_apdu, cac_applet_pki_reset,
2146 : : pki_aid, pki_aid_len);
2147 [ - + ]: 16 : if (applet == NULL) {
2148 : 0 : goto failure;
2149 : : }
2150 : 16 : vcard_set_applet_private(applet, applet_private,
2151 : : cac_delete_pki_applet_private);
2152 : : applet_private = NULL;
2153 : :
2154 : 16 : return applet;
2155 : :
2156 : : failure:
2157 : : if (applet_private != NULL) {
2158 : 0 : cac_delete_pki_applet_private(applet_private);
2159 : : }
2160 : : return NULL;
2161 : : }
2162 : :
2163 : : static VCardApplet *
2164 : 54 : cac_new_empty_applet(const unsigned char *aid, unsigned int aid_len,
2165 : : unsigned char coids[][2], unsigned int coids_len)
2166 : : {
2167 : : VCardAppletPrivate *applet_private;
2168 : : VCardApplet *applet;
2169 : :
2170 : 54 : applet_private = cac_new_empty_applet_private(coids, coids_len);
2171 [ - + ]: 54 : if (applet_private == NULL) {
2172 : 0 : goto failure;
2173 : : }
2174 : :
2175 : 54 : applet = vcard_new_applet(cac_common_process_apdu_read,
2176 : : NULL, aid, aid_len);
2177 [ - + ]: 54 : if (applet == NULL) {
2178 : 0 : goto failure;
2179 : : }
2180 : :
2181 : 54 : vcard_set_applet_private(applet, applet_private,
2182 : : cac_delete_empty_applet_private);
2183 : : applet_private = NULL;
2184 : :
2185 : 54 : return applet;
2186 : :
2187 : : failure:
2188 : : if (applet_private != NULL) {
2189 : 0 : cac_delete_empty_applet_private(applet_private);
2190 : : }
2191 : : return NULL;
2192 : : }
2193 : :
2194 : : static VCardApplet *
2195 : 12 : cac_new_passthrough_applet(VCard *card, const char *label,
2196 : : const unsigned char *aid, unsigned int aid_len)
2197 : : {
2198 : : VCardAppletPrivate *applet_private;
2199 : : VCardApplet *applet;
2200 : :
2201 : 12 : applet_private = cac_new_passthrough_applet_private(card, label,
2202 : : aid, aid_len);
2203 [ - + ]: 12 : if (applet_private == NULL) {
2204 : 0 : goto failure;
2205 : : }
2206 : :
2207 : 12 : applet = vcard_new_applet(cac_passthrough_container_process_apdu,
2208 : : cac_applet_passthrough_reset, aid, aid_len);
2209 [ - + ]: 12 : if (applet == NULL) {
2210 : 0 : goto failure;
2211 : : }
2212 : :
2213 : 12 : vcard_set_applet_private(applet, applet_private,
2214 : : cac_delete_passthrough_applet_private);
2215 : : applet_private = NULL;
2216 : :
2217 : 12 : return applet;
2218 : :
2219 : : failure:
2220 : : if (applet_private != NULL) {
2221 : 0 : cac_delete_empty_applet_private(applet_private);
2222 : : }
2223 : : return NULL;
2224 : : }
2225 : :
2226 : : /*
2227 : : * Get ATR of CAC card since some application might be picky about out
2228 : : * virtual one
2229 : : */
2230 : : static unsigned char cac_atr[] = {
2231 : : /* The older CAC card from official CAC document */
2232 : : 0x3B, 0x7A, 0x18, 0x00, 0x00, 0x73, 0x66, 0x74, 0x65, 0x20, 0x63, 0x64, 0x31, 0x34, 0x34
2233 : : };
2234 : : static int cac_atr_len = sizeof(cac_atr);
2235 : :
2236 : : static void
2237 : 1 : cac_get_atr(G_GNUC_UNUSED VCard *card, unsigned char *atr, int *atr_len)
2238 : : {
2239 : : int len;
2240 [ - + ]: 1 : assert(atr != NULL);
2241 : :
2242 : 1 : len = MIN(cac_atr_len, *atr_len);
2243 : 1 : memcpy(atr, cac_atr, len);
2244 : 1 : *atr_len = len;
2245 : 1 : }
2246 : :
2247 : : /*
2248 : : * Initialize the cac card. This is the only public function in this file. All
2249 : : * the rest are connected through function pointers.
2250 : : */
2251 : : VCardStatus
2252 : 6 : cac_card_init(G_GNUC_UNUSED VReader *reader, VCard *card,
2253 : : unsigned char * const *cert,
2254 : : int cert_len[],
2255 : : VCardKey *key[] /* adopt the keys*/,
2256 : : int cert_count)
2257 : : {
2258 : : int i;
2259 : : VCardApplet *applet;
2260 : 6 : unsigned char coids[][2] = {{0x02, 0xfb}};
2261 : 6 : unsigned char acf_coids[][2] = {
2262 : : {0x30, 0x00},
2263 : : {0x60, 0x10},
2264 : : {0x60, 0x30},
2265 : : {0x90, 0x00},
2266 : : };
2267 : :
2268 : 6 : g_debug("%s: called", __func__);
2269 : :
2270 : : /* CAC Cards are VM Cards */
2271 : 6 : vcard_set_type(card, VCARD_VM);
2272 : :
2273 [ + - ]: 6 : if (cert_count > 10) {
2274 : 0 : g_debug("Too many PKI objects");
2275 : 0 : goto failure;
2276 : : }
2277 : :
2278 : : /* create one PKI applet for each cert */
2279 [ + + ]: 22 : for (i = 0; i < cert_count; i++) {
2280 : 16 : applet = cac_new_pki_applet(i, cert[i], cert_len[i], key[i]);
2281 [ - + ]: 16 : if (applet == NULL) {
2282 : 0 : goto failure;
2283 : : }
2284 : 16 : vcard_add_applet(card, applet);
2285 : : }
2286 : :
2287 : : /* create a ACA applet, to list access rules */
2288 : 6 : applet = cac_new_aca_applet(cert_count);
2289 [ - + ]: 6 : if (applet == NULL) {
2290 : 0 : goto failure;
2291 : : }
2292 : 6 : vcard_add_applet(card, applet);
2293 : :
2294 : : /* create a CCC container, which is need for CAC recognition,
2295 : : * which should be default
2296 : : */
2297 : 6 : applet = cac_new_ccc_applet(cert_count);
2298 [ - + ]: 6 : if (applet == NULL) {
2299 : 0 : goto failure;
2300 : : }
2301 : 6 : vcard_add_applet(card, applet);
2302 : :
2303 : : /* Three more empty applets without buffer */
2304 : : /* 02 F0 */
2305 : 6 : applet = cac_new_empty_applet(cac_02f0_aid, sizeof(cac_02f0_aid), NULL, 0);
2306 [ - + ]: 6 : if (applet == NULL) {
2307 : 0 : goto failure;
2308 : : }
2309 : 6 : vcard_add_applet(card, applet);
2310 : :
2311 : : /* 02 F1 */
2312 : 6 : applet = cac_new_empty_applet(cac_02f1_aid, sizeof(cac_02f1_aid), NULL, 0);
2313 [ - + ]: 6 : if (applet == NULL) {
2314 : 0 : goto failure;
2315 : : }
2316 : 6 : vcard_add_applet(card, applet);
2317 : :
2318 : : /* 02 F2 */
2319 : 6 : applet = cac_new_empty_applet(cac_02f2_aid, sizeof(cac_02f2_aid), NULL, 0);
2320 [ - + ]: 6 : if (applet == NULL) {
2321 : 0 : goto failure;
2322 : : }
2323 : 6 : vcard_add_applet(card, applet);
2324 : :
2325 : : /* Empty generic applet (0x02FB) */
2326 : 6 : applet = cac_new_empty_applet(cac_02fb_aid, sizeof(cac_02fb_aid),
2327 : : coids, 1);
2328 [ - + ]: 6 : if (applet == NULL) {
2329 : 0 : goto failure;
2330 : : }
2331 : 6 : vcard_add_applet(card, applet);
2332 : :
2333 : : /* PKI Certificate passthrough applet (0x02FE)
2334 : : * TODO: Find a way how to expose generic non-SimpleTLV buffers
2335 : : * from OpenSC in sane manner
2336 : : */
2337 : : /*applet = cac_new_passthrough_applet(card, "PKI Certificate",
2338 : : cac_pki_certificate_aid, sizeof(cac_pki_certificate_aid));*/
2339 : 6 : coids[0][1] = 0xfe;
2340 : 6 : applet = cac_new_empty_applet(cac_pki_certificate_aid,
2341 : : sizeof(cac_pki_certificate_aid), coids, 1);
2342 [ - + ]: 6 : if (applet == NULL) {
2343 : 0 : goto failure;
2344 : : }
2345 : 6 : vcard_add_applet(card, applet);
2346 : :
2347 : : /* PKI Credential passthrough applet (0x02FD)
2348 : : * TODO: Find a way how to expose generic non-SimpleTLV buffers
2349 : : * from OpenSC in sane manner
2350 : : */
2351 : : /*applet = cac_new_passthrough_applet(card, "PKI Credential",
2352 : : cac_pki_credential_aid, sizeof(cac_pki_credential_aid));*/
2353 : 6 : coids[0][1] = 0xfd;
2354 : 6 : applet = cac_new_empty_applet(cac_pki_credential_aid,
2355 : : sizeof(cac_pki_credential_aid), coids, 1);
2356 [ - + ]: 6 : if (applet == NULL) {
2357 : 0 : goto failure;
2358 : : }
2359 : 6 : vcard_add_applet(card, applet);
2360 : :
2361 : : /* Person Instance passthrough applet (0x0200) */
2362 : 6 : applet = cac_new_passthrough_applet(card, "Person Instance",
2363 : : cac_person_instance_aid, sizeof(cac_person_instance_aid));
2364 [ - + ]: 6 : if (applet == NULL) {
2365 : 0 : goto failure;
2366 : : }
2367 : 6 : vcard_add_applet(card, applet);
2368 : :
2369 : : /* Personnel passthrough applet (0x0200) */
2370 : 6 : applet = cac_new_passthrough_applet(card, "Personnel",
2371 : : cac_personnel_aid, sizeof(cac_personnel_aid));
2372 [ - + ]: 6 : if (applet == NULL) {
2373 : 0 : goto failure;
2374 : : }
2375 : 6 : vcard_add_applet(card, applet);
2376 : :
2377 : : /* Empty generic applet (0x1201) */
2378 : 6 : coids[0][0] = 0x12;
2379 : 6 : coids[0][1] = 0x01;
2380 : 6 : applet = cac_new_empty_applet(cac_1201_aid, sizeof(cac_1201_aid), coids, 1);
2381 [ - + ]: 6 : if (applet == NULL) {
2382 : 0 : goto failure;
2383 : : }
2384 : 6 : vcard_add_applet(card, applet);
2385 : :
2386 : : /* Empty generic applet (0x1202) */
2387 : 6 : coids[0][1] = 0x02;
2388 : 6 : applet = cac_new_empty_applet(cac_1202_aid, sizeof(cac_1202_aid), coids, 1);
2389 [ - + ]: 6 : if (applet == NULL) {
2390 : 0 : goto failure;
2391 : : }
2392 : 6 : vcard_add_applet(card, applet);
2393 : :
2394 : : /* Access Control File */
2395 : 6 : applet = cac_new_empty_applet(cac_access_control_aid,
2396 : : sizeof(cac_access_control_aid), acf_coids, 4);
2397 [ - + ]: 6 : if (applet == NULL) {
2398 : 0 : goto failure;
2399 : : }
2400 : 6 : vcard_add_applet(card, applet);
2401 : :
2402 : : /* GP applet is created from vcard_emul_type() */
2403 : :
2404 : : /* Modify ATR to match existing cards */
2405 : 6 : vcard_set_atr_func(card, cac_get_atr);
2406 : :
2407 : 6 : return VCARD_DONE;
2408 : :
2409 : : failure:
2410 : : return VCARD_FAIL;
2411 : : }
2412 : :
2413 : : /* vim: set ts=4 sw=4 tw=0 noet expandtab: */
|