LCOV - code coverage report
Current view: top level - src - vcard.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 91.0 % 134 122
Test Date: 2025-12-04 16:15:14 Functions: 96.2 % 26 25
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 70.7 % 58 41

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :  * implement the Java card standard.
       3                 :             :  *
       4                 :             :  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
       5                 :             :  * See the COPYING file in the top-level directory.
       6                 :             :  */
       7                 :             : 
       8                 :             : #include <glib.h>
       9                 :             : 
      10                 :             : #include <string.h>
      11                 :             : 
      12                 :             : #include "vcard.h"
      13                 :             : #include "vcard_emul.h"
      14                 :             : #include "card_7816t.h"
      15                 :             : #include "common.h"
      16                 :             : 
      17                 :             : struct VCardAppletStruct {
      18                 :             :     VCardApplet   *next;
      19                 :             :     VCardProcessAPDU process_apdu;
      20                 :             :     VCardResetApplet reset_applet;
      21                 :             :     unsigned char *aid;
      22                 :             :     int aid_len;
      23                 :             :     void *applet_private;
      24                 :             :     VCardAppletPrivateFree applet_private_free;
      25                 :             : };
      26                 :             : 
      27                 :             : struct VCardStruct {
      28                 :             :     int reference_count;
      29                 :             :     VCardApplet *applet_list;
      30                 :             :     VCardApplet *current_applet[MAX_CHANNEL];
      31                 :             :     VCardBufferResponse *vcard_buffer_response;
      32                 :             :     VCardType type;
      33                 :             :     VCardEmul *vcard_private;
      34                 :             :     VCardEmulFree vcard_private_free;
      35                 :             :     VCardGetAtr vcard_get_atr;
      36                 :             :     unsigned int compat;
      37                 :             :     unsigned char serial[32]; /* SHA256 of the first certificate */
      38                 :             :     int serial_len;
      39                 :             : };
      40                 :             : 
      41                 :             : VCardBufferResponse *
      42                 :         227 : vcard_buffer_response_new(const unsigned char *buffer, int size)
      43                 :             : {
      44                 :             :     VCardBufferResponse *new_buffer;
      45                 :             : 
      46                 :         227 :     new_buffer = g_new(VCardBufferResponse, 1);
      47                 :         227 :     new_buffer->buffer = (unsigned char *)g_memdup2(buffer, size);
      48                 :         227 :     new_buffer->buffer_len = size;
      49                 :         227 :     new_buffer->current = new_buffer->buffer;
      50                 :         227 :     new_buffer->len = size;
      51                 :         227 :     return new_buffer;
      52                 :             : }
      53                 :             : 
      54                 :             : void
      55                 :         231 : vcard_buffer_response_delete(VCardBufferResponse *buffer_response)
      56                 :             : {
      57         [ +  + ]:         231 :     if (buffer_response == NULL) {
      58                 :             :         return;
      59                 :             :     }
      60                 :         227 :     g_free(buffer_response->buffer);
      61                 :         227 :     g_free(buffer_response);
      62                 :             : }
      63                 :             : 
      64                 :             : 
      65                 :             : /*
      66                 :             :  * clean up state after a reset
      67                 :             :  */
      68                 :             : void
      69                 :          16 : vcard_reset(VCard *card, VCardPower power)
      70                 :             : {
      71                 :             :     int i;
      72                 :             :     VCardApplet *applet = NULL;
      73                 :             : 
      74         [ -  + ]:          16 :     if (card->type ==  VCARD_DIRECT) {
      75                 :             :         /* select the last applet */
      76                 :             :         VCardApplet *current_applet = NULL;
      77         [ #  # ]:           0 :         for (current_applet = card->applet_list; current_applet;
      78                 :           0 :                                        current_applet = current_applet->next) {
      79                 :             :             applet = current_applet;
      80                 :             :         }
      81                 :             :     }
      82         [ +  + ]:          80 :     for (i = 0; i < MAX_CHANNEL; i++) {
      83                 :          64 :         card->current_applet[i] = applet;
      84                 :             :     }
      85         [ -  + ]:          16 :     if (card->vcard_buffer_response) {
      86                 :           0 :         vcard_buffer_response_delete(card->vcard_buffer_response);
      87                 :           0 :         card->vcard_buffer_response = NULL;
      88                 :             :     }
      89                 :          16 :     vcard_emul_reset(card, power);
      90         [ -  + ]:          16 :     if (applet) {
      91                 :           0 :         applet->reset_applet(card, 0);
      92                 :             :     }
      93                 :          16 : }
      94                 :             : 
      95                 :             : /* applet utilities */
      96                 :             : 
      97                 :             : /*
      98                 :             :  * applet utilities
      99                 :             :  */
     100                 :             : /* constructor */
     101                 :             : VCardApplet *
     102                 :         106 : vcard_new_applet(VCardProcessAPDU applet_process_function,
     103                 :             :                  VCardResetApplet applet_reset_function,
     104                 :             :                  const unsigned char *aid, int aid_len)
     105                 :             : {
     106                 :             :     VCardApplet *applet;
     107                 :             : 
     108                 :         106 :     applet = g_new0(VCardApplet, 1);
     109                 :         106 :     applet->process_apdu = applet_process_function;
     110                 :         106 :     applet->reset_applet = applet_reset_function;
     111                 :             : 
     112                 :         106 :     applet->aid = g_memdup2(aid, aid_len);
     113                 :         106 :     applet->aid_len = aid_len;
     114                 :         106 :     return applet;
     115                 :             : }
     116                 :             : 
     117                 :             : /* destructor */
     118                 :             : void
     119                 :          88 : vcard_delete_applet(VCardApplet *applet)
     120                 :             : {
     121         [ +  - ]:          88 :     if (applet == NULL) {
     122                 :             :         return;
     123                 :             :     }
     124         [ +  + ]:          88 :     if (applet->applet_private_free) {
     125                 :          78 :         applet->applet_private_free(applet->applet_private);
     126                 :             :     }
     127                 :          88 :     g_free(applet->aid);
     128                 :          88 :     g_free(applet);
     129                 :             : }
     130                 :             : 
     131                 :             : /* accessor */
     132                 :             : void
     133                 :          94 : vcard_set_applet_private(VCardApplet *applet, VCardAppletPrivate *private,
     134                 :             :                          VCardAppletPrivateFree private_free)
     135                 :             : {
     136         [ -  + ]:          94 :     if (applet->applet_private_free) {
     137                 :           0 :         applet->applet_private_free(applet->applet_private);
     138                 :             :     }
     139                 :          94 :     applet->applet_private = private;
     140                 :          94 :     applet->applet_private_free = private_free;
     141                 :          94 : }
     142                 :             : 
     143                 :             : VCard *
     144                 :           6 : vcard_new(VCardEmul *private, VCardEmulFree private_free)
     145                 :             : {
     146                 :             :     VCard *new_card;
     147                 :             : 
     148                 :           6 :     g_debug("%s: called", __func__);
     149                 :             : 
     150                 :           6 :     new_card = g_new0(VCard, 1);
     151                 :           6 :     new_card->type = VCARD_VM;
     152                 :           6 :     new_card->vcard_private = private;
     153                 :           6 :     new_card->vcard_private_free = private_free;
     154                 :           6 :     new_card->reference_count = 1;
     155                 :           6 :     return new_card;
     156                 :             : }
     157                 :             : 
     158                 :             : VCard *
     159                 :         856 : vcard_reference(VCard *vcard)
     160                 :             : {
     161         [ +  + ]:         856 :     if (vcard == NULL) {
     162                 :             :         return NULL;
     163                 :             :     }
     164                 :         824 :     vcard->reference_count++;
     165                 :         824 :     return vcard;
     166                 :             : }
     167                 :             : 
     168                 :             : void
     169                 :         851 : vcard_free(VCard *vcard)
     170                 :             : {
     171                 :             :     VCardApplet *current_applet;
     172                 :             :     VCardApplet *next_applet;
     173                 :             : 
     174         [ +  + ]:         851 :     if (vcard == NULL) {
     175                 :             :         return;
     176                 :             :     }
     177                 :         827 :     vcard->reference_count--;
     178         [ +  + ]:         827 :     if (vcard->reference_count != 0) {
     179                 :             :         return;
     180                 :             :     }
     181         [ +  - ]:           5 :     if (vcard->vcard_private_free) {
     182                 :           5 :         (*vcard->vcard_private_free)(vcard->vcard_private);
     183                 :             :     }
     184         [ +  + ]:          93 :     for (current_applet = vcard->applet_list; current_applet;
     185                 :             :                                         current_applet = next_applet) {
     186                 :          88 :         next_applet = current_applet->next;
     187                 :          88 :         vcard_delete_applet(current_applet);
     188                 :             :     }
     189                 :           5 :     vcard_buffer_response_delete(vcard->vcard_buffer_response);
     190                 :           5 :     g_free(vcard);
     191                 :             : }
     192                 :             : 
     193                 :             : void
     194                 :           2 : vcard_get_atr(VCard *vcard, unsigned char *atr, int *atr_len)
     195                 :             : {
     196         [ +  + ]:           2 :     if (vcard->vcard_get_atr) {
     197                 :           1 :         (*vcard->vcard_get_atr)(vcard, atr, atr_len);
     198                 :           1 :         return;
     199                 :             :     }
     200                 :           1 :     vcard_emul_get_atr(vcard, atr, atr_len);
     201                 :             : }
     202                 :             : 
     203                 :             : void
     204                 :           7 : vcard_set_atr_func(VCard *card, VCardGetAtr get_atr)
     205                 :             : {
     206                 :           7 :     card->vcard_get_atr = get_atr;
     207                 :           7 : }
     208                 :             : 
     209                 :             : 
     210                 :             : VCardStatus
     211                 :         106 : vcard_add_applet(VCard *card, VCardApplet *applet)
     212                 :             : {
     213                 :         106 :     g_debug("%s: called", __func__);
     214                 :             : 
     215                 :         106 :     applet->next = card->applet_list;
     216                 :         106 :     card->applet_list = applet;
     217                 :             :     /* if our card-type is direct, always call the applet */
     218         [ -  + ]:         106 :     if (card->type ==  VCARD_DIRECT) {
     219                 :             :         int i;
     220                 :             : 
     221         [ #  # ]:           0 :         for (i = 0; i < MAX_CHANNEL; i++) {
     222                 :           0 :             card->current_applet[i] = applet;
     223                 :             :         }
     224                 :             :     }
     225                 :         106 :     return VCARD_DONE;
     226                 :             : }
     227                 :             : 
     228                 :             : /*
     229                 :             :  * manage applets
     230                 :             :  */
     231                 :             : VCardApplet *
     232                 :         193 : vcard_find_applet(VCard *card, const unsigned char *aid, int aid_len)
     233                 :             : {
     234                 :             :     VCardApplet *current_applet;
     235                 :             : 
     236         [ +  + ]:        1398 :     for (current_applet = card->applet_list; current_applet;
     237                 :        1205 :                                         current_applet = current_applet->next) {
     238         [ +  + ]:        1397 :         if (current_applet->aid_len != aid_len) {
     239                 :         190 :             continue;
     240                 :             :         }
     241         [ +  + ]:        1207 :         if (memcmp(current_applet->aid, aid, aid_len) == 0) {
     242                 :             :             break;
     243                 :             :         }
     244                 :             :     }
     245                 :         193 :     return current_applet;
     246                 :             : }
     247                 :             : 
     248                 :             : unsigned char *
     249                 :           0 : vcard_applet_get_aid(VCardApplet *applet, int *aid_len)
     250                 :             : {
     251         [ #  # ]:           0 :     if (applet == NULL) {
     252                 :             :         return NULL;
     253                 :             :     }
     254                 :           0 :     *aid_len = applet->aid_len;
     255                 :           0 :     return applet->aid;
     256                 :             : }
     257                 :             : 
     258                 :             : 
     259                 :             : void
     260                 :          97 : vcard_select_applet(VCard *card, int channel, VCardApplet *applet)
     261                 :             : {
     262         [ +  - ]:          97 :     g_assert(channel >= 0 && channel < MAX_CHANNEL);
     263                 :             : 
     264                 :          97 :     card->current_applet[channel] = applet;
     265                 :             :     /* reset the applet */
     266   [ +  +  +  + ]:          97 :     if (applet && applet->reset_applet) {
     267                 :          36 :         applet->reset_applet(card, channel);
     268                 :             :     }
     269                 :          97 : }
     270                 :             : 
     271                 :             : VCardAppletPrivate *
     272                 :        1441 : vcard_get_current_applet_private(VCard *card, int channel)
     273                 :             : {
     274                 :        1441 :     VCardApplet *applet = card->current_applet[channel];
     275                 :             : 
     276         [ +  - ]:        1441 :     if (applet == NULL) {
     277                 :             :         return NULL;
     278                 :             :     }
     279                 :        1441 :     return applet->applet_private;
     280                 :             : }
     281                 :             : 
     282                 :             : VCardStatus
     283                 :         750 : vcard_process_applet_apdu(VCard *card, VCardAPDU *apdu,
     284                 :             :                           VCardResponse **response)
     285                 :             : {
     286         [ +  + ]:         750 :     if (card->current_applet[apdu->a_channel]) {
     287                 :         733 :         return card->current_applet[apdu->a_channel]->process_apdu(
     288                 :             :                                                         card, apdu, response);
     289                 :             :     }
     290                 :             :     return VCARD_NEXT;
     291                 :             : }
     292                 :             : 
     293                 :             : /*
     294                 :             :  * Accessor functions
     295                 :             :  */
     296                 :             : /* accessor functions for the response buffer */
     297                 :             : VCardBufferResponse *
     298                 :        1030 : vcard_get_buffer_response(VCard *card)
     299                 :             : {
     300                 :        1030 :     return card->vcard_buffer_response;
     301                 :             : }
     302                 :             : 
     303                 :             : void
     304                 :         453 : vcard_set_buffer_response(VCard *card, VCardBufferResponse *buffer)
     305                 :             : {
     306                 :         453 :     card->vcard_buffer_response = buffer;
     307                 :         453 : }
     308                 :             : 
     309                 :             : 
     310                 :             : /* accessor functions for the type */
     311                 :             : VCardType
     312                 :         204 : vcard_get_type(VCard *card)
     313                 :             : {
     314                 :         204 :     return card->type;
     315                 :             : }
     316                 :             : 
     317                 :             : void
     318                 :           6 : vcard_set_type(VCard *card, VCardType type)
     319                 :             : {
     320                 :           6 :     card->type = type;
     321                 :           6 : }
     322                 :             : 
     323                 :             : /* accessor for private data */
     324                 :             : VCardEmul *
     325                 :         124 : vcard_get_private(VCard *vcard)
     326                 :             : {
     327                 :         124 :     return vcard->vcard_private;
     328                 :             : }
     329                 :             : 
     330                 :             : /* Get remaining login count for the current card */
     331                 :             : int
     332                 :           4 : vcard_get_login_count(VCard *card)
     333                 :             : {
     334                 :           4 :     int rv = vcard_emul_get_login_count(card);
     335                 :             : 
     336                 :             :     /* Windows drivers are not very happy with the answer we can give here
     337                 :             :      * so lets assume the card still have all the attempts unlocked here */
     338   [ +  -  +  + ]:           4 :     if (rv == -1 && card->compat & VCARD_COMPAT_WINDOWS) {
     339                 :           2 :         return 3;
     340                 :             :     }
     341                 :             :     return rv;
     342                 :             : }
     343                 :             : 
     344                 :             : /* Set compat bits for the given cards. See VCARD_COMPAT_* options */
     345                 :             : void
     346                 :           3 : vcard_set_compat(VCard *card, unsigned int set)
     347                 :             : {
     348                 :           3 :     card->compat |= set;
     349                 :           3 : }
     350                 :             : 
     351                 :             : /* Set card serial number */
     352                 :             : void
     353                 :           6 : vcard_set_serial(VCard *card, unsigned char *serial, size_t len)
     354                 :             : {
     355                 :           6 :     len = MIN(sizeof(card->serial), len);
     356                 :           6 :     memcpy(card->serial, serial, len);
     357                 :           6 :     card->serial_len = len;
     358                 :           6 : }
     359                 :             : 
     360                 :             : unsigned char *
     361                 :           3 : vcard_get_serial(VCard *card, int *len)
     362                 :             : {
     363         [ +  - ]:           3 :     if (len != NULL)
     364                 :           3 :         *len = card->serial_len;
     365                 :           3 :     return card->serial;
     366                 :             : }
        

Generated by: LCOV version 2.0-1