LCOV - code coverage report
Current view: top level - src - cac.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 570 643 88.6 %
Date: 2023-06-12 11:14:12 Functions: 26 26 100.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 164 235 69.8 %

           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: */

Generated by: LCOV version 1.14