LCOV - code coverage report
Current view: top level - src - vcard.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 122 134 91.0 %
Date: 2023-06-12 11:14:12 Functions: 25 26 96.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 42 60 70.0 %

           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 1.14