list_init:
  235|    295|int list_init(list_t *simclist_restrict l) {
  236|    295|    if (l == NULL) {
  ------------------
  |  Branch (236:9): [True: 0, False: 295]
  ------------------
  237|      0|        return -1;
  238|      0|    }
  239|       |
  240|    295|    memset(l, 0, sizeof *l);
  241|       |
  242|    295|    seed_random();
  243|       |
  244|    295|    l->numels = 0;
  245|       |
  246|       |    /* head/tail sentinels and mid pointer */
  247|    295|    l->head_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
  248|    295|    l->tail_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
  249|    295|    if (l->tail_sentinel == NULL || l->head_sentinel == NULL) {
  ------------------
  |  Branch (249:9): [True: 0, False: 295]
  |  Branch (249:37): [True: 0, False: 295]
  ------------------
  250|      0|        return -1;
  251|      0|    }
  252|    295|    l->head_sentinel->next = l->tail_sentinel;
  253|    295|    l->tail_sentinel->prev = l->head_sentinel;
  254|    295|    l->head_sentinel->prev = l->tail_sentinel->next = l->mid = NULL;
  255|    295|    l->head_sentinel->data = l->tail_sentinel->data = NULL;
  256|       |
  257|       |    /* iteration attributes */
  258|    295|    l->iter_active = 0;
  259|    295|    l->iter_pos = 0;
  260|    295|    l->iter_curentry = NULL;
  261|       |
  262|       |    /* free-list attributes */
  263|    295|    l->spareelsnum = 0;
  264|    295|    l->spareels = (struct list_entry_s **)malloc(SIMCLIST_MAX_SPARE_ELEMS * sizeof(struct list_entry_s *));
  ------------------
  |  |  115|    295|#define SIMCLIST_MAX_SPARE_ELEMS        5
  ------------------
  265|    295|    if (l->spareels == NULL) {
  ------------------
  |  Branch (265:9): [True: 0, False: 295]
  ------------------
  266|      0|        return -1;
  267|      0|    }
  268|       |
  269|       |#ifdef SIMCLIST_WITH_THREADS
  270|       |    l->threadcount = 0;
  271|       |#endif
  272|       |
  273|    295|    if (0 != list_attributes_setdefaults(l)) {
  ------------------
  |  Branch (273:9): [True: 0, False: 295]
  ------------------
  274|      0|        return -1;
  275|      0|    }
  276|       |
  277|    295|    assert(list_repOk(l));
  278|    295|    assert(list_attrOk(l));
  279|       |
  280|    295|    return 0;
  281|    295|}
list_destroy:
  283|    295|void list_destroy(list_t *simclist_restrict l) {
  284|    295|    unsigned int i;
  285|       |
  286|    295|    list_clear(l);
  287|    346|    for (i = 0; i < l->spareelsnum; i++) {
  ------------------
  |  Branch (287:17): [True: 51, False: 295]
  ------------------
  288|     51|        free(l->spareels[i]);
  289|     51|    }
  290|    295|    free(l->spareels);
  291|    295|    free(l->head_sentinel);
  292|    295|    free(l->tail_sentinel);
  293|    295|}
list_attributes_seeker:
  325|    295|int list_attributes_seeker(list_t *simclist_restrict l, element_seeker seeker_fun) {
  326|    295|    if (l == NULL) return -1;
  ------------------
  |  Branch (326:9): [True: 0, False: 295]
  ------------------
  327|       |
  328|    295|    l->attrs.seeker = seeker_fun;
  329|    295|    assert(list_attrOk(l));
  330|       |
  331|    295|    return 0;
  332|    295|}
list_append:
  369|     51|int list_append(list_t *simclist_restrict l, const void *data) {
  370|     51|    return list_insert_at(l, data, l->numels);
  371|     51|}
list_get_at:
  381|    102|void *list_get_at(const list_t *simclist_restrict l, unsigned int pos) {
  382|    102|    struct list_entry_s *tmp;
  383|       |
  384|    102|    tmp = list_findpos(l, pos);
  385|       |
  386|    102|    return (tmp != NULL ? tmp->data : NULL);
  ------------------
  |  Branch (386:13): [True: 102, False: 0]
  ------------------
  387|    102|}
list_insert_at:
  465|     51|int list_insert_at(list_t *simclist_restrict l, const void *data, unsigned int pos) {
  466|     51|    struct list_entry_s *lent, *succ, *prec;
  467|       |
  468|     51|    if (l->iter_active || pos > l->numels) return -1;
  ------------------
  |  Branch (468:9): [True: 0, False: 51]
  |  Branch (468:27): [True: 0, False: 51]
  ------------------
  469|       |
  470|       |    /* this code optimizes malloc() with a free-list */
  471|     51|    if (l->spareelsnum > 0) {
  ------------------
  |  Branch (471:9): [True: 0, False: 51]
  ------------------
  472|      0|        lent = l->spareels[l->spareelsnum-1];
  473|      0|        l->spareelsnum--;
  474|     51|    } else {
  475|     51|        lent = (struct list_entry_s *)malloc(sizeof(struct list_entry_s));
  476|     51|        if (lent == NULL) {
  ------------------
  |  Branch (476:13): [True: 0, False: 51]
  ------------------
  477|      0|            return -1;
  478|      0|        }
  479|     51|    }
  480|       |
  481|     51|    if (l->attrs.copy_data) {
  ------------------
  |  Branch (481:9): [True: 0, False: 51]
  ------------------
  482|       |        /* make room for user' data (has to be copied) */
  483|      0|        size_t datalen = l->attrs.meter(data);
  484|      0|        lent->data = (struct list_entry_s *)malloc(datalen);
  485|      0|        if (lent->data == NULL) {
  ------------------
  |  Branch (485:13): [True: 0, False: 0]
  ------------------
  486|      0|            if (!(l->spareelsnum > 0)) {
  ------------------
  |  Branch (486:17): [True: 0, False: 0]
  ------------------
  487|      0|                free(lent);
  488|      0|            }
  489|      0|            return -1;
  490|      0|        }
  491|      0|        memcpy(lent->data, data, datalen);
  492|     51|    } else {
  493|     51|        lent->data = (void*)data;
  494|     51|    }
  495|       |
  496|       |    /* actually append element */
  497|     51|    prec = list_findpos(l, pos-1);
  498|     51|    if (prec == NULL) {
  ------------------
  |  Branch (498:9): [True: 0, False: 51]
  ------------------
  499|      0|        if (l->attrs.copy_data) {
  ------------------
  |  Branch (499:13): [True: 0, False: 0]
  ------------------
  500|      0|            free(lent->data);
  501|      0|        }
  502|      0|        if (!(l->spareelsnum > 0)) {
  ------------------
  |  Branch (502:13): [True: 0, False: 0]
  ------------------
  503|      0|            free(lent);
  504|      0|        }
  505|      0|        return -1;
  506|      0|    }
  507|     51|    succ = prec->next;
  508|       |
  509|     51|    prec->next = lent;
  510|     51|    lent->prev = prec;
  511|     51|    lent->next = succ;
  512|     51|    succ->prev = lent;
  513|       |
  514|     51|    l->numels++;
  515|       |
  516|       |    /* fix mid pointer */
  517|     51|    if (l->numels == 1) { /* first element, set pointer */
  ------------------
  |  Branch (517:9): [True: 51, False: 0]
  ------------------
  518|     51|        l->mid = lent;
  519|     51|    } else if (l->numels % 2) {    /* now odd */
  ------------------
  |  Branch (519:16): [True: 0, False: 0]
  ------------------
  520|      0|        if (pos >= (l->numels-1)/2) l->mid = l->mid->next;
  ------------------
  |  Branch (520:13): [True: 0, False: 0]
  ------------------
  521|      0|    } else {                /* now even */
  522|      0|        if (pos <= (l->numels-1)/2) l->mid = l->mid->prev;
  ------------------
  |  Branch (522:13): [True: 0, False: 0]
  ------------------
  523|      0|    }
  524|       |
  525|     51|    assert(list_repOk(l));
  526|       |
  527|     51|    return 1;
  528|     51|}
list_delete:
  530|     51|int list_delete(list_t *simclist_restrict l, const void *data) {
  531|     51|	int pos, r;
  532|       |
  533|     51|	pos = list_locate(l, data);
  534|     51|	if (pos < 0)
  ------------------
  |  Branch (534:6): [True: 0, False: 51]
  ------------------
  535|      0|		return -1;
  536|       |
  537|     51|	r = list_delete_at(l, pos);
  538|     51|	if (r < 0)
  ------------------
  |  Branch (538:6): [True: 0, False: 51]
  ------------------
  539|      0|		return -1;
  540|       |
  541|     51|    assert(list_repOk(l));
  542|       |
  543|     51|	return 0;
  544|     51|}
list_delete_at:
  546|     51|int list_delete_at(list_t *simclist_restrict l, unsigned int pos) {
  547|     51|    struct list_entry_s *delendo;
  548|       |
  549|       |
  550|     51|    if (l->iter_active || pos >= l->numels) return -1;
  ------------------
  |  Branch (550:9): [True: 0, False: 51]
  |  Branch (550:27): [True: 0, False: 51]
  ------------------
  551|       |
  552|     51|    delendo = list_findpos(l, pos);
  553|       |
  554|     51|    list_drop_elem(l, delendo, pos);
  555|       |
  556|     51|    l->numels--;
  557|       |
  558|       |
  559|     51|    assert(list_repOk(l));
  560|       |
  561|     51|    return  0;
  562|     51|}
list_clear:
  629|    295|int list_clear(list_t *simclist_restrict l) {
  630|    295|    struct list_entry_s *s;
  631|       |
  632|    295|    if (l->iter_active) return -1;
  ------------------
  |  Branch (632:9): [True: 0, False: 295]
  ------------------
  633|       |
  634|    295|    if (l->head_sentinel && l->tail_sentinel) {
  ------------------
  |  Branch (634:9): [True: 295, False: 0]
  |  Branch (634:29): [True: 295, False: 0]
  ------------------
  635|    295|        if (l->attrs.copy_data) {        /* also free user data */
  ------------------
  |  Branch (635:13): [True: 0, False: 295]
  ------------------
  636|       |            /* spare a loop conditional with two loops: spareing elems and freeing elems */
  637|      0|            for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) {
  ------------------
  |  |  115|      0|#define SIMCLIST_MAX_SPARE_ELEMS        5
  ------------------
  |  Branch (637:46): [True: 0, False: 0]
  |  Branch (637:91): [True: 0, False: 0]
  ------------------
  638|       |                /* move elements as spares as long as there is room */
  639|      0|                if (s->data != NULL) free(s->data);
  ------------------
  |  Branch (639:21): [True: 0, False: 0]
  ------------------
  640|      0|                l->spareels[l->spareelsnum++] = s;
  641|      0|            }
  642|      0|            while (s != l->tail_sentinel) {
  ------------------
  |  Branch (642:20): [True: 0, False: 0]
  ------------------
  643|       |                /* free the remaining elems */
  644|      0|                if (s->data != NULL) free(s->data);
  ------------------
  |  Branch (644:21): [True: 0, False: 0]
  ------------------
  645|      0|                s = s->next;
  646|      0|                free(s->prev);
  647|      0|            }
  648|      0|            l->head_sentinel->next = l->tail_sentinel;
  649|      0|            l->tail_sentinel->prev = l->head_sentinel;
  650|    295|        } else { /* only free element containers */
  651|       |            /* spare a loop conditional with two loops: spareing elems and freeing elems */
  652|    295|            for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) {
  ------------------
  |  |  115|    590|#define SIMCLIST_MAX_SPARE_ELEMS        5
  ------------------
  |  Branch (652:46): [True: 295, False: 0]
  |  Branch (652:91): [True: 0, False: 295]
  ------------------
  653|       |                /* move elements as spares as long as there is room */
  654|      0|                l->spareels[l->spareelsnum++] = s;
  655|      0|            }
  656|    295|            while (s != l->tail_sentinel) {
  ------------------
  |  Branch (656:20): [True: 0, False: 295]
  ------------------
  657|       |                /* free the remaining elems */
  658|      0|                s = s->next;
  659|      0|                free(s->prev);
  660|      0|            }
  661|    295|            l->head_sentinel->next = l->tail_sentinel;
  662|    295|            l->tail_sentinel->prev = l->head_sentinel;
  663|    295|        }
  664|    295|    }
  665|    295|    l->numels = 0;
  666|    295|    l->mid = NULL;
  667|       |
  668|    295|    assert(list_repOk(l));
  669|       |
  670|    295|    return 0;
  671|    295|}
list_size:
  673|    397|unsigned int list_size(const list_t *simclist_restrict l) {
  674|    397|    return l->numels;
  675|    397|}
list_locate:
  681|     51|int list_locate(const list_t *simclist_restrict l, const void *data) {
  682|     51|    struct list_entry_s *el;
  683|     51|    int pos = 0;
  684|       |
  685|     51|    if (l->head_sentinel == NULL || l->tail_sentinel == NULL) return -1;
  ------------------
  |  Branch (685:9): [True: 0, False: 51]
  |  Branch (685:37): [True: 0, False: 51]
  ------------------
  686|       |
  687|     51|    if (l->attrs.comparator != NULL) {
  ------------------
  |  Branch (687:9): [True: 0, False: 51]
  ------------------
  688|       |        /* use comparator */
  689|      0|        for (el = l->head_sentinel->next; el != l->tail_sentinel; el = el->next, pos++) {
  ------------------
  |  Branch (689:43): [True: 0, False: 0]
  ------------------
  690|      0|            if (l->attrs.comparator(data, el->data) == 0) break;
  ------------------
  |  Branch (690:17): [True: 0, False: 0]
  ------------------
  691|      0|        }
  692|     51|    } else {
  693|       |        /* compare references */
  694|     51|        for (el = l->head_sentinel->next; el != l->tail_sentinel; el = el->next, pos++) {
  ------------------
  |  Branch (694:43): [True: 51, False: 0]
  ------------------
  695|     51|            if (el->data == data) break;
  ------------------
  |  Branch (695:17): [True: 51, False: 0]
  ------------------
  696|     51|        }
  697|     51|    }
  698|     51|    if (el == l->tail_sentinel) return -1;
  ------------------
  |  Branch (698:9): [True: 0, False: 51]
  ------------------
  699|       |
  700|     51|    return pos;
  701|     51|}
simclist.c:list_attributes_setdefaults:
  295|    295|int list_attributes_setdefaults(list_t *simclist_restrict l) {
  296|    295|    l->attrs.comparator = NULL;
  297|    295|    l->attrs.seeker = NULL;
  298|       |
  299|       |    /* also free() element data when removing and element from the list */
  300|    295|    l->attrs.meter = NULL;
  301|    295|    l->attrs.copy_data = 0;
  302|       |
  303|    295|    l->attrs.hasher = NULL;
  304|       |
  305|       |    /* serializer/unserializer */
  306|    295|    l->attrs.serializer = NULL;
  307|    295|    l->attrs.unserializer = NULL;
  308|       |
  309|    295|    assert(list_attrOk(l));
  310|       |
  311|    295|    return 0;
  312|    295|}
simclist.c:list_findpos:
  416|    204|static simclist_inline struct list_entry_s *list_findpos(const list_t *simclist_restrict l, int posstart) {
  417|    204|    struct list_entry_s *ptr;
  418|    204|    float x;
  419|    204|    int i;
  420|       |
  421|    204|    if (l->head_sentinel == NULL || l->tail_sentinel == NULL) return NULL;
  ------------------
  |  Branch (421:9): [True: 0, False: 204]
  |  Branch (421:37): [True: 0, False: 204]
  ------------------
  422|       |
  423|       |    /* accept 1 slot overflow for fetching head and tail sentinels */
  424|    204|    if (posstart < -1 || posstart > (int)l->numels) return NULL;
  ------------------
  |  Branch (424:9): [True: 0, False: 204]
  |  Branch (424:26): [True: 0, False: 204]
  ------------------
  425|       |
  426|    204|    x = l->numels ? (float)(posstart+1) / l->numels : 0;
  ------------------
  |  Branch (426:9): [True: 153, False: 51]
  ------------------
  427|    204|    if (x <= 0.25) {
  ------------------
  |  Branch (427:9): [True: 51, False: 153]
  ------------------
  428|       |        /* first quarter: get to posstart from head */
  429|     51|        for (i = -1, ptr = l->head_sentinel; i < posstart; ptr = ptr->next, i++);
  ------------------
  |  Branch (429:46): [True: 0, False: 51]
  ------------------
  430|    153|    } else if (x < 0.5) {
  ------------------
  |  Branch (430:16): [True: 0, False: 153]
  ------------------
  431|       |        /* second quarter: get to posstart from mid */
  432|      0|        for (i = (l->numels-1)/2, ptr = l->mid; i > posstart; ptr = ptr->prev, i--);
  ------------------
  |  Branch (432:49): [True: 0, False: 0]
  ------------------
  433|    153|    } else if (x <= 0.75) {
  ------------------
  |  Branch (433:16): [True: 0, False: 153]
  ------------------
  434|       |        /* third quarter: get to posstart from mid */
  435|      0|        for (i = (l->numels-1)/2, ptr = l->mid; i < posstart; ptr = ptr->next, i++);
  ------------------
  |  Branch (435:49): [True: 0, False: 0]
  ------------------
  436|    153|    } else {
  437|       |        /* fourth quarter: get to posstart from tail */
  438|    306|        for (i = l->numels, ptr = l->tail_sentinel; i > posstart; ptr = ptr->prev, i--);
  ------------------
  |  Branch (438:53): [True: 153, False: 153]
  ------------------
  439|    153|    }
  440|       |
  441|    204|    return ptr;
  442|    204|}
simclist.c:list_drop_elem:
 1427|     51|static int list_drop_elem(list_t *simclist_restrict l, struct list_entry_s *tmp, unsigned int pos) {
 1428|     51|    if (tmp == NULL) return -1;
  ------------------
  |  Branch (1428:9): [True: 0, False: 51]
  ------------------
 1429|       |
 1430|       |    /* fix mid pointer. This is wrt the PRE situation */
 1431|     51|    if (l->numels % 2) {    /* now odd */
  ------------------
  |  Branch (1431:9): [True: 51, False: 0]
  ------------------
 1432|       |        /* sort out the base case by hand */
 1433|     51|        if (l->numels == 1) l->mid = NULL;
  ------------------
  |  Branch (1433:13): [True: 51, False: 0]
  ------------------
 1434|      0|        else if (pos >= l->numels/2) l->mid = l->mid->prev;
  ------------------
  |  Branch (1434:18): [True: 0, False: 0]
  ------------------
 1435|     51|    } else {                /* now even */
 1436|      0|        if (pos < l->numels/2) l->mid = l->mid->next;
  ------------------
  |  Branch (1436:13): [True: 0, False: 0]
  ------------------
 1437|      0|    }
 1438|       |
 1439|     51|    tmp->prev->next = tmp->next;
 1440|     51|    tmp->next->prev = tmp->prev;
 1441|       |
 1442|       |    /* free what's to be freed */
 1443|     51|    if (l->attrs.copy_data && tmp->data != NULL)
  ------------------
  |  Branch (1443:9): [True: 0, False: 51]
  |  Branch (1443:31): [True: 0, False: 0]
  ------------------
 1444|      0|        free(tmp->data);
 1445|       |
 1446|     51|    if (l->spareels != NULL && l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS) {
  ------------------
  |  |  115|     51|#define SIMCLIST_MAX_SPARE_ELEMS        5
  ------------------
  |  Branch (1446:9): [True: 51, False: 0]
  |  Branch (1446:32): [True: 51, False: 0]
  ------------------
 1447|     51|        l->spareels[l->spareelsnum++] = tmp;
 1448|     51|    } else {
 1449|      0|        free(tmp);
 1450|      0|    }
 1451|       |
 1452|     51|    return 0;
 1453|     51|}

sc_check_apdu:
  257|  2.24k|{
  258|  2.24k|	if ((apdu->cse & ~SC_APDU_SHORT_MASK) == 0) {
  ------------------
  |  |  295|  2.24k|#define SC_APDU_SHORT_MASK		0x0f
  ------------------
  |  Branch (258:6): [True: 2.24k, False: 0]
  ------------------
  259|       |		/* length check for short APDU */
  260|  2.24k|		if (apdu->le > 256 || (apdu->lc > 255 && (apdu->flags & SC_APDU_FLAGS_CHAINING) == 0))   {
  ------------------
  |  |  306|      0|#define SC_APDU_FLAGS_CHAINING		0x00000001UL
  ------------------
  |  Branch (260:7): [True: 0, False: 2.24k]
  |  Branch (260:26): [True: 0, False: 2.24k]
  |  Branch (260:44): [True: 0, False: 0]
  ------------------
  261|      0|			sc_log(card->ctx, "failed length check for short APDU");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  262|      0|			goto error;
  263|      0|		}
  264|  2.24k|	}
  265|      0|	else if ((apdu->cse & SC_APDU_EXT) != 0) {
  ------------------
  |  |  296|      0|#define SC_APDU_EXT			0x10
  ------------------
  |  Branch (265:11): [True: 0, False: 0]
  ------------------
  266|       |		/* check if the card supports extended APDUs */
  267|      0|		if ((card->caps & SC_CARD_CAP_APDU_EXT) == 0) {
  ------------------
  |  |  554|      0|#define SC_CARD_CAP_APDU_EXT		0x00000001
  ------------------
  |  Branch (267:7): [True: 0, False: 0]
  ------------------
  268|      0|			sc_log(card->ctx, "card doesn't support extended APDUs");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  269|      0|			goto error;
  270|      0|		}
  271|       |		/* length check for extended APDU */
  272|      0|		if (apdu->le > 65536 || apdu->lc > 65535)   {
  ------------------
  |  Branch (272:7): [True: 0, False: 0]
  |  Branch (272:27): [True: 0, False: 0]
  ------------------
  273|      0|			sc_log(card->ctx, "failed length check for extended APDU");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  274|      0|			goto error;
  275|      0|		}
  276|      0|	}
  277|      0|	else   {
  278|      0|		goto error;
  279|      0|	}
  280|       |
  281|  2.24k|	switch (apdu->cse & SC_APDU_SHORT_MASK) {
  ------------------
  |  |  295|  2.24k|#define SC_APDU_SHORT_MASK		0x0f
  ------------------
  282|      0|	case SC_APDU_CASE_1:
  ------------------
  |  |  291|      0|#define SC_APDU_CASE_1			0x01
  ------------------
  |  Branch (282:2): [True: 0, False: 2.24k]
  ------------------
  283|       |		/* no data is sent or received */
  284|      0|		if (apdu->datalen != 0 || apdu->lc != 0 || apdu->le != 0)
  ------------------
  |  Branch (284:7): [True: 0, False: 0]
  |  Branch (284:29): [True: 0, False: 0]
  |  Branch (284:46): [True: 0, False: 0]
  ------------------
  285|      0|			goto error;
  286|      0|		break;
  287|     51|	case SC_APDU_CASE_2_SHORT:
  ------------------
  |  |  292|     51|#define SC_APDU_CASE_2_SHORT		0x02
  ------------------
  |  Branch (287:2): [True: 51, False: 2.19k]
  ------------------
  288|       |		/* no data is sent */
  289|     51|		if (apdu->datalen != 0 || apdu->lc != 0)
  ------------------
  |  Branch (289:7): [True: 0, False: 51]
  |  Branch (289:29): [True: 0, False: 51]
  ------------------
  290|      0|			goto error;
  291|       |		/* data is expected       */
  292|     51|		if (apdu->resplen == 0 || apdu->resp == NULL)
  ------------------
  |  Branch (292:7): [True: 0, False: 51]
  |  Branch (292:29): [True: 0, False: 51]
  ------------------
  293|      0|			goto error;
  294|     51|		break;
  295|    255|	case SC_APDU_CASE_3_SHORT:
  ------------------
  |  |  293|    255|#define SC_APDU_CASE_3_SHORT		0x03
  ------------------
  |  Branch (295:2): [True: 255, False: 1.98k]
  ------------------
  296|       |		/* data is sent */
  297|    255|		if (apdu->datalen == 0 || apdu->data == NULL || apdu->lc == 0)
  ------------------
  |  Branch (297:7): [True: 0, False: 255]
  |  Branch (297:29): [True: 0, False: 255]
  |  Branch (297:51): [True: 0, False: 255]
  ------------------
  298|      0|			goto error;
  299|       |		/* no data is expected    */
  300|    255|		if (apdu->le != 0)
  ------------------
  |  Branch (300:7): [True: 0, False: 255]
  ------------------
  301|      0|			goto error;
  302|       |		/* inconsistent datalen   */
  303|    255|		if (apdu->datalen != apdu->lc)
  ------------------
  |  Branch (303:7): [True: 0, False: 255]
  ------------------
  304|      0|			goto error;
  305|    255|		break;
  306|  1.93k|	case SC_APDU_CASE_4_SHORT:
  ------------------
  |  |  294|  1.93k|#define SC_APDU_CASE_4_SHORT		0x04
  ------------------
  |  Branch (306:2): [True: 1.93k, False: 306]
  ------------------
  307|       |		/* data is sent */
  308|  1.93k|		if (apdu->datalen == 0 || apdu->data == NULL || apdu->lc == 0)
  ------------------
  |  Branch (308:7): [True: 0, False: 1.93k]
  |  Branch (308:29): [True: 0, False: 1.93k]
  |  Branch (308:51): [True: 0, False: 1.93k]
  ------------------
  309|      0|			goto error;
  310|       |		/* data is expected       */
  311|  1.93k|		if (apdu->resplen == 0 || apdu->resp == NULL)
  ------------------
  |  Branch (311:7): [True: 0, False: 1.93k]
  |  Branch (311:29): [True: 0, False: 1.93k]
  ------------------
  312|      0|			goto error;
  313|       |		/* inconsistent datalen   */
  314|  1.93k|		if (apdu->datalen != apdu->lc)
  ------------------
  |  Branch (314:7): [True: 0, False: 1.93k]
  ------------------
  315|      0|			goto error;
  316|  1.93k|		break;
  317|  1.93k|	default:
  ------------------
  |  Branch (317:2): [True: 0, False: 2.24k]
  ------------------
  318|      0|		sc_log(card->ctx, "Invalid APDU case %d", apdu->cse);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  319|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  320|  2.24k|	}
  321|  2.24k|	return SC_SUCCESS;
  ------------------
  |  |   28|  2.24k|#define SC_SUCCESS				0
  ------------------
  322|      0|error:
  323|      0|	sc_log(card->ctx, "Invalid Case %d %s APDU:\n"
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |               #define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |  326|      0|		apdu->cse & SC_APDU_SHORT_MASK,
  |  |  |  |  ------------------
  |  |  |  |  |  |  295|      0|#define SC_APDU_SHORT_MASK		0x0f
  |  |  |  |  ------------------
  |  |  |  |  327|      0|		(apdu->cse & SC_APDU_EXT) != 0 ? "extended" : "short",
  |  |  |  |  ------------------
  |  |  |  |  |  |  296|      0|#define SC_APDU_EXT			0x10
  |  |  |  |  ------------------
  |  |  |  |  328|      0|		apdu->cse, apdu->cla, apdu->ins, apdu->p1, apdu->p2,
  |  |  |  |  329|      0|		(unsigned long) apdu->lc, (unsigned long) apdu->le,
  |  |  |  |  330|      0|		apdu->resp, (unsigned long) apdu->resplen,
  |  |  |  |  331|      0|		apdu->data, (unsigned long) apdu->datalen, apdu->flags);
  |  |  ------------------
  ------------------
  324|      0|		"cse=%02x cla=%02x ins=%02x p1=%02x p2=%02x lc=%lu le=%lu\n"
  325|      0|		"resp=%p resplen=%lu data=%p datalen=%lu flags=0x%8.8lx",
  326|      0|		apdu->cse & SC_APDU_SHORT_MASK,
  327|      0|		(apdu->cse & SC_APDU_EXT) != 0 ? "extended" : "short",
  328|      0|		apdu->cse, apdu->cla, apdu->ins, apdu->p1, apdu->p2,
  329|      0|		(unsigned long) apdu->lc, (unsigned long) apdu->le,
  330|      0|		apdu->resp, (unsigned long) apdu->resplen,
  331|      0|		apdu->data, (unsigned long) apdu->datalen, apdu->flags);
  332|      0|	return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  333|  2.24k|}
sc_transmit_apdu:
  544|  2.24k|{
  545|  2.24k|	int r = SC_SUCCESS;
  ------------------
  |  |   28|  2.24k|#define SC_SUCCESS				0
  ------------------
  546|       |
  547|  2.24k|	if (card == NULL || apdu == NULL)
  ------------------
  |  Branch (547:6): [True: 0, False: 2.24k]
  |  Branch (547:22): [True: 0, False: 2.24k]
  ------------------
  548|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  549|       |
  550|  2.24k|	LOG_FUNC_CALLED(card->ctx);
  ------------------
  |  |  151|  2.24k|#define LOG_FUNC_CALLED(ctx) SC_FUNC_CALLED((ctx), SC_LOG_DEBUG_NORMAL)
  |  |  ------------------
  |  |  |  |  148|  2.24k|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  |  |  149|  2.24k|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  150|  2.24k|} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (150:10): [Folded, False: 2.24k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  551|       |
  552|       |	/* determine the APDU type if necessary, i.e. to use
  553|       |	 * short or extended APDUs  */
  554|  2.24k|	sc_detect_apdu_cse(card, apdu);
  555|       |	/* basic APDU consistency check */
  556|  2.24k|	r = sc_check_apdu(card, apdu);
  557|  2.24k|	if (r != SC_SUCCESS)
  ------------------
  |  |   28|  2.24k|#define SC_SUCCESS				0
  ------------------
  |  Branch (557:6): [True: 0, False: 2.24k]
  ------------------
  558|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  559|       |
  560|  2.24k|	r = sc_lock(card);	/* acquire card lock*/
  561|  2.24k|	if (r != SC_SUCCESS) {
  ------------------
  |  |   28|  2.24k|#define SC_SUCCESS				0
  ------------------
  |  Branch (561:6): [True: 0, False: 2.24k]
  ------------------
  562|      0|		sc_log(card->ctx, "unable to acquire lock");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  563|      0|		return r;
  564|      0|	}
  565|       |
  566|  2.24k|#if ENABLE_SM
  567|  2.24k|	if (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT
  ------------------
  |  |   47|  4.48k|#define SM_MODE_TRANSMIT	0x200
  ------------------
  |  Branch (567:6): [True: 0, False: 2.24k]
  ------------------
  568|      0|			&& (apdu->flags & SC_APDU_FLAGS_CHAINING) != 0
  ------------------
  |  |  306|      0|#define SC_APDU_FLAGS_CHAINING		0x00000001UL
  ------------------
  |  Branch (568:7): [True: 0, False: 0]
  ------------------
  569|      0|			&& (apdu->flags & SC_APDU_FLAGS_SM_CHAINING) != 0) {
  ------------------
  |  |  316|      0|#define SC_APDU_FLAGS_SM_CHAINING	0x00000010UL
  ------------------
  |  Branch (569:7): [True: 0, False: 0]
  ------------------
  570|      0|		sc_log(card->ctx,"Let SM do the chaining");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  571|      0|		r = sc_transmit(card, apdu);
  572|      0|	} else
  573|  2.24k|#endif
  574|  2.24k|	if ((apdu->flags & SC_APDU_FLAGS_CHAINING) != 0) {
  ------------------
  |  |  306|  2.24k|#define SC_APDU_FLAGS_CHAINING		0x00000001UL
  ------------------
  |  Branch (574:6): [True: 0, False: 2.24k]
  ------------------
  575|       |		/* divide et impera: transmit APDU in chunks with Lc <= max_send_size
  576|       |		 * bytes using command chaining */
  577|      0|		size_t    len  = apdu->datalen;
  578|      0|		const u8  *buf = apdu->data;
  579|      0|		size_t    max_send_size = sc_get_max_send_size(card);
  580|       |
  581|      0|		while (len != 0) {
  ------------------
  |  Branch (581:10): [True: 0, False: 0]
  ------------------
  582|      0|			size_t    plen;
  583|      0|			sc_apdu_t tapdu;
  584|      0|			int       last = 0;
  585|       |
  586|      0|			tapdu = *apdu;
  587|       |			/* clear chaining flag */
  588|      0|			tapdu.flags &= ~SC_APDU_FLAGS_CHAINING;
  ------------------
  |  |  306|      0|#define SC_APDU_FLAGS_CHAINING		0x00000001UL
  ------------------
  589|      0|			if (len > max_send_size) {
  ------------------
  |  Branch (589:8): [True: 0, False: 0]
  ------------------
  590|       |				/* adjust APDU case: in case of CASE 4 APDU
  591|       |				 * the intermediate APDU are of CASE 3 */
  592|      0|				if ((tapdu.cse & SC_APDU_SHORT_MASK) == SC_APDU_CASE_4_SHORT)
  ------------------
  |  |  295|      0|#define SC_APDU_SHORT_MASK		0x0f
  ------------------
              				if ((tapdu.cse & SC_APDU_SHORT_MASK) == SC_APDU_CASE_4_SHORT)
  ------------------
  |  |  294|      0|#define SC_APDU_CASE_4_SHORT		0x04
  ------------------
  |  Branch (592:9): [True: 0, False: 0]
  ------------------
  593|      0|					tapdu.cse--;
  594|       |				/* XXX: the chunk size must be adjusted when
  595|       |				 *      secure messaging is used */
  596|      0|				plen          = max_send_size;
  597|      0|				tapdu.cla    |= 0x10;
  598|       |				/* the intermediate APDU don't expect response data */
  599|      0|				tapdu.le      = 0;
  600|      0|				tapdu.resplen = 0;
  601|      0|				tapdu.resp    = NULL;
  602|      0|			} else {
  603|      0|				plen = len;
  604|      0|				last = 1;
  605|      0|			}
  606|      0|			tapdu.data    = buf;
  607|      0|			tapdu.datalen = tapdu.lc = plen;
  608|       |
  609|      0|			r = sc_check_apdu(card, &tapdu);
  610|      0|			if (r != SC_SUCCESS) {
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (610:8): [True: 0, False: 0]
  ------------------
  611|      0|				sc_log(card->ctx, "inconsistent APDU while chaining");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  612|      0|				break;
  613|      0|			}
  614|       |
  615|      0|			r = sc_transmit(card, &tapdu);
  616|      0|			if (r != SC_SUCCESS)
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (616:8): [True: 0, False: 0]
  ------------------
  617|      0|				break;
  618|      0|			if (last != 0) {
  ------------------
  |  Branch (618:8): [True: 0, False: 0]
  ------------------
  619|       |				/* in case of the last APDU set the SW1
  620|       |				 * and SW2 bytes in the original APDU */
  621|      0|				apdu->sw1 = tapdu.sw1;
  622|      0|				apdu->sw2 = tapdu.sw2;
  623|      0|				apdu->resplen = tapdu.resplen;
  624|      0|			} else {
  625|       |				/* otherwise check the status bytes */
  626|      0|				r = sc_check_sw(card, tapdu.sw1, tapdu.sw2);
  627|      0|				if (r != SC_SUCCESS)
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (627:9): [True: 0, False: 0]
  ------------------
  628|      0|					break;
  629|      0|			}
  630|      0|			len -= plen;
  631|      0|			buf += plen;
  632|      0|		}
  633|  2.24k|	} else {
  634|       |		/* transmit single APDU */
  635|  2.24k|		r = sc_transmit(card, apdu);
  636|  2.24k|	}
  637|       |
  638|  2.24k|	if (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) {
  ------------------
  |  |   37|  4.48k|#define SC_ERROR_CARD_RESET			-1106
  ------------------
              	if (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) {
  ------------------
  |  |   46|  2.24k|#define SC_ERROR_READER_REATTACHED		-1115
  ------------------
  |  Branch (638:6): [True: 0, False: 2.24k]
  |  Branch (638:34): [True: 0, False: 2.24k]
  ------------------
  639|       |		/* give card driver a chance to react on resets */
  640|      0|		if (card->ops->card_reader_lock_obtained)
  ------------------
  |  Branch (640:7): [True: 0, False: 0]
  ------------------
  641|      0|			card->ops->card_reader_lock_obtained(card, 1);
  642|      0|	}
  643|       |
  644|       |	/* all done => release lock */
  645|  2.24k|	if (sc_unlock(card) != SC_SUCCESS)
  ------------------
  |  |   28|  2.24k|#define SC_SUCCESS				0
  ------------------
  |  Branch (645:6): [True: 0, False: 2.24k]
  ------------------
  646|      0|		sc_log(card->ctx, "sc_unlock failed");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  647|       |
  648|  2.24k|	return r;
  649|  2.24k|}
apdu.c:sc_detect_apdu_cse:
  341|  2.24k|{
  342|  2.24k|	if (apdu->cse == SC_APDU_CASE_2 || apdu->cse == SC_APDU_CASE_3 ||
  ------------------
  |  |  301|  4.48k|#define SC_APDU_CASE_2			0x22
  ------------------
              	if (apdu->cse == SC_APDU_CASE_2 || apdu->cse == SC_APDU_CASE_3 ||
  ------------------
  |  |  302|  4.48k|#define SC_APDU_CASE_3			0x23
  ------------------
  |  Branch (342:6): [True: 0, False: 2.24k]
  |  Branch (342:37): [True: 0, False: 2.24k]
  ------------------
  343|  2.24k|	    apdu->cse == SC_APDU_CASE_4) {
  ------------------
  |  |  303|  2.24k|#define SC_APDU_CASE_4			0x24
  ------------------
  |  Branch (343:6): [True: 0, False: 2.24k]
  ------------------
  344|      0|		int btype = apdu->cse & SC_APDU_SHORT_MASK;
  ------------------
  |  |  295|      0|#define SC_APDU_SHORT_MASK		0x0f
  ------------------
  345|       |		/* if either Lc or Le is bigger than the maximum for
  346|       |		 * short APDUs and the card supports extended APDUs
  347|       |		 * use extended APDUs (unless Lc is greater than
  348|       |		 * 255 and command chaining is activated) */
  349|      0|		if ((apdu->le > 256 || (apdu->lc > 255 && (apdu->flags & SC_APDU_FLAGS_CHAINING) == 0)) &&
  ------------------
  |  |  306|      0|#define SC_APDU_FLAGS_CHAINING		0x00000001UL
  ------------------
  |  Branch (349:8): [True: 0, False: 0]
  |  Branch (349:27): [True: 0, False: 0]
  |  Branch (349:45): [True: 0, False: 0]
  ------------------
  350|      0|		    (card->caps & SC_CARD_CAP_APDU_EXT) != 0)
  ------------------
  |  |  554|      0|#define SC_CARD_CAP_APDU_EXT		0x00000001
  ------------------
  |  Branch (350:7): [True: 0, False: 0]
  ------------------
  351|      0|			btype |= SC_APDU_EXT;
  ------------------
  |  |  296|      0|#define SC_APDU_EXT			0x10
  ------------------
  352|      0|		apdu->cse = btype;
  353|      0|	}
  354|  2.24k|}
apdu.c:sc_transmit:
  510|  2.24k|{
  511|  2.24k|	struct sc_context *ctx  = card->ctx;
  512|  2.24k|	size_t       olen  = apdu->resplen;
  513|  2.24k|	int          r;
  514|       |
  515|  2.24k|	LOG_FUNC_CALLED(ctx);
  ------------------
  |  |  151|  2.24k|#define LOG_FUNC_CALLED(ctx) SC_FUNC_CALLED((ctx), SC_LOG_DEBUG_NORMAL)
  |  |  ------------------
  |  |  |  |  148|  2.24k|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  |  |  149|  2.24k|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  150|  2.24k|} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (150:10): [Folded, False: 2.24k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  516|       |
  517|  2.24k|	r = sc_single_transmit(card, apdu);
  518|  2.24k|	LOG_TEST_RET(ctx, r, "transmit APDU failed");
  ------------------
  |  |  174|  2.24k|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|  2.24k|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|  2.24k|	int _ret = (r); \
  |  |  |  |  168|  2.24k|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 2.24k]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|  2.24k|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 2.24k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  519|       |
  520|       |	/* ok, the APDU was successfully transmitted. Now we have two special cases:
  521|       |	 * 1. the card returned 0x6Cxx: in this case APDU will be re-transmitted with Le set to SW2
  522|       |	 * (possible only if response buffer size is larger than new Le = SW2)
  523|       |	 */
  524|  2.24k|	if (apdu->sw1 == 0x6C && (apdu->flags & SC_APDU_FLAGS_NO_RETRY_WL) == 0) {
  ------------------
  |  |  312|      0|#define SC_APDU_FLAGS_NO_RETRY_WL	0x00000004UL
  ------------------
  |  Branch (524:6): [True: 0, False: 2.24k]
  |  Branch (524:27): [True: 0, False: 0]
  ------------------
  525|      0|		r = sc_set_le_and_transmit(card, apdu, olen);
  526|      0|		LOG_TEST_RET(ctx, r, "cannot re-transmit APDU ");
  ------------------
  |  |  174|      0|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|      0|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|      0|	int _ret = (r); \
  |  |  |  |  168|      0|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  527|      0|	}
  528|       |
  529|       |	/* 2. the card returned 0x61xx: more data can be read from the card
  530|       |	 *    using the GET RESPONSE command (mostly used in the T0 protocol).
  531|       |	 *    Unless the SC_APDU_FLAGS_NO_GET_RESP is set we try to read as
  532|       |	 *    much data as possible using GET RESPONSE.
  533|       |	 */
  534|  2.24k|	if (apdu->sw1 == 0x61 && (apdu->flags & SC_APDU_FLAGS_NO_GET_RESP) == 0) {
  ------------------
  |  |  308|      0|#define SC_APDU_FLAGS_NO_GET_RESP	0x00000002UL
  ------------------
  |  Branch (534:6): [True: 0, False: 2.24k]
  |  Branch (534:27): [True: 0, False: 0]
  ------------------
  535|      0|		r = sc_get_response(card, apdu, olen);
  536|      0|		LOG_TEST_RET(ctx, r, "cannot get all data with 'GET RESPONSE'");
  ------------------
  |  |  174|      0|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|      0|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|      0|	int _ret = (r); \
  |  |  |  |  168|      0|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  537|      0|	}
  538|       |
  539|  2.24k|	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
  ------------------
  |  |  164|  2.24k|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|  2.24k|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|  2.24k|	int _ret = r; \
  |  |  |  |  155|  2.24k|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 2.24k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|  2.24k|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 2.24k]
  |  |  |  |  ------------------
  |  |  |  |  157|  2.24k|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|  2.24k|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|  2.24k|	return _ret; \
  |  |  |  |  163|  2.24k|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  540|  2.24k|}
apdu.c:sc_single_transmit:
  359|  2.24k|{
  360|  2.24k|	struct sc_context *ctx  = card->ctx;
  361|  2.24k|	int rv;
  362|       |
  363|  2.24k|	LOG_FUNC_CALLED(ctx);
  ------------------
  |  |  151|  2.24k|#define LOG_FUNC_CALLED(ctx) SC_FUNC_CALLED((ctx), SC_LOG_DEBUG_NORMAL)
  |  |  ------------------
  |  |  |  |  148|  2.24k|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  |  |  149|  2.24k|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  150|  2.24k|} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (150:10): [Folded, False: 2.24k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  364|  2.24k|	if (card->reader->ops->transmit == NULL)
  ------------------
  |  Branch (364:6): [True: 0, False: 2.24k]
  ------------------
  365|  2.24k|		LOG_TEST_RET(card->ctx, SC_ERROR_NOT_SUPPORTED, "cannot transmit APDU");
  ------------------
  |  |  174|      0|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|      0|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|      0|	int _ret = (r); \
  |  |  |  |  168|      0|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  366|       |
  367|  2.24k|	sc_log(ctx,
  ------------------
  |  |   71|  2.24k|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  368|  2.24k|	       "CLA:%X, INS:%X, P1:%X, P2:%X, data(%"SC_FORMAT_LEN_SIZE_T"u) %p",
  369|  2.24k|	       apdu->cla, apdu->ins, apdu->p1, apdu->p2, apdu->datalen,
  370|  2.24k|	       apdu->data);
  371|  2.24k|#ifdef ENABLE_SM
  372|  2.24k|	if (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT
  ------------------
  |  |   47|  4.48k|#define SM_MODE_TRANSMIT	0x200
  ------------------
  |  Branch (372:6): [True: 0, False: 2.24k]
  ------------------
  373|      0|		   	&& (apdu->flags & SC_APDU_FLAGS_NO_SM) == 0) {
  ------------------
  |  |  314|      0|#define SC_APDU_FLAGS_NO_SM		0x00000008UL
  ------------------
  |  Branch (373:10): [True: 0, False: 0]
  ------------------
  374|      0|		LOG_FUNC_RETURN(ctx, sc_sm_single_transmit(card, apdu));
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  375|      0|	}
  376|  2.24k|#endif
  377|       |
  378|       |	/* send APDU to the reader driver */
  379|  2.24k|	rv = card->reader->ops->transmit(card->reader, apdu);
  380|  2.24k|	LOG_TEST_RET(ctx, rv, "unable to transmit APDU");
  ------------------
  |  |  174|  2.24k|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|  2.24k|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|  2.24k|	int _ret = (r); \
  |  |  |  |  168|  2.24k|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 2.24k]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|  2.24k|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 2.24k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  381|       |
  382|  2.24k|	LOG_FUNC_RETURN(ctx, rv);
  ------------------
  |  |  164|  2.24k|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|  2.24k|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|  2.24k|	int _ret = r; \
  |  |  |  |  155|  2.24k|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 2.24k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|  2.24k|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 2.24k]
  |  |  |  |  ------------------
  |  |  |  |  157|  2.24k|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|  2.24k|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|  2.24k|	return _ret; \
  |  |  |  |  163|  2.24k|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  383|  2.24k|}

sc_get_asepcos_driver:
 1086|    295|{
 1087|    295|	return sc_get_driver();
 1088|    295|}
card-asepcos.c:sc_get_driver:
 1064|    295|{
 1065|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (1065:6): [True: 1, False: 294]
  ------------------
 1066|      1|		iso_ops = sc_get_iso7816_driver()->ops;
 1067|    295|	asepcos_ops = *iso_ops;
 1068|    295|	asepcos_ops.match_card        = asepcos_match_card;
 1069|    295|	asepcos_ops.init              = asepcos_init;
 1070|    295|	asepcos_ops.select_file       = asepcos_select_file;
 1071|    295|	asepcos_ops.set_security_env  = asepcos_set_security_env;
 1072|    295|	asepcos_ops.decipher          = asepcos_decipher;
 1073|    295|	asepcos_ops.compute_signature = asepcos_compute_signature;
 1074|    295|	asepcos_ops.create_file       = asepcos_create_file;
 1075|    295|	asepcos_ops.delete_file       = asepcos_delete_file;
 1076|    295|	asepcos_ops.list_files        = asepcos_list_files;
 1077|    295|	asepcos_ops.card_ctl          = asepcos_card_ctl;
 1078|    295|	asepcos_ops.pin_cmd           = asepcos_pin_cmd;
 1079|    295|	asepcos_ops.logout            = asepcos_logout;
 1080|    295|	asepcos_ops.card_reader_lock_obtained = asepcos_card_reader_lock_obtained;
 1081|       |
 1082|    295|	return &asepcos_drv;
 1083|    295|}
card-asepcos.c:asepcos_match_card:
   47|     51|{
   48|     51|	int i = _sc_match_atr(card, asepcos_atrs, &card->type);
   49|     51|	if (i < 0)
  ------------------
  |  Branch (49:6): [True: 51, False: 0]
  ------------------
   50|     51|		return 0;
   51|      0|	return 1;
   52|     51|}

sc_get_atrust_acos_driver:
  814|    295|{
  815|    295|	return sc_get_driver();
  816|    295|}
card-atrust-acos.c:sc_get_driver:
  789|    295|{
  790|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
  791|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (791:6): [True: 1, False: 294]
  ------------------
  792|      1|		iso_ops = iso_drv->ops;
  793|       |
  794|    295|	atrust_acos_ops = *iso_drv->ops;
  795|    295|	atrust_acos_ops.match_card = atrust_acos_match_card;
  796|    295|	atrust_acos_ops.init   = atrust_acos_init;
  797|    295|	atrust_acos_ops.finish = atrust_acos_finish;
  798|    295|	atrust_acos_ops.select_file = atrust_acos_select_file;
  799|    295|	atrust_acos_ops.check_sw    = atrust_acos_check_sw;
  800|    295|	atrust_acos_ops.create_file = NULL;
  801|    295|	atrust_acos_ops.delete_file = NULL;
  802|    295|	atrust_acos_ops.set_security_env  = atrust_acos_set_security_env;
  803|    295|	atrust_acos_ops.compute_signature = atrust_acos_compute_signature;
  804|    295|	atrust_acos_ops.decipher    = atrust_acos_decipher;
  805|    295|	atrust_acos_ops.card_ctl    = atrust_acos_card_ctl;
  806|    295|	atrust_acos_ops.logout      = atrust_acos_logout;
  807|       |
  808|    295|	return &atrust_acos_drv;
  809|    295|}
card-atrust-acos.c:atrust_acos_match_card:
   76|     51|{
   77|     51|	int		i, match = 0;
   78|       |
   79|       |
   80|    255|	for (i = 0; atrust_acos_atrs[i] != NULL; i++)
  ------------------
  |  Branch (80:14): [True: 204, False: 51]
  ------------------
   81|    204|	{
   82|    204|		u8 defatr[SC_MAX_ATR_SIZE];
   83|    204|		size_t len = sizeof(defatr);
   84|    204|		const char *atrp = atrust_acos_atrs[i];
   85|       |
   86|    204|		if (sc_hex_to_bin(atrp, defatr, &len))
  ------------------
  |  Branch (86:7): [True: 0, False: 204]
  ------------------
   87|      0|			continue;
   88|       |		/* we may only verify part of ATR since */
   89|       |		/* part of the hist chars is variable */
   90|    204|		if (len > card->atr.len)
  ------------------
  |  Branch (90:7): [True: 204, False: 0]
  ------------------
   91|    204|			continue;
   92|      0|		if (memcmp(card->atr.value, defatr, len) != 0)
  ------------------
  |  Branch (92:7): [True: 0, False: 0]
  ------------------
   93|      0|			continue;
   94|       |
   95|      0|		match = 1;
   96|      0|		card->name = atrust_acos_names[i];
   97|       |
   98|      0|		break;
   99|      0|    }
  100|     51|	return match;
  101|     51|}

sc_get_authentic_driver:
 2168|    295|{
 2169|    295|	return sc_get_driver();
 2170|    295|}
card-authentic.c:sc_get_driver:
 2133|    295|{
 2134|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 2135|       |
 2136|    295|	if (!iso_ops)
  ------------------
  |  Branch (2136:6): [True: 1, False: 294]
  ------------------
 2137|      1|		iso_ops = iso_drv->ops;
 2138|       |
 2139|    295|	authentic_ops = *iso_ops;
 2140|       |
 2141|    295|	authentic_ops.match_card = authentic_match_card;
 2142|    295|	authentic_ops.init = authentic_init;
 2143|    295|	authentic_ops.finish = authentic_finish;
 2144|    295|	authentic_ops.read_binary = authentic_read_binary;
 2145|    295|	authentic_ops.write_binary = authentic_write_binary;
 2146|    295|	authentic_ops.update_binary = authentic_update_binary;
 2147|    295|	authentic_ops.erase_binary = authentic_erase_binary;
 2148|       |	/* authentic_ops.resize_file = authentic_resize_file; */
 2149|    295|	authentic_ops.select_file = authentic_select_file;
 2150|       |	/* get_response: Untested */
 2151|    295|	authentic_ops.get_challenge = authentic_get_challenge;
 2152|    295|	authentic_ops.set_security_env = authentic_set_security_env;
 2153|       |	/* decipher: Untested */
 2154|    295|	authentic_ops.decipher = authentic_decipher;
 2155|       |	/* authentic_ops.compute_signature = authentic_compute_signature; */
 2156|    295|	authentic_ops.create_file = authentic_create_file;
 2157|    295|	authentic_ops.delete_file = authentic_delete_file;
 2158|    295|	authentic_ops.card_ctl = authentic_card_ctl;
 2159|    295|	authentic_ops.process_fci = authentic_process_fci;
 2160|    295|	authentic_ops.pin_cmd = authentic_pin_cmd;
 2161|    295|	authentic_ops.card_reader_lock_obtained = authentic_card_reader_lock_obtained;
 2162|       |
 2163|    295|	return &authentic_drv;
 2164|    295|}
card-authentic.c:authentic_match_card:
  390|     51|{
  391|     51|	struct sc_context *ctx = card->ctx;
  392|     51|	int i;
  393|       |
  394|     51|	sc_log_hex(ctx, "try to match card with ATR", card->atr.value, card->atr.len);
  ------------------
  |  |  129|     51|    sc_debug_hex(ctx, SC_LOG_DEBUG_NORMAL, label, data, len)
  |  |  ------------------
  |  |  |  |  127|     51|    _sc_debug_hex(ctx, level, FILENAME, __LINE__, __FUNCTION__, label, data, len)
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  395|     51|	i = _sc_match_atr(card, authentic_known_atrs, &card->type);
  396|     51|	if (i < 0)   {
  ------------------
  |  Branch (396:6): [True: 51, False: 0]
  ------------------
  397|     51|		sc_log(ctx, "card not matched");
  ------------------
  |  |   71|     51|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  398|     51|		return 0;
  399|     51|	}
  400|       |
  401|      0|	sc_log(ctx, "'%s' card matched", authentic_known_atrs[i].name);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  402|      0|	return 1;
  403|     51|}

sc_get_belpic_driver:
  447|    295|{
  448|    295|	return sc_get_driver();
  449|    295|}
card-belpic.c:sc_get_driver:
  424|    295|{
  425|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (425:6): [True: 1, False: 294]
  ------------------
  426|      1|		iso_ops = sc_get_iso7816_driver()->ops;
  427|       |
  428|    295|	belpic_ops.match_card = belpic_match_card;
  429|    295|	belpic_ops.init = belpic_init;
  430|       |
  431|    295|	belpic_ops.update_binary = iso_ops->update_binary;
  432|    295|	belpic_ops.select_file = belpic_select_file;
  433|    295|	belpic_ops.read_binary = belpic_read_binary;
  434|    295|	belpic_ops.pin_cmd = belpic_pin_cmd;
  435|    295|	belpic_ops.set_security_env = belpic_set_security_env;
  436|       |
  437|    295|	belpic_ops.compute_signature = iso_ops->compute_signature;
  438|    295|	belpic_ops.get_challenge = iso_ops->get_challenge;
  439|    295|	belpic_ops.get_response = iso_ops->get_response;
  440|    295|	belpic_ops.check_sw = iso_ops->check_sw;
  441|       |
  442|    295|	return &belpic_drv;
  443|    295|}
card-belpic.c:belpic_match_card:
  209|     51|{
  210|     51|	int i;
  211|       |
  212|     51|	i = _sc_match_atr(card, belpic_atrs, &card->type);
  213|     51|	if (i < 0)
  ------------------
  |  Branch (213:6): [True: 51, False: 0]
  ------------------
  214|     51|		return 0;
  215|      0|	return 1;
  216|     51|}

sc_get_cac_driver:
 1944|    590|{
 1945|    590|	return sc_get_driver();
 1946|    590|}
card-cac.c:sc_get_driver:
 1918|    590|{
 1919|    590|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 1920|       |
 1921|    590|	cac_ops = *iso_drv->ops;
 1922|    590|	cac_ops.match_card = cac_match_card;
 1923|    590|	cac_ops.init = cac_init;
 1924|    590|	cac_ops.finish = cac_finish;
 1925|       |
 1926|    590|	cac_ops.select_file =  cac_select_file; /* need to record object type */
 1927|    590|	cac_ops.get_challenge = cac_get_challenge;
 1928|    590|	cac_ops.read_binary = cac_read_binary;
 1929|       |	/* CAC driver is read only */
 1930|    590|	cac_ops.write_binary = NULL;
 1931|    590|	cac_ops.set_security_env = cac_set_security_env;
 1932|    590|	cac_ops.restore_security_env = cac_restore_security_env;
 1933|    590|	cac_ops.compute_signature = cac_compute_signature;
 1934|    590|	cac_ops.decipher =  cac_decipher;
 1935|    590|	cac_ops.card_ctl = cac_card_ctl;
 1936|    590|	cac_ops.pin_cmd = cac_pin_cmd;
 1937|    590|	cac_ops.logout = cac_logout;
 1938|       |
 1939|    590|	return &cac_drv;
 1940|    590|}
card-cac.c:cac_match_card:
 1829|     51|{
 1830|     51|	int r;
 1831|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
 1832|       |
 1833|     51|	r = cac_find_and_initialize(card, 0);
 1834|     51|	return (r == SC_SUCCESS); /* never match */
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
 1835|     51|}
card-cac.c:cac_find_and_initialize:
 1752|     51|{
 1753|     51|	int r, index;
 1754|     51|	cac_private_data_t *priv = NULL;
 1755|       |
 1756|       |	/* already initialized? */
 1757|     51|	if (card->drv_data) {
  ------------------
  |  Branch (1757:6): [True: 0, False: 51]
  ------------------
 1758|      0|		return SC_SUCCESS;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
 1759|      0|	}
 1760|       |
 1761|       |	/* is this a CAC-2 specified in NIST Interagency Report 6887 -
 1762|       |	 * "Government Smart Card Interoperability Specification v2.1 July 2003" */
 1763|     51|	r = cac_select_CCC(card);
 1764|     51|	if (r == SC_SUCCESS) {
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  |  Branch (1764:6): [True: 0, False: 51]
  ------------------
 1765|      0|		sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "CCC found, is CAC-2");
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1766|      0|		if (!initialize) /* match card only */
  ------------------
  |  Branch (1766:7): [True: 0, False: 0]
  ------------------
 1767|      0|			return r;
 1768|       |
 1769|      0|		priv = cac_new_private_data();
 1770|      0|		if (!priv)
  ------------------
  |  Branch (1770:7): [True: 0, False: 0]
  ------------------
 1771|      0|			return SC_ERROR_OUT_OF_MEMORY;
  ------------------
  |  |   85|      0|#define SC_ERROR_OUT_OF_MEMORY			-1404
  ------------------
 1772|      0|		r = cac_process_CCC(card, priv, 0);
 1773|      0|		if (r == SC_SUCCESS) {
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (1773:7): [True: 0, False: 0]
  ------------------
 1774|      0|			card->type = SC_CARD_TYPE_CAC_II;
 1775|      0|			card->drv_data = priv;
 1776|      0|			return r;
 1777|      0|		}
 1778|      0|	}
 1779|       |
 1780|       |	/* Even some ALT tokens can be missing CCC so we should try with ACA */
 1781|     51|	r = cac_select_ACA(card);
 1782|     51|	if (r == SC_SUCCESS) {
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  |  Branch (1782:6): [True: 0, False: 51]
  ------------------
 1783|      0|		sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "ACA found, is CAC-2 without CCC");
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1784|      0|		if (!initialize) /* match card only */
  ------------------
  |  Branch (1784:7): [True: 0, False: 0]
  ------------------
 1785|      0|			return r;
 1786|       |
 1787|      0|		if (!priv) {
  ------------------
  |  Branch (1787:7): [True: 0, False: 0]
  ------------------
 1788|      0|			priv = cac_new_private_data();
 1789|      0|			if (!priv)
  ------------------
  |  Branch (1789:8): [True: 0, False: 0]
  ------------------
 1790|      0|				return SC_ERROR_OUT_OF_MEMORY;
  ------------------
  |  |   85|      0|#define SC_ERROR_OUT_OF_MEMORY			-1404
  ------------------
 1791|      0|		}
 1792|      0|		r = cac_process_ACA(card, priv);
 1793|      0|		if (r == SC_SUCCESS) {
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (1793:7): [True: 0, False: 0]
  ------------------
 1794|      0|			card->type = SC_CARD_TYPE_CAC_ALT_HID;
 1795|      0|			card->drv_data = priv;
 1796|      0|			return r;
 1797|      0|		}
 1798|      0|	}
 1799|       |
 1800|       |	/* is this a CAC Alt token without any accompanying structures */
 1801|     51|	r = cac_find_first_pki_applet(card, &index);
 1802|     51|	if (r == SC_SUCCESS) {
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  |  Branch (1802:6): [True: 0, False: 51]
  ------------------
 1803|      0|		sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "PKI applet found, is bare CAC Alt");
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1804|      0|		if (!initialize) /* match card only */
  ------------------
  |  Branch (1804:7): [True: 0, False: 0]
  ------------------
 1805|      0|			return r;
 1806|       |
 1807|      0|		if (!priv) {
  ------------------
  |  Branch (1807:7): [True: 0, False: 0]
  ------------------
 1808|      0|			priv = cac_new_private_data();
 1809|      0|			if (!priv)
  ------------------
  |  Branch (1809:8): [True: 0, False: 0]
  ------------------
 1810|      0|				return SC_ERROR_OUT_OF_MEMORY;
  ------------------
  |  |   85|      0|#define SC_ERROR_OUT_OF_MEMORY			-1404
  ------------------
 1811|      0|		}
 1812|      0|		card->drv_data = priv; /* needed for the read_binary() */
 1813|      0|		r = cac_populate_cac_alt(card, index, priv);
 1814|      0|		if (r == SC_SUCCESS) {
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (1814:7): [True: 0, False: 0]
  ------------------
 1815|      0|			card->type = SC_CARD_TYPE_CAC_II;
 1816|      0|			return r;
 1817|      0|		}
 1818|      0|		card->drv_data = NULL; /* reset on failure */
 1819|      0|	}
 1820|     51|	if (priv) {
  ------------------
  |  Branch (1820:6): [True: 0, False: 51]
  ------------------
 1821|      0|		cac_free_private_data(priv);
 1822|      0|	}
 1823|     51|	return r;
 1824|     51|}
card-cac.c:cac_select_CCC:
 1244|     51|{
 1245|       |	return cac_select_file_by_type(card, &cac_CCC_Path, NULL);
 1246|     51|}
card-cac.c:cac_select_file_by_type:
 1049|    918|{
 1050|    918|	struct sc_context *ctx;
 1051|    918|	struct sc_apdu apdu;
 1052|    918|	unsigned char buf[SC_MAX_APDU_BUFFER_SIZE];
 1053|    918|	unsigned char pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf;
 1054|    918|	int r, pathtype;
 1055|    918|	size_t pathlen;
 1056|    918|	struct sc_file *file = NULL;
 1057|    918|	cac_private_data_t *priv;
 1058|       |
 1059|    918|	if (card == NULL || in_path == NULL)
  ------------------
  |  Branch (1059:6): [True: 0, False: 918]
  |  Branch (1059:22): [True: 0, False: 918]
  ------------------
 1060|      0|		return SC_ERROR_INTERNAL;
  ------------------
  |  |   81|      0|#define SC_ERROR_INTERNAL			-1400
  ------------------
 1061|       |
 1062|    918|	priv = CAC_DATA(card);
  ------------------
  |  |   61|    918|#define CAC_DATA(card) ((cac_private_data_t*)card->drv_data)
  ------------------
 1063|    918|	ctx = card->ctx;
 1064|       |
 1065|    918|	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|    918|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|    918|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|    918|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 918]
  |  |  ------------------
  ------------------
 1066|       |
 1067|    918|	memcpy(path, in_path->value, in_path->len);
 1068|    918|	pathlen = in_path->len;
 1069|    918|	pathtype = in_path->type;
 1070|       |
 1071|    918|	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
  ------------------
  |  |   70|    918|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1072|    918|	    "path=%s, path->value=%s path->type=%d (%x)",
 1073|    918|	    sc_print_path(in_path),
 1074|    918|	    sc_dump_hex(in_path->value, in_path->len),
 1075|    918|	    in_path->type, in_path->type);
 1076|    918|	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "file_out=%p index=%d count=%d\n",
  ------------------
  |  |   70|    918|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1077|    918|	    file_out, in_path->index, in_path->count);
 1078|       |
 1079|       |	/* Sigh, iso7816_select_file expects paths to keys to have specific
 1080|       |	 * formats. There is no override. We have to add some bytes to the
 1081|       |	 * path to make it happy.
 1082|       |	 * We only need to do this for private keys.
 1083|       |	 */
 1084|    918|	if ((pathlen > 2) && (pathlen <= 4) && memcmp(path, "\x3F\x00", 2) == 0) {
  ------------------
  |  Branch (1084:6): [True: 0, False: 918]
  |  Branch (1084:23): [True: 0, False: 0]
  |  Branch (1084:41): [True: 0, False: 0]
  ------------------
 1085|      0|		path += 2;
 1086|      0|		pathlen -= 2;
 1087|      0|	}
 1088|       |
 1089|       |
 1090|       |	/* CAC has multiple different type of objects that aren't PKCS #15. When we read
 1091|       |	 * them we need convert them to something PKCS #15 would understand. Find the object
 1092|       |	 * and object type here:
 1093|       |	 */
 1094|    918|	if (priv) { /* don't record anything if we haven't been initialized yet */
  ------------------
  |  Branch (1094:6): [True: 0, False: 918]
  ------------------
 1095|      0|		priv->object_type = CAC_OBJECT_TYPE_GENERIC;
  ------------------
  |  |  172|      0|#define CAC_OBJECT_TYPE_GENERIC		5
  ------------------
 1096|      0|		if (cac_is_cert(priv, in_path)) {
  ------------------
  |  Branch (1096:7): [True: 0, False: 0]
  ------------------
 1097|      0|			priv->object_type = CAC_OBJECT_TYPE_CERT;
  ------------------
  |  |  170|      0|#define CAC_OBJECT_TYPE_CERT		1
  ------------------
 1098|      0|		}
 1099|       |
 1100|       |		/* forget any old cached values */
 1101|      0|		if (priv->cache_buf) {
  ------------------
  |  Branch (1101:7): [True: 0, False: 0]
  ------------------
 1102|      0|			free(priv->cache_buf);
 1103|      0|			priv->cache_buf = NULL;
 1104|      0|		}
 1105|      0|		priv->cache_buf_len = 0;
 1106|      0|		priv->cached = 0;
 1107|      0|	}
 1108|       |
 1109|    918|	if (in_path->aid.len) {
  ------------------
  |  Branch (1109:6): [True: 918, False: 0]
  ------------------
 1110|    918|		if (!pathlen) {
  ------------------
  |  Branch (1110:7): [True: 918, False: 0]
  ------------------
 1111|    918|			memcpy(path, in_path->aid.value, in_path->aid.len);
 1112|    918|			pathlen = in_path->aid.len;
 1113|    918|			pathtype = SC_PATH_TYPE_DF_NAME;
  ------------------
  |  |  118|    918|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
 1114|    918|		} else {
 1115|       |			/* First, select the application */
 1116|      0|			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"select application" );
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1117|      0|			sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 4, 0);
  ------------------
  |  |  293|      0|#define SC_APDU_CASE_3_SHORT		0x03
  ------------------
 1118|      0|			apdu.data = in_path->aid.value;
 1119|      0|			apdu.datalen = in_path->aid.len;
 1120|      0|			apdu.lc = in_path->aid.len;
 1121|       |
 1122|      0|			r = sc_transmit_apdu(card, &apdu);
 1123|      0|			LOG_TEST_RET(ctx, r, "APDU transmit failed");
  ------------------
  |  |  174|      0|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|      0|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|      0|	int _ret = (r); \
  |  |  |  |  168|      0|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1124|      0|			r = sc_check_sw(card, apdu.sw1, apdu.sw2);
 1125|      0|			if (r)
  ------------------
  |  Branch (1125:8): [True: 0, False: 0]
  ------------------
 1126|      0|				LOG_FUNC_RETURN(ctx, r);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1127|       |
 1128|      0|		}
 1129|    918|	}
 1130|       |
 1131|    918|	sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0, 0);
  ------------------
  |  |  294|    918|#define SC_APDU_CASE_4_SHORT		0x04
  ------------------
 1132|       |
 1133|    918|	switch (pathtype) {
 1134|       |	/* ideally we would had SC_PATH_TYPE_OBJECT_ID and add code to the iso7816 select.
 1135|       |	 * Unfortunately we'd also need to update the caching code as well. For now just
 1136|       |	 * use FILE_ID and change p1 here */
 1137|      0|	case SC_PATH_TYPE_FILE_ID:
  ------------------
  |  |  117|      0|#define SC_PATH_TYPE_FILE_ID		0
  ------------------
  |  Branch (1137:2): [True: 0, False: 918]
  ------------------
 1138|      0|		apdu.p1 = 2;
 1139|      0|		if (pathlen != 2)
  ------------------
  |  Branch (1139:7): [True: 0, False: 0]
  ------------------
 1140|      0|			return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
 1141|      0|		break;
 1142|    918|	case SC_PATH_TYPE_DF_NAME:
  ------------------
  |  |  118|    918|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
  |  Branch (1142:2): [True: 918, False: 0]
  ------------------
 1143|    918|		apdu.p1 = 4;
 1144|    918|		break;
 1145|      0|	default:
  ------------------
  |  Branch (1145:2): [True: 0, False: 918]
  ------------------
 1146|      0|		LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1147|    918|	}
 1148|    918|	apdu.lc = pathlen;
 1149|    918|	apdu.data = path;
 1150|    918|	apdu.datalen = pathlen;
 1151|    918|	apdu.resp = buf;
 1152|    918|	apdu.resplen = sizeof(buf);
 1153|    918|	apdu.le = sc_get_max_recv_size(card) < 256 ? sc_get_max_recv_size(card) : 256;
  ------------------
  |  Branch (1153:12): [True: 0, False: 918]
  ------------------
 1154|       |
 1155|    918|	if (file_out != NULL) {
  ------------------
  |  Branch (1155:6): [True: 0, False: 918]
  ------------------
 1156|      0|		apdu.p2 = 0;		/* first record, return FCI */
 1157|      0|	}
 1158|    918|	else {
 1159|    918|		apdu.p2 = 0x0C;
 1160|    918|	}
 1161|       |
 1162|    918|	r = sc_transmit_apdu(card, &apdu);
 1163|    918|	LOG_TEST_RET(ctx, r, "APDU transmit failed");
  ------------------
  |  |  174|    918|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|    918|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|    918|	int _ret = (r); \
  |  |  |  |  168|    918|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 918]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|    918|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 918]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1164|       |
 1165|    918|	if (file_out == NULL) {
  ------------------
  |  Branch (1165:6): [True: 918, False: 0]
  ------------------
 1166|       |		/* For some cards 'SELECT' can be only with request to return FCI/FCP. */
 1167|    918|		r = sc_check_sw(card, apdu.sw1, apdu.sw2);
 1168|    918|		if (apdu.sw1 == 0x6A && apdu.sw2 == 0x86)   {
  ------------------
  |  Branch (1168:7): [True: 0, False: 918]
  |  Branch (1168:27): [True: 0, False: 0]
  ------------------
 1169|      0|			apdu.p2 = 0x00;
 1170|      0|			apdu.resplen = sizeof(buf);
 1171|      0|			if (sc_transmit_apdu(card, &apdu) == SC_SUCCESS)
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (1171:8): [True: 0, False: 0]
  ------------------
 1172|      0|				r = sc_check_sw(card, apdu.sw1, apdu.sw2);
 1173|      0|		}
 1174|    918|		if (apdu.sw1 == 0x61)
  ------------------
  |  Branch (1174:7): [True: 0, False: 918]
  ------------------
 1175|    918|			LOG_FUNC_RETURN(ctx, SC_SUCCESS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1176|    918|		LOG_FUNC_RETURN(ctx, r);
  ------------------
  |  |  164|    918|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|    918|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|    918|	int _ret = r; \
  |  |  |  |  155|    918|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 918, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|    918|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|    918|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 918, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|    918|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|    918|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|    918|	return _ret; \
  |  |  |  |  163|    918|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1177|    918|	}
 1178|       |
 1179|      0|	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
 1180|      0|	if (r)
  ------------------
  |  Branch (1180:6): [True: 0, False: 0]
  ------------------
 1181|      0|		LOG_FUNC_RETURN(ctx, r);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1182|       |
 1183|       |	/* This needs to come after the applet selection */
 1184|      0|	if (priv && in_path->len >= 2) {
  ------------------
  |  Branch (1184:6): [True: 0, False: 0]
  |  Branch (1184:14): [True: 0, False: 0]
  ------------------
 1185|       |		/* get applet properties to know if we can treat the
 1186|       |		 * buffer as SimpleLTV and if we have PKI applet.
 1187|       |		 *
 1188|       |		 * Do this only if we select applets for reading
 1189|       |		 * (not during driver initialization)
 1190|       |		 */
 1191|      0|		cac_properties_t prop = {0};
 1192|      0|		size_t i = -1;
 1193|       |
 1194|      0|		r = cac_get_properties(card, &prop);
 1195|      0|		if (r == SC_SUCCESS) {
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (1195:7): [True: 0, False: 0]
  ------------------
 1196|      0|			for (i = 0; i < prop.num_objects; i++) {
  ------------------
  |  Branch (1196:16): [True: 0, False: 0]
  ------------------
 1197|      0|				sc_log(card->ctx, "Searching for our OID: 0x%02x 0x%02x = 0x%02x 0x%02x",
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1198|      0|				    prop.objects[i].oid[0], prop.objects[i].oid[1],
 1199|      0|					in_path->value[0], in_path->value[1]);
 1200|      0|				if (memcmp(prop.objects[i].oid,
  ------------------
  |  Branch (1200:9): [True: 0, False: 0]
  ------------------
 1201|      0|				    in_path->value, 2) == 0)
 1202|      0|					break;
 1203|      0|			}
 1204|      0|		}
 1205|      0|		if (i < prop.num_objects) {
  ------------------
  |  Branch (1205:7): [True: 0, False: 0]
  ------------------
 1206|      0|			if (prop.objects[i].privatekey)
  ------------------
  |  Branch (1206:8): [True: 0, False: 0]
  ------------------
 1207|      0|				priv->object_type = CAC_OBJECT_TYPE_CERT;
  ------------------
  |  |  170|      0|#define CAC_OBJECT_TYPE_CERT		1
  ------------------
 1208|      0|			else if (prop.objects[i].simpletlv == 0)
  ------------------
  |  Branch (1208:13): [True: 0, False: 0]
  ------------------
 1209|      0|				priv->object_type = CAC_OBJECT_TYPE_TLV_FILE;
  ------------------
  |  |  171|      0|#define CAC_OBJECT_TYPE_TLV_FILE	4
  ------------------
 1210|      0|		}
 1211|      0|	}
 1212|       |
 1213|       |	/* CAC cards never return FCI, fake one */
 1214|      0|	file = sc_file_new();
 1215|      0|	if (file == NULL)
  ------------------
  |  Branch (1215:6): [True: 0, False: 0]
  ------------------
 1216|      0|			LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1217|      0|	file->path = *in_path;
 1218|      0|	file->size = CAC_MAX_SIZE; /* we don't know how big, just give a large size until we can read the file */
  ------------------
  |  |   26|      0|#define CAC_MAX_SIZE 4096		/* arbitrary, just needs to be 'large enough' */
  ------------------
 1219|       |
 1220|      0|	*file_out = file;
 1221|      0|	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1222|       |
 1223|      0|}
card-cac.c:cac_select_ACA:
 1250|     51|{
 1251|       |	return cac_select_file_by_type(card, &cac_ACA_Path, NULL);
 1252|     51|}
card-cac.c:cac_find_first_pki_applet:
 1631|     51|{
 1632|     51|	int r, i;
 1633|    867|	for (i = 0; i < MAX_CAC_SLOTS; i++) {
  ------------------
  |  |   70|    867|#define MAX_CAC_SLOTS 16		/* Maximum number of slots is 16 now */
  ------------------
  |  Branch (1633:14): [True: 816, False: 51]
  ------------------
 1634|    816|		r = cac_select_pki_applet(card, i);
 1635|    816|		if (r == SC_SUCCESS) {
  ------------------
  |  |   28|    816|#define SC_SUCCESS				0
  ------------------
  |  Branch (1635:7): [True: 0, False: 816]
  ------------------
 1636|       |			/* Try to read first two bytes of the buffer to
 1637|       |			 * make sure it is not just malfunctioning card
 1638|       |			 */
 1639|      0|			u8 params[2] = {CAC_FILE_TAG, 2};
  ------------------
  |  |   66|      0|#define CAC_FILE_TAG    1
  ------------------
 1640|      0|			u8 data[2], *out_ptr = data;
 1641|      0|			size_t len = 2;
 1642|      0|			r = cac_apdu_io(card, CAC_INS_READ_FILE, 0, 0,
  ------------------
  |  |   61|      0|#define CAC_INS_READ_FILE             0x52  /* read a TL or V file */
  ------------------
 1643|      0|			    &params[0], sizeof(params), &out_ptr, &len);
 1644|      0|			if (r != 2)
  ------------------
  |  Branch (1644:8): [True: 0, False: 0]
  ------------------
 1645|      0|				continue;
 1646|       |
 1647|      0|			*index_out = i;
 1648|      0|			return SC_SUCCESS;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
 1649|      0|		}
 1650|    816|	}
 1651|     51|	return SC_ERROR_OBJECT_NOT_FOUND;
  ------------------
  |  |   88|     51|#define SC_ERROR_OBJECT_NOT_FOUND		-1407
  ------------------
 1652|     51|}
card-cac.c:cac_select_pki_applet:
 1621|    816|{
 1622|    816|	sc_path_t applet_path = cac_cac_pki_obj.path;
 1623|    816|	applet_path.aid.value[applet_path.aid.len-1] = index;
 1624|       |	return cac_select_file_by_type(card, &applet_path, NULL);
 1625|    816|}

sc_get_cac1_driver:
  558|    295|{
  559|    295|	return sc_get_driver();
  560|    295|}
card-cac1.c:sc_get_driver:
  540|    295|{
  541|       |	/* Inherit most of the things from the CAC driver */
  542|    295|	struct sc_card_driver *cac_drv = sc_get_cac_driver();
  543|       |
  544|    295|	cac_ops = *cac_drv->ops;
  545|    295|	cac_ops.match_card = cac_match_card;
  546|    295|	cac_ops.init = cac_init;
  547|    295|	cac_ops.finish = cac_finish;
  548|       |
  549|    295|	cac_ops.select_file =  cac_select_file; /* need to record object type */
  550|    295|	cac_ops.read_binary = cac_read_binary;
  551|    295|	cac_ops.logout = cac_logout;
  552|       |
  553|    295|	return &cac1_drv;
  554|    295|}
card-cac1.c:cac_match_card:
  493|     51|{
  494|     51|	int r;
  495|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
  496|       |
  497|     51|	r = cac_find_and_initialize(card, 0);
  498|     51|	return (r == SC_SUCCESS); /* never match */
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  499|     51|}
card-cac1.c:cac_find_and_initialize:
  455|     51|{
  456|     51|	int r, index;
  457|     51|	cac_private_data_t *priv = NULL;
  458|       |
  459|       |	/* already initialized? */
  460|     51|	if (card->drv_data) {
  ------------------
  |  Branch (460:6): [True: 0, False: 51]
  ------------------
  461|      0|		return SC_SUCCESS;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  462|      0|	}
  463|       |
  464|       |	/* is this a CAC Alt token without any accompanying structures */
  465|     51|	r = cac_find_first_pki_applet(card, &index);
  466|     51|	if (r == SC_SUCCESS) {
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  |  Branch (466:6): [True: 0, False: 51]
  ------------------
  467|      0|		sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "PKI applet found, is bare CAC-1");
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  468|      0|		if (!initialize) /* match card only */
  ------------------
  |  Branch (468:7): [True: 0, False: 0]
  ------------------
  469|      0|			return r;
  470|       |
  471|      0|		if (!priv) {
  ------------------
  |  Branch (471:7): [True: 0, False: 0]
  ------------------
  472|      0|			priv = cac_new_private_data();
  473|      0|			if (!priv)
  ------------------
  |  Branch (473:8): [True: 0, False: 0]
  ------------------
  474|      0|				return SC_ERROR_OUT_OF_MEMORY;
  ------------------
  |  |   85|      0|#define SC_ERROR_OUT_OF_MEMORY			-1404
  ------------------
  475|      0|		}
  476|      0|		card->drv_data = priv; /* needed for the read_binary() */
  477|      0|		r = cac_populate_cac1(card, index, priv);
  478|      0|		if (r == SC_SUCCESS) {
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (478:7): [True: 0, False: 0]
  ------------------
  479|      0|			card->type = SC_CARD_TYPE_CAC_I;
  480|      0|			return r;
  481|      0|		}
  482|      0|		card->drv_data = NULL; /* reset on failure */
  483|      0|	}
  484|     51|	if (priv) {
  ------------------
  |  Branch (484:6): [True: 0, False: 51]
  ------------------
  485|      0|		cac_free_private_data(priv);
  486|      0|	}
  487|     51|	return r;
  488|     51|}
card-cac1.c:cac_find_first_pki_applet:
  369|     51|{
  370|     51|	int r, i;
  371|       |
  372|    867|	for (i = 0; i < MAX_CAC_SLOTS; i++) {
  ------------------
  |  |   70|    867|#define MAX_CAC_SLOTS 16		/* Maximum number of slots is 16 now */
  ------------------
  |  Branch (372:14): [True: 816, False: 51]
  ------------------
  373|    816|		r = cac_select_pki_applet(card, i);
  374|    816|		if (r == SC_SUCCESS) {
  ------------------
  |  |   28|    816|#define SC_SUCCESS				0
  ------------------
  |  Branch (374:7): [True: 0, False: 816]
  ------------------
  375|      0|			u8 data[2];
  376|      0|			sc_apdu_t apdu;
  377|       |
  378|       |			/* Try to read first two bytes of the buffer to
  379|       |			 * make sure it is not just malfunctioning card
  380|       |			 */
  381|      0|			sc_format_apdu(card, &apdu, SC_APDU_CASE_2,
  ------------------
  |  |  301|      0|#define SC_APDU_CASE_2			0x22
  ------------------
  382|      0|				CAC_INS_GET_CERTIFICATE, 0x00, 0x00);
  ------------------
  |  |   59|      0|#define CAC_INS_GET_CERTIFICATE       0x36  /* CAC1 command to read a certificate */
  ------------------
  383|      0|			apdu.le = 0x02;
  384|      0|			apdu.resplen = 2;
  385|      0|			apdu.resp = data;
  386|      0|			r = sc_transmit_apdu(card, &apdu);
  387|       |			/* SW1 = 0x63 means more data in CAC1 */
  388|      0|			if (r == SC_SUCCESS && apdu.sw1 != 0x63)
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (388:8): [True: 0, False: 0]
  |  Branch (388:27): [True: 0, False: 0]
  ------------------
  389|      0|				continue;
  390|       |
  391|      0|			*index_out = i;
  392|      0|			return SC_SUCCESS;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  393|      0|		}
  394|    816|	}
  395|     51|	return SC_ERROR_OBJECT_NOT_FOUND;
  ------------------
  |  |   88|     51|#define SC_ERROR_OBJECT_NOT_FOUND		-1407
  ------------------
  396|     51|}
card-cac1.c:cac_select_pki_applet:
  359|    816|{
  360|    816|	sc_path_t applet_path = cac_cac_pki_obj.path;
  361|    816|	applet_path.aid.value[applet_path.aid.len-1] = index;
  362|       |	return cac_select_file_by_type(card, &applet_path, NULL);
  363|    816|}
card-cac1.c:cac_select_file_by_type:
  205|    816|{
  206|    816|	struct sc_context *ctx;
  207|    816|	struct sc_apdu apdu;
  208|    816|	unsigned char buf[SC_MAX_APDU_BUFFER_SIZE];
  209|    816|	unsigned char pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf;
  210|    816|	int r, pathtype;
  211|    816|	size_t pathlen;
  212|    816|	struct sc_file *file = NULL;
  213|    816|	cac_private_data_t *priv;
  214|       |
  215|    816|	if (card == NULL || in_path == NULL)
  ------------------
  |  Branch (215:6): [True: 0, False: 816]
  |  Branch (215:22): [True: 0, False: 816]
  ------------------
  216|      0|		return SC_ERROR_INTERNAL;
  ------------------
  |  |   81|      0|#define SC_ERROR_INTERNAL			-1400
  ------------------
  217|       |
  218|    816|	ctx = card->ctx;
  219|    816|	priv = CAC_DATA(card);
  ------------------
  |  |   61|    816|#define CAC_DATA(card) ((cac_private_data_t*)card->drv_data)
  ------------------
  220|       |
  221|    816|	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|    816|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|    816|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|    816|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 816]
  |  |  ------------------
  ------------------
  222|       |
  223|    816|	memcpy(path, in_path->value, in_path->len);
  224|    816|	pathlen = in_path->len;
  225|    816|	pathtype = in_path->type;
  226|       |
  227|    816|	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
  ------------------
  |  |   70|    816|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  228|    816|		"path=%s, path->value=%s path->type=%d (%x)",
  229|    816|		sc_print_path(in_path),
  230|    816|		sc_dump_hex(in_path->value, in_path->len),
  231|    816|		in_path->type, in_path->type);
  232|    816|	sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "file_out=%p index=%d count=%d\n",
  ------------------
  |  |   70|    816|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  233|    816|		file_out, in_path->index, in_path->count);
  234|       |
  235|       |	/* Sigh, iso7816_select_file expects paths to keys to have specific
  236|       |	 * formats. There is no override. We have to add some bytes to the
  237|       |	 * path to make it happy.
  238|       |	 * We only need to do this for private keys.
  239|       |	 */
  240|    816|	if ((pathlen > 2) && (pathlen <= 4) && memcmp(path, "\x3F\x00", 2) == 0) {
  ------------------
  |  Branch (240:6): [True: 0, False: 816]
  |  Branch (240:23): [True: 0, False: 0]
  |  Branch (240:41): [True: 0, False: 0]
  ------------------
  241|      0|		path += 2;
  242|      0|		pathlen -= 2;
  243|      0|	}
  244|       |
  245|       |
  246|       |	/* CAC has multiple different type of objects that aren't PKCS #15. When we read
  247|       |	 * them we need convert them to something PKCS #15 would understand. Find the object
  248|       |	 * and object type here:
  249|       |	 */
  250|    816|	if (priv) { /* don't record anything if we haven't been initialized yet */
  ------------------
  |  Branch (250:6): [True: 0, False: 816]
  ------------------
  251|       |		/* forget any old cached values */
  252|      0|		if (priv->cache_buf) {
  ------------------
  |  Branch (252:7): [True: 0, False: 0]
  ------------------
  253|      0|			free(priv->cache_buf);
  254|      0|			priv->cache_buf = NULL;
  255|      0|		}
  256|      0|		priv->cache_buf_len = 0;
  257|      0|		priv->cached = 0;
  258|      0|	}
  259|       |
  260|    816|	if (in_path->aid.len) {
  ------------------
  |  Branch (260:6): [True: 816, False: 0]
  ------------------
  261|    816|		if (!pathlen) {
  ------------------
  |  Branch (261:7): [True: 816, False: 0]
  ------------------
  262|    816|			memcpy(path, in_path->aid.value, in_path->aid.len);
  263|    816|			pathlen = in_path->aid.len;
  264|    816|			pathtype = SC_PATH_TYPE_DF_NAME;
  ------------------
  |  |  118|    816|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
  265|    816|		} else {
  266|       |			/* First, select the application */
  267|      0|			sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,"select application" );
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  268|      0|			sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 4, 0);
  ------------------
  |  |  293|      0|#define SC_APDU_CASE_3_SHORT		0x03
  ------------------
  269|      0|			apdu.data = in_path->aid.value;
  270|      0|			apdu.datalen = in_path->aid.len;
  271|      0|			apdu.lc = in_path->aid.len;
  272|       |
  273|      0|			r = sc_transmit_apdu(card, &apdu);
  274|      0|			LOG_TEST_RET(ctx, r, "APDU transmit failed");
  ------------------
  |  |  174|      0|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|      0|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|      0|	int _ret = (r); \
  |  |  |  |  168|      0|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  275|      0|			r = sc_check_sw(card, apdu.sw1, apdu.sw2);
  276|      0|			if (r)
  ------------------
  |  Branch (276:8): [True: 0, False: 0]
  ------------------
  277|      0|				LOG_FUNC_RETURN(ctx, r);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  278|       |
  279|      0|		}
  280|    816|	}
  281|       |
  282|    816|	sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0, 0);
  ------------------
  |  |  294|    816|#define SC_APDU_CASE_4_SHORT		0x04
  ------------------
  283|       |
  284|    816|	switch (pathtype) {
  285|       |	/* ideally we would had SC_PATH_TYPE_OBJECT_ID and add code to the iso7816 select.
  286|       |	 * Unfortunately we'd also need to update the caching code as well. For now just
  287|       |	 * use FILE_ID and change p1 here */
  288|      0|	case SC_PATH_TYPE_FILE_ID:
  ------------------
  |  |  117|      0|#define SC_PATH_TYPE_FILE_ID		0
  ------------------
  |  Branch (288:2): [True: 0, False: 816]
  ------------------
  289|      0|		apdu.p1 = 2;
  290|      0|		if (pathlen != 2)
  ------------------
  |  Branch (290:7): [True: 0, False: 0]
  ------------------
  291|      0|			return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  292|      0|		break;
  293|    816|	case SC_PATH_TYPE_DF_NAME:
  ------------------
  |  |  118|    816|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
  |  Branch (293:2): [True: 816, False: 0]
  ------------------
  294|    816|		apdu.p1 = 4;
  295|    816|		break;
  296|      0|	default:
  ------------------
  |  Branch (296:2): [True: 0, False: 816]
  ------------------
  297|      0|		LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  298|    816|	}
  299|    816|	apdu.lc = pathlen;
  300|    816|	apdu.data = path;
  301|    816|	apdu.datalen = pathlen;
  302|    816|	apdu.resp = buf;
  303|    816|	apdu.resplen = sizeof(buf);
  304|    816|	apdu.le = sc_get_max_recv_size(card) < 256 ? sc_get_max_recv_size(card) : 256;
  ------------------
  |  Branch (304:12): [True: 0, False: 816]
  ------------------
  305|    816|	apdu.p2 = 0x00;
  306|       |
  307|    816|	r = sc_transmit_apdu(card, &apdu);
  308|    816|	LOG_TEST_RET(ctx, r, "APDU transmit failed");
  ------------------
  |  |  174|    816|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|    816|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|    816|	int _ret = (r); \
  |  |  |  |  168|    816|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 816]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|    816|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 816]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  309|       |
  310|    816|	if (file_out == NULL) {
  ------------------
  |  Branch (310:6): [True: 816, False: 0]
  ------------------
  311|       |		/* For some cards 'SELECT' can be only with request to return FCI/FCP. */
  312|    816|		r = sc_check_sw(card, apdu.sw1, apdu.sw2);
  313|    816|		if (apdu.sw1 == 0x6A && apdu.sw2 == 0x86)   {
  ------------------
  |  Branch (313:7): [True: 0, False: 816]
  |  Branch (313:27): [True: 0, False: 0]
  ------------------
  314|      0|			apdu.p2 = 0x00;
  315|      0|			apdu.resplen = sizeof(buf);
  316|      0|			if (sc_transmit_apdu(card, &apdu) == SC_SUCCESS)
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (316:8): [True: 0, False: 0]
  ------------------
  317|      0|				r = sc_check_sw(card, apdu.sw1, apdu.sw2);
  318|      0|		}
  319|    816|		if (apdu.sw1 == 0x61)
  ------------------
  |  Branch (319:7): [True: 0, False: 816]
  ------------------
  320|    816|			LOG_FUNC_RETURN(ctx, SC_SUCCESS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  321|    816|		LOG_FUNC_RETURN(ctx, r);
  ------------------
  |  |  164|    816|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|    816|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|    816|	int _ret = r; \
  |  |  |  |  155|    816|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 816, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|    816|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|    816|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 816, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|    816|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|    816|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|    816|	return _ret; \
  |  |  |  |  163|    816|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  322|    816|	}
  323|       |
  324|      0|	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
  325|      0|	if (r)
  ------------------
  |  Branch (325:6): [True: 0, False: 0]
  ------------------
  326|      0|		LOG_FUNC_RETURN(ctx, r);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  327|       |
  328|       |	/* CAC cards never return FCI, fake one */
  329|      0|	file = sc_file_new();
  330|      0|	if (file == NULL)
  ------------------
  |  Branch (330:6): [True: 0, False: 0]
  ------------------
  331|      0|			LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  332|      0|	file->path = *in_path;
  333|      0|	file->size = CAC_MAX_SIZE; /* we don't know how big, just give a large size until we can read the file */
  ------------------
  |  |   26|      0|#define CAC_MAX_SIZE 4096		/* arbitrary, just needs to be 'large enough' */
  ------------------
  334|       |
  335|      0|	*file_out = file;
  336|      0|	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  337|       |
  338|      0|}

sc_get_cardos_driver:
 1570|    295|{
 1571|    295|	return sc_get_driver();
 1572|    295|}
card-cardos.c:sc_get_driver:
 1545|    295|{
 1546|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (1546:6): [True: 1, False: 294]
  ------------------
 1547|      1|		iso_ops = sc_get_iso7816_driver()->ops;
 1548|    295|	cardos_ops = *iso_ops;
 1549|    295|	cardos_ops.match_card = cardos_match_card;
 1550|    295|	cardos_ops.init = cardos_init;
 1551|    295|	cardos_ops.finish = cardos_finish;
 1552|    295|	cardos_ops.select_file = cardos_select_file;
 1553|    295|	cardos_ops.create_file = cardos_create_file;
 1554|    295|	cardos_ops.set_security_env = cardos_set_security_env;
 1555|    295|	cardos_ops.restore_security_env = cardos_restore_security_env;
 1556|    295|	cardos_ops.compute_signature = cardos_compute_signature;
 1557|    295|	cardos_ops.decipher = cardos_decipher;
 1558|       |
 1559|    295|	cardos_ops.list_files = cardos_list_files;
 1560|    295|	cardos_ops.check_sw = cardos_check_sw;
 1561|    295|	cardos_ops.card_ctl = cardos_card_ctl;
 1562|    295|	cardos_ops.pin_cmd = cardos_pin_cmd;
 1563|    295|	cardos_ops.logout  = cardos_logout;
 1564|       |
 1565|    295|	return &cardos_drv;
 1566|    295|}
card-cardos.c:cardos_match_card:
   76|     51|{
   77|     51|	unsigned char atr[SC_MAX_ATR_SIZE] = {0};
   78|     51|	int i;
   79|       |
   80|     51|	i = _sc_match_atr(card, cardos_atrs, &card->type);
   81|     51|	if (i < 0)
  ------------------
  |  Branch (81:6): [True: 51, False: 0]
  ------------------
   82|     51|		return 0;
   83|       |
   84|      0|	memcpy(atr, card->atr.value, card->atr.len);
   85|       |
   86|       |	/* Do not change card type for CIE! */
   87|      0|	if (card->type == SC_CARD_TYPE_CARDOS_CIE_V1)
  ------------------
  |  Branch (87:6): [True: 0, False: 0]
  ------------------
   88|      0|		return 1;
   89|      0|	if (card->type == SC_CARD_TYPE_CARDOS_M4_4)
  ------------------
  |  Branch (89:6): [True: 0, False: 0]
  ------------------
   90|      0|		return 1;
   91|      0|	if (card->type == SC_CARD_TYPE_CARDOS_V5_0)
  ------------------
  |  Branch (91:6): [True: 0, False: 0]
  ------------------
   92|      0|		return 1;
   93|      0|	if (card->type == SC_CARD_TYPE_CARDOS_V5_3)
  ------------------
  |  Branch (93:6): [True: 0, False: 0]
  ------------------
   94|      0|		return 1;
   95|      0|	if (card->type == SC_CARD_TYPE_CARDOS_M4_2) {
  ------------------
  |  Branch (95:6): [True: 0, False: 0]
  ------------------
   96|      0|		int rv;
   97|      0|		sc_apdu_t apdu = {0};
   98|      0|		u8 rbuf[SC_MAX_APDU_BUFFER_SIZE] = {0};
   99|       |		/* first check some additional ATR bytes */
  100|      0|		if ((atr[4] != 0xff && atr[4] != 0x02) ||
  ------------------
  |  Branch (100:8): [True: 0, False: 0]
  |  Branch (100:26): [True: 0, False: 0]
  ------------------
  101|      0|		    (atr[6] != 0x10 && atr[6] != 0x0a) ||
  ------------------
  |  Branch (101:8): [True: 0, False: 0]
  |  Branch (101:26): [True: 0, False: 0]
  ------------------
  102|      0|		    (atr[9] != 0x55 && atr[9] != 0x58))
  ------------------
  |  Branch (102:8): [True: 0, False: 0]
  |  Branch (102:26): [True: 0, False: 0]
  ------------------
  103|      0|			return 0;
  104|       |		/* get the os version using GET DATA and compare it with
  105|       |		 * version in the ATR */
  106|      0|		sc_log(card->ctx,  "checking cardos version ...");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  107|      0|		sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xca, 0x01, 0x82);
  ------------------
  |  |  292|      0|#define SC_APDU_CASE_2_SHORT		0x02
  ------------------
  108|      0|		apdu.resp = rbuf;
  109|      0|		apdu.resplen = sizeof(rbuf);
  110|      0|		apdu.le = 256;
  111|      0|		apdu.lc = 0;
  112|      0|		rv = sc_transmit_apdu(card, &apdu);
  113|      0|		LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
  ------------------
  |  |  174|      0|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|      0|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|      0|	int _ret = (r); \
  |  |  |  |  168|      0|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  114|      0|		if (apdu.sw1 != 0x90 || apdu.sw2 != 0x00 || apdu.resplen < 2)
  ------------------
  |  Branch (114:7): [True: 0, False: 0]
  |  Branch (114:27): [True: 0, False: 0]
  |  Branch (114:47): [True: 0, False: 0]
  ------------------
  115|      0|			return 0;
  116|      0|		if (apdu.resp[0] != atr[10] ||
  ------------------
  |  Branch (116:7): [True: 0, False: 0]
  ------------------
  117|      0|		    apdu.resp[1] != atr[11])
  ------------------
  |  Branch (117:7): [True: 0, False: 0]
  ------------------
  118|       |			/* version mismatch */
  119|      0|			return 0;
  120|      0|		if (atr[11] <= 0x04) {
  ------------------
  |  Branch (120:7): [True: 0, False: 0]
  ------------------
  121|      0|			sc_log(card->ctx,  "found cardos m4.01");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  122|      0|			card->type = SC_CARD_TYPE_CARDOS_M4_01;
  123|      0|		} else if (atr[11] == 0x08) {
  ------------------
  |  Branch (123:14): [True: 0, False: 0]
  ------------------
  124|      0|			sc_log(card->ctx,  "found cardos v4.3b");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  125|      0|			card->type = SC_CARD_TYPE_CARDOS_M4_3;
  126|      0|		} else if (atr[11] == 0x09) {
  ------------------
  |  Branch (126:14): [True: 0, False: 0]
  ------------------
  127|      0|			sc_log(card->ctx,  "found cardos v4.2b");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  128|      0|			card->type = SC_CARD_TYPE_CARDOS_M4_2B;
  129|      0|		} else if (atr[11] >= 0x0B) {
  ------------------
  |  Branch (129:14): [True: 0, False: 0]
  ------------------
  130|      0|			sc_log(card->ctx,  "found cardos v4.2c or higher");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  131|      0|			card->type = SC_CARD_TYPE_CARDOS_M4_2C;
  132|      0|		} else {
  133|      0|			sc_log(card->ctx,  "found cardos m4.2");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  134|      0|		}
  135|      0|	}
  136|      0|	return 1;
  137|      0|}

sc_get_coolkey_driver:
 2476|    295|{
 2477|    295|	return sc_get_driver();
 2478|    295|}
card-coolkey.c:coolkey_apdu_io:
  912|     51|{
  913|     51|	int r;
  914|     51|	sc_apdu_t apdu;
  915|     51|	u8 rbufinitbuf[COOLKEY_MAX_SIZE];
  916|     51|	u8 rsendbuf[COOLKEY_MAX_SIZE];
  917|     51|	u8 *rbuf;
  918|     51|	size_t rbuflen;
  919|     51|	int cse = 0;
  920|       |
  921|       |
  922|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
  923|       |
  924|     51|	sc_log(card->ctx,
  ------------------
  |  |   71|     51|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  925|     51|		 "%02x %02x %02x %"SC_FORMAT_LEN_SIZE_T"u : %"SC_FORMAT_LEN_SIZE_T"u %"SC_FORMAT_LEN_SIZE_T"u\n",
  926|     51|		 ins, p1, p2, sendbuflen, card->max_send_size,
  927|     51|		 card->max_recv_size);
  928|       |
  929|     51|	rbuf = rbufinitbuf;
  930|     51|	rbuflen = sizeof(rbufinitbuf);
  931|       |
  932|       |	/* if caller provided a buffer and length */
  933|     51|	if (recvbuf && *recvbuf && recvbuflen && *recvbuflen) {
  ------------------
  |  Branch (933:6): [True: 0, False: 51]
  |  Branch (933:17): [True: 0, False: 0]
  |  Branch (933:29): [True: 0, False: 0]
  |  Branch (933:43): [True: 0, False: 0]
  ------------------
  934|      0|		rbuf = *recvbuf;
  935|      0|		rbuflen = *recvbuflen;
  936|      0|	}
  937|       |
  938|     51|	if (sendbuf || nonce) {
  ------------------
  |  Branch (938:6): [True: 51, False: 0]
  |  Branch (938:17): [True: 0, False: 0]
  ------------------
  939|     51|		if (recvbuf) {
  ------------------
  |  Branch (939:7): [True: 0, False: 51]
  ------------------
  940|      0|			cse = SC_APDU_CASE_4_SHORT;
  ------------------
  |  |  294|      0|#define SC_APDU_CASE_4_SHORT		0x04
  ------------------
  941|     51|		} else {
  942|     51|			cse = SC_APDU_CASE_3_SHORT;
  ------------------
  |  |  293|     51|#define SC_APDU_CASE_3_SHORT		0x03
  ------------------
  943|     51|		}
  944|     51|	} else {
  945|      0|		if (recvbuf) {
  ------------------
  |  Branch (945:7): [True: 0, False: 0]
  ------------------
  946|      0|			cse = SC_APDU_CASE_2_SHORT;
  ------------------
  |  |  292|      0|#define SC_APDU_CASE_2_SHORT		0x02
  ------------------
  947|      0|		} else {
  948|      0|			cse = SC_APDU_CASE_1;
  ------------------
  |  |  291|      0|#define SC_APDU_CASE_1			0x01
  ------------------
  949|      0|		}
  950|      0|	}
  951|       |
  952|       |	/* append the nonce if we have it. Coolkey just blindly puts this at the end
  953|       |	 * of the APDU (while adjusting lc). This converts case 1 to case 3. coolkey
  954|       |	 * also always drops le in case 4 (which happens when proto = T0). nonces are
  955|       |	 * never used on case 2 commands, so we can simply append the nonce to the data
  956|       |	 * and we should be fine */
  957|     51|	if (nonce) {
  ------------------
  |  Branch (957:6): [True: 0, False: 51]
  ------------------
  958|      0|		u8 *buf = rsendbuf;
  959|      0|		if (sendbuf) {
  ------------------
  |  Branch (959:7): [True: 0, False: 0]
  ------------------
  960|      0|			sendbuflen = MIN(sendbuflen,sizeof(rsendbuf)-nonce_len);
  ------------------
  |  |   70|      0|#define MIN(x, y) (((x) < (y)) ? (x) : (y))
  |  |  ------------------
  |  |  |  Branch (70:20): [True: 0, False: 0]
  |  |  ------------------
  ------------------
  961|      0|			memcpy(rsendbuf, sendbuf, sendbuflen);
  962|      0|			buf += sendbuflen;
  963|      0|		}
  964|      0|		memcpy(buf, nonce, nonce_len);
  965|      0|		sendbuflen += nonce_len;
  966|      0|		sendbuf =rsendbuf;
  967|      0|	}
  968|       |
  969|     51|	sc_format_apdu(card, &apdu, cse, ins, p1, p2);
  970|       |
  971|     51|	apdu.lc = sendbuflen;
  972|     51|	apdu.datalen = sendbuflen;
  973|     51|	apdu.data = sendbuf;
  974|       |
  975|       |
  976|       |	/* coolkey uses non-standard classes */
  977|     51|	apdu.cla = cla;
  978|       |
  979|     51|	if (recvbuf) {
  ------------------
  |  Branch (979:6): [True: 0, False: 51]
  ------------------
  980|      0|		apdu.resp = rbuf;
  981|      0|		apdu.le = (rbuflen > 255) ? 255 : rbuflen;
  ------------------
  |  Branch (981:13): [True: 0, False: 0]
  ------------------
  982|      0|		apdu.resplen = rbuflen;
  983|     51|	} else {
  984|     51|		 apdu.resp =  rbuf;
  985|     51|		 apdu.le = 0;
  986|     51|		 apdu.resplen = 0;
  987|     51|	}
  988|       |
  989|     51|	sc_log(card->ctx,
  ------------------
  |  |   71|     51|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  990|     51|		 "calling sc_transmit_apdu flags=%lx le=%"SC_FORMAT_LEN_SIZE_T"u, resplen=%"SC_FORMAT_LEN_SIZE_T"u, resp=%p",
  991|     51|		 apdu.flags, apdu.le, apdu.resplen, apdu.resp);
  992|       |
  993|       |	/* with new adpu.c and chaining, this actually reads the whole object */
  994|     51|	r = sc_transmit_apdu(card, &apdu);
  995|       |
  996|     51|	sc_log(card->ctx,
  ------------------
  |  |   71|     51|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  997|     51|		 "result r=%d apdu.resplen=%"SC_FORMAT_LEN_SIZE_T"u sw1=%02x sw2=%02x",
  998|     51|		 r, apdu.resplen, apdu.sw1, apdu.sw2);
  999|       |
 1000|     51|	if (r < 0) {
  ------------------
  |  Branch (1000:6): [True: 0, False: 51]
  ------------------
 1001|      0|		sc_log(card->ctx, "Transmit failed");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1002|      0|		goto err;
 1003|      0|	}
 1004|     51|	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
 1005|     51|	if (r < 0) {
  ------------------
  |  Branch (1005:6): [True: 51, False: 0]
  ------------------
 1006|     51|		sc_log(card->ctx, "Transmit failed");
  ------------------
  |  |   71|     51|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1007|     51|		goto err;
 1008|     51|	}
 1009|       |
 1010|      0|	if (recvbuflen) {
  ------------------
  |  Branch (1010:6): [True: 0, False: 0]
  ------------------
 1011|      0|		if (recvbuf && *recvbuf == NULL) {
  ------------------
  |  Branch (1011:7): [True: 0, False: 0]
  |  Branch (1011:18): [True: 0, False: 0]
  ------------------
 1012|      0|			*recvbuf =  malloc(apdu.resplen);
 1013|      0|			if (*recvbuf == NULL) {
  ------------------
  |  Branch (1013:8): [True: 0, False: 0]
  ------------------
 1014|      0|				r = SC_ERROR_OUT_OF_MEMORY;
  ------------------
  |  |   85|      0|#define SC_ERROR_OUT_OF_MEMORY			-1404
  ------------------
 1015|      0|				goto err;
 1016|      0|			}
 1017|      0|			memcpy(*recvbuf, rbuf, apdu.resplen);
 1018|      0|		}
 1019|      0|		*recvbuflen =  apdu.resplen;
 1020|      0|		r = (int)*recvbuflen;
 1021|      0|	}
 1022|       |
 1023|     51|err:
 1024|     51|	LOG_FUNC_RETURN(card->ctx, r);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|     51|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1025|     51|}
card-coolkey.c:sc_get_driver:
 2449|    295|{
 2450|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 2451|       |
 2452|    295|	coolkey_ops = *iso_drv->ops;
 2453|    295|	coolkey_ops.match_card = coolkey_match_card;
 2454|    295|	coolkey_ops.init = coolkey_init;
 2455|    295|	coolkey_ops.finish = coolkey_finish;
 2456|       |
 2457|    295|	coolkey_ops.select_file =  coolkey_select_file; /* need to record object type */
 2458|    295|	coolkey_ops.get_challenge = coolkey_get_challenge;
 2459|    295|	coolkey_ops.read_binary = coolkey_read_binary;
 2460|    295|	coolkey_ops.write_binary = coolkey_write_binary;
 2461|    295|	coolkey_ops.set_security_env = coolkey_set_security_env;
 2462|    295|	coolkey_ops.restore_security_env = coolkey_restore_security_env;
 2463|    295|	coolkey_ops.compute_signature = coolkey_compute_crypt;
 2464|    295|	coolkey_ops.decipher =  coolkey_compute_crypt;
 2465|    295|	coolkey_ops.card_ctl = coolkey_card_ctl;
 2466|    295|	coolkey_ops.check_sw = coolkey_check_sw;
 2467|    295|	coolkey_ops.pin_cmd = coolkey_pin_cmd;
 2468|    295|	coolkey_ops.logout = coolkey_logout;
 2469|    295|	coolkey_ops.card_reader_lock_obtained = coolkey_card_reader_lock_obtained;
 2470|       |
 2471|    295|	return &coolkey_drv;
 2472|    295|}
card-coolkey.c:coolkey_match_card:
 2288|     51|{
 2289|     51|	int r;
 2290|       |
 2291|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
 2292|       |
 2293|     51|	r = coolkey_select_applet(card);
 2294|     51|	if (r == SC_SUCCESS) {
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  |  Branch (2294:6): [True: 0, False: 51]
  ------------------
 2295|      0|		sc_apdu_t apdu;
 2296|       |
 2297|       |		/* The GET STATUS INS with P1 = 1 returns invalid instruction (0x6D00)
 2298|       |		 * on Coolkey applet (reserved for GetMemory function),
 2299|       |		 * while incorrect P1 (0x9C10) on Muscle applets
 2300|       |		 */
 2301|      0|		sc_format_apdu(card, &apdu, SC_APDU_CASE_1, COOLKEY_INS_GET_STATUS, 0x01, 0x00);
  ------------------
  |  |  291|      0|#define SC_APDU_CASE_1			0x01
  ------------------
              		sc_format_apdu(card, &apdu, SC_APDU_CASE_1, COOLKEY_INS_GET_STATUS, 0x01, 0x00);
  ------------------
  |  |   79|      0|#define COOLKEY_INS_GET_STATUS                 0x3c
  ------------------
 2302|      0|		apdu.cla = COOLKEY_CLASS;
  ------------------
  |  |   72|      0|#define COOLKEY_CLASS           0xb0
  ------------------
 2303|      0|		apdu.le = 0x00;
 2304|      0|		apdu.resplen = 0;
 2305|      0|		apdu.resp = NULL;
 2306|      0|		r = sc_transmit_apdu(card, &apdu);
 2307|      0|		if (r == SC_SUCCESS && apdu.sw1 == 0x6d && apdu.sw2 == 0x00) {
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (2307:7): [True: 0, False: 0]
  |  Branch (2307:26): [True: 0, False: 0]
  |  Branch (2307:46): [True: 0, False: 0]
  ------------------
 2308|      0|			return 1;
 2309|      0|		}
 2310|      0|		return 0;
 2311|      0|	}
 2312|     51|	return 0;
 2313|     51|}
card-coolkey.c:coolkey_select_applet:
 1074|     51|{
 1075|     51|	u8 aid[] = { 0x62, 0x76, 0x01, 0xff, 0x00, 0x00, 0x00 };
 1076|     51|	return coolkey_apdu_io(card, ISO7816_CLASS, ISO7816_INS_SELECT_FILE, 4, 0,
  ------------------
  |  |   71|     51|#define ISO7816_CLASS           0x00
  ------------------
              	return coolkey_apdu_io(card, ISO7816_CLASS, ISO7816_INS_SELECT_FILE, 4, 0,
  ------------------
  |  |   75|     51|#define ISO7816_INS_SELECT_FILE 0xa4
  ------------------
 1077|     51|			&aid[0], sizeof(aid), NULL, NULL,  NULL, 0);
 1078|     51|}
card-coolkey.c:coolkey_check_sw:
  876|     51|{
  877|     51|	sc_log(card->ctx,
  ------------------
  |  |   71|     51|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  878|     51|		"sw1 = 0x%02x, sw2 = 0x%02x\n", sw1, sw2);
  879|       |
  880|     51|	if (sw1 == 0x90 && sw2 == 0x00)
  ------------------
  |  Branch (880:6): [True: 0, False: 51]
  |  Branch (880:21): [True: 0, False: 0]
  ------------------
  881|      0|		return SC_SUCCESS;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  882|       |
  883|     51|	if (sw1 == 0x9c) {
  ------------------
  |  Branch (883:6): [True: 0, False: 51]
  ------------------
  884|      0|		if (sw2 == 0xff) {
  ------------------
  |  Branch (884:7): [True: 0, False: 0]
  ------------------
  885|       |			/* shouldn't happen on a production applet, 0x9cff is a debugging error code */
  886|      0|			return SC_ERROR_INTERNAL;
  ------------------
  |  |   81|      0|#define SC_ERROR_INTERNAL			-1400
  ------------------
  887|      0|		}
  888|      0|		if (sw2 >= coolkey_number_of_error_codes) {
  ------------------
  |  Branch (888:7): [True: 0, False: 0]
  ------------------
  889|      0|			return SC_ERROR_UNKNOWN;
  ------------------
  |  |  130|      0|#define SC_ERROR_UNKNOWN			-1900
  ------------------
  890|      0|		}
  891|      0|		return coolkey_error_codes[sw2].sc_error;
  892|      0|	}
  893|       |
  894|       |	/* iso error */
  895|     51|        return sc_get_iso7816_driver()->ops->check_sw(card, sw1, sw2);
  896|     51|}
card-coolkey.c:coolkey_card_reader_lock_obtained:
 2427|     51|{
 2428|     51|	int r = SC_SUCCESS;
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
 2429|       |
 2430|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
 2431|       |
 2432|     51|	if (was_reset > 0) {
  ------------------
  |  Branch (2432:6): [True: 0, False: 51]
  ------------------
 2433|      0|		r = coolkey_select_applet(card);
 2434|      0|	}
 2435|       |
 2436|     51|	LOG_FUNC_RETURN(card->ctx, r);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2437|     51|}

sc_get_default_driver:
   67|    295|{
   68|    295|	return sc_get_driver();
   69|    295|}
card-default.c:sc_get_driver:
   56|    295|{
   57|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
   58|       |
   59|    295|	default_ops = *iso_drv->ops;
   60|    295|	default_ops.match_card = default_match_card;
   61|    295|	default_ops.init = default_init;
   62|       |
   63|    295|	return &default_drv;
   64|    295|}

dnie_match_card:
  738|     51|{
  739|     51|	int result = 0;
  740|     51|	int matched = -1;
  741|     51|	LOG_FUNC_CALLED(card->ctx);
  ------------------
  |  |  151|     51|#define LOG_FUNC_CALLED(ctx) SC_FUNC_CALLED((ctx), SC_LOG_DEBUG_NORMAL)
  |  |  ------------------
  |  |  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  150|     51|} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  742|     51|	matched = _sc_match_atr(card, dnie_atrs, &card->type);
  743|     51|	result = (matched >= 0) ? 1 : 0;
  ------------------
  |  Branch (743:11): [True: 0, False: 51]
  ------------------
  744|     51|	LOG_FUNC_RETURN(card->ctx, result);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  745|     51|}
sc_get_dnie_driver:
 2305|    295|{
 2306|    295|	return get_dnie_driver();
 2307|    295|}
card-dnie.c:get_dnie_driver:
 2242|    295|{
 2243|    295|	sc_card_driver_t *iso_drv = sc_get_iso7816_driver();
 2244|       |
 2245|       |	/* memcpy() from standard iso7816 declared operations */
 2246|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (2246:6): [True: 1, False: 294]
  ------------------
 2247|      1|		iso_ops = iso_drv->ops;
 2248|    295|	dnie_ops = *iso_drv->ops;
 2249|       |
 2250|       |	/* fill card specific function pointers */
 2251|       |	/* NULL means that function is not supported neither by DNIe nor iso7816.c */
 2252|       |	/* if pointer is omitted, default ISO7816 function will be used */
 2253|       |
 2254|       |	/* initialization */
 2255|    295|	dnie_ops.match_card	= dnie_match_card;
 2256|    295|	dnie_ops.init		= dnie_init;
 2257|    295|	dnie_ops.finish		= dnie_finish;
 2258|       |
 2259|       |	/* iso7816-4 functions */
 2260|    295|	dnie_ops.read_binary	= dnie_read_binary;
 2261|    295|	dnie_ops.write_binary	= NULL;
 2262|    295|	dnie_ops.update_binary	= NULL;
 2263|    295|	dnie_ops.erase_binary	= NULL;
 2264|    295|	dnie_ops.read_record	= NULL;
 2265|    295|	dnie_ops.write_record	= NULL;
 2266|    295|	dnie_ops.append_record	= NULL;
 2267|    295|	dnie_ops.update_record	= NULL;
 2268|    295|	dnie_ops.select_file	= dnie_select_file;
 2269|    295|	dnie_ops.get_challenge	= dnie_get_challenge;
 2270|       |
 2271|       |	/* iso7816-8 functions */
 2272|    295|	dnie_ops.verify		= NULL;
 2273|    295|	dnie_ops.logout		= dnie_logout;
 2274|       |	/* dnie_ops.restore_security_env */
 2275|    295|	dnie_ops.set_security_env = dnie_set_security_env;
 2276|    295|	dnie_ops.decipher	= dnie_decipher;
 2277|    295|	dnie_ops.compute_signature = dnie_compute_signature;
 2278|    295|	dnie_ops.change_reference_data = NULL;
 2279|    295|	dnie_ops.reset_retry_counter = NULL;
 2280|       |
 2281|       |	/* iso7816-9 functions */
 2282|    295|	dnie_ops.create_file	= NULL;
 2283|    295|	dnie_ops.delete_file	= NULL;
 2284|    295|	dnie_ops.list_files	= dnie_list_files;
 2285|    295|	dnie_ops.check_sw	= dnie_check_sw;
 2286|    295|	dnie_ops.card_ctl	= dnie_card_ctl;
 2287|    295|	dnie_ops.process_fci	= dnie_process_fci;
 2288|       |	/* dnie_ops.construct_fci */
 2289|    295|	dnie_ops.pin_cmd	= dnie_pin_cmd;
 2290|    295|	dnie_ops.get_data	= NULL;
 2291|    295|	dnie_ops.put_data	= NULL;
 2292|    295|	dnie_ops.delete_record	= NULL;
 2293|       |
 2294|    295|	return &dnie_driver;
 2295|    295|}

sc_get_dtrust_driver:
 1056|    295|{
 1057|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (1057:6): [True: 1, False: 294]
  ------------------
 1058|      1|		iso_ops = sc_get_iso7816_driver()->ops;
 1059|       |
 1060|    295|	dtrust_ops = *iso_ops;
 1061|    295|	dtrust_ops.match_card = dtrust_match_card;
 1062|    295|	dtrust_ops.init = dtrust_init;
 1063|    295|	dtrust_ops.finish = dtrust_finish;
 1064|    295|	dtrust_ops.pin_cmd = dtrust_pin_cmd;
 1065|    295|	dtrust_ops.set_security_env = dtrust_set_security_env;
 1066|    295|	dtrust_ops.compute_signature = dtrust_compute_signature;
 1067|    295|	dtrust_ops.decipher = dtrust_decipher;
 1068|    295|	dtrust_ops.logout = dtrust_logout;
 1069|       |
 1070|    295|	return &dtrust_drv;
 1071|    295|}
card-dtrust.c:dtrust_match_card:
  234|     51|{
  235|     51|	if (_sc_match_atr(card, dtrust_atrs, &card->type) < 0)
  ------------------
  |  Branch (235:6): [True: 51, False: 0]
  ------------------
  236|     51|		return 0;
  237|       |
  238|      0|	if (_dtrust_match_cardos(card) != SC_SUCCESS)
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (238:6): [True: 0, False: 0]
  ------------------
  239|      0|		return 0;
  240|       |
  241|      0|	if (_dtrust_match_profile(card) != SC_SUCCESS)
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (241:6): [True: 0, False: 0]
  ------------------
  242|      0|		return 0;
  243|       |
  244|      0|	sc_log(card->ctx, "D-Trust Signature Card");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  245|       |
  246|      0|	return 1;
  247|      0|}

sc_get_edo_driver:
  306|    295|struct sc_card_driver* sc_get_edo_driver(void) {
  307|    295|	edo_ops = *sc_get_iso7816_driver()->ops;
  308|    295|	edo_ops.match_card = edo_match_card;
  309|    295|	edo_ops.init = edo_init;
  310|    295|	edo_ops.select_file = edo_select_file;
  311|    295|	edo_ops.set_security_env = edo_set_security_env;
  312|    295|	edo_ops.compute_signature = edo_compute_signature;
  313|    295|	edo_ops.logout = edo_logout;
  314|       |
  315|    295|	return &edo_drv;
  316|    295|}
card-edo.c:edo_match_card:
   62|     51|static int edo_match_card(sc_card_t* card) {
   63|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
   64|     51|	if (_sc_match_atr(card, edo_atrs, &card->type) >= 0) {
  ------------------
  |  Branch (64:6): [True: 0, False: 51]
  ------------------
   65|      0|		sc_log(card->ctx, "ATR recognized as Polish eID card.");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
   66|      0|		LOG_FUNC_RETURN(card->ctx, 1);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   67|      0|	}
   68|     51|	LOG_FUNC_RETURN(card->ctx, 0);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   69|     51|}

sc_get_entersafe_driver:
 1579|    295|{
 1580|    295|	return sc_get_driver();
 1581|    295|}
card-entersafe.c:sc_get_driver:
 1553|    295|{
 1554|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 1555|       |
 1556|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (1556:6): [True: 1, False: 294]
  ------------------
 1557|      1|		iso_ops = iso_drv->ops;
 1558|       |
 1559|    295|	entersafe_ops = *iso_drv->ops;
 1560|    295|	entersafe_ops.match_card = entersafe_match_card;
 1561|    295|	entersafe_ops.init = entersafe_init;
 1562|    295|	entersafe_ops.read_binary = entersafe_read_binary;
 1563|    295|	entersafe_ops.write_binary = NULL;
 1564|    295|	entersafe_ops.update_binary = entersafe_update_binary;
 1565|    295|	entersafe_ops.select_file = entersafe_select_file;
 1566|    295|	entersafe_ops.restore_security_env = entersafe_restore_security_env;
 1567|    295|	entersafe_ops.set_security_env = entersafe_set_security_env;
 1568|    295|	entersafe_ops.decipher = entersafe_decipher;
 1569|    295|	entersafe_ops.compute_signature = entersafe_compute_signature;
 1570|    295|	entersafe_ops.create_file = entersafe_create_file;
 1571|       |	entersafe_ops.delete_file = NULL;
 1572|    295|	entersafe_ops.pin_cmd = entersafe_pin_cmd;
 1573|    295|	entersafe_ops.card_ctl = entersafe_card_ctl_2048;
 1574|    295|	entersafe_ops.process_fci = entersafe_process_fci;
 1575|    295|	return &entersafe_drv;
 1576|    295|}
card-entersafe.c:entersafe_match_card:
  135|     51|{
  136|     51|	int i;
  137|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
  138|       |
  139|     51|	i = _sc_match_atr(card, entersafe_atrs, &card->type);
  140|     51|	if (i < 0)
  ------------------
  |  Branch (140:6): [True: 51, False: 0]
  ------------------
  141|     51|		return 0;
  142|       |
  143|      0|	return 1;
  144|     51|}

sc_get_eoi_driver:
  566|    295|{
  567|    295|	eoi_ops = *sc_get_iso7816_driver()->ops;
  568|       |
  569|    295|	eoi_ops.match_card = eoi_match_card;
  570|    295|	eoi_ops.init = eoi_init;
  571|    295|	eoi_ops.finish = eoi_finish;
  572|    295|	eoi_ops.select_file = eoi_select_file;
  573|    295|	eoi_ops.logout = eoi_logout;
  574|    295|	eoi_ops.pin_cmd = eoi_pin_cmd;
  575|    295|	eoi_ops.card_ctl = eoi_card_ctl;
  576|    295|	eoi_ops.set_security_env = eoi_set_security_env;
  577|    295|	eoi_ops.compute_signature = eoi_compute_signature;
  578|       |
  579|    295|	return &eoi_drv;
  580|    295|}
card-eoi.c:eoi_match_card:
  236|     51|static int eoi_match_card(sc_card_t* card) {
  237|     51|	LOG_FUNC_CALLED(card->ctx);
  ------------------
  |  |  151|     51|#define LOG_FUNC_CALLED(ctx) SC_FUNC_CALLED((ctx), SC_LOG_DEBUG_NORMAL)
  |  |  ------------------
  |  |  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  150|     51|} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  238|     51|	if (_sc_match_atr(card, eoi_atrs, &card->type) >= 0) {
  ------------------
  |  Branch (238:6): [True: 0, False: 51]
  ------------------
  239|      0|		sc_log(card->ctx, "ATR recognized as Slovenian eID card");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  240|      0|		LOG_FUNC_RETURN(card->ctx, ATR_MATCH);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  241|      0|	}
  242|     51|	LOG_FUNC_RETURN(card->ctx, !ATR_MATCH);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  243|     51|}

sc_get_epass2003_driver:
 3314|    295|{
 3315|    295|	return sc_get_driver();
 3316|    295|}
card-epass2003.c:sc_get_driver:
 3281|    295|{
 3282|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 3283|       |
 3284|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (3284:6): [True: 1, False: 294]
  ------------------
 3285|      1|		iso_ops = iso_drv->ops;
 3286|       |
 3287|    295|	epass2003_ops = *iso_ops;
 3288|       |
 3289|    295|	epass2003_ops.match_card = epass2003_match_card;
 3290|    295|	epass2003_ops.init = epass2003_init;
 3291|    295|	epass2003_ops.finish = epass2003_finish;
 3292|    295|	epass2003_ops.write_binary = NULL;
 3293|    295|	epass2003_ops.write_record = NULL;
 3294|    295|	epass2003_ops.select_file = epass2003_select_file;
 3295|       |	epass2003_ops.get_response = NULL;
 3296|    295|	epass2003_ops.restore_security_env = epass2003_restore_security_env;
 3297|    295|	epass2003_ops.set_security_env = epass2003_set_security_env;
 3298|    295|	epass2003_ops.decipher = epass2003_decipher;
 3299|    295|	epass2003_ops.compute_signature = epass2003_decipher;
 3300|    295|	epass2003_ops.create_file = epass2003_create_file;
 3301|    295|	epass2003_ops.delete_file = epass2003_delete_file;
 3302|    295|	epass2003_ops.list_files = epass2003_list_files;
 3303|    295|	epass2003_ops.card_ctl = epass2003_card_ctl;
 3304|    295|	epass2003_ops.process_fci = epass2003_process_fci;
 3305|    295|	epass2003_ops.construct_fci = epass2003_construct_fci;
 3306|    295|	epass2003_ops.pin_cmd = epass2003_pin_cmd;
 3307|    295|	epass2003_ops.check_sw = epass2003_check_sw;
 3308|    295|	epass2003_ops.get_challenge = epass2003_get_challenge;
 3309|    295|	epass2003_ops.logout = epass2003_logout;
 3310|    295|	return &epass2003_drv;
 3311|    295|}
card-epass2003.c:epass2003_match_card:
 1689|     51|{
 1690|     51|	int r;
 1691|       |
 1692|     51|	LOG_FUNC_CALLED(card->ctx);
  ------------------
  |  |  151|     51|#define LOG_FUNC_CALLED(ctx) SC_FUNC_CALLED((ctx), SC_LOG_DEBUG_NORMAL)
  |  |  ------------------
  |  |  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  150|     51|} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1693|     51|	r = _sc_match_atr(card, epass2003_atrs, &card->type);
 1694|     51|	if (r < 0)
  ------------------
  |  Branch (1694:6): [True: 51, False: 0]
  ------------------
 1695|     51|		return 0;
 1696|       |
 1697|      0|	return 1;
 1698|     51|}

sc_get_esteid2018_driver:
  303|    295|struct sc_card_driver *sc_get_esteid2018_driver(void) {
  304|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
  305|       |
  306|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (306:6): [True: 1, False: 294]
  ------------------
  307|      1|		iso_ops = iso_drv->ops;
  308|       |
  309|    295|	esteid_ops = *iso_drv->ops;
  310|    295|	esteid_ops.match_card = esteid_match_card;
  311|    295|	esteid_ops.init = esteid_init;
  312|    295|	esteid_ops.finish = esteid_finish;
  313|       |
  314|    295|	esteid_ops.select_file = esteid_select_file;
  315|       |
  316|    295|	esteid_ops.set_security_env = esteid_set_security_env;
  317|    295|	esteid_ops.compute_signature = esteid_compute_signature;
  318|    295|	esteid_ops.pin_cmd = esteid_pin_cmd;
  319|    295|	esteid_ops.logout = esteid_logout;
  320|       |
  321|    295|	return &esteid2018_driver;
  322|    295|}
card-esteid2018.c:esteid_match_card:
   83|     51|static int esteid_match_card(sc_card_t *card) {
   84|     51|	int i = _sc_match_atr(card, esteid_atrs, &card->type);
   85|       |
   86|     51|	if (i >= 0 && gp_select_aid(card, &IASECC_AID) == SC_SUCCESS) {
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (86:6): [True: 0, False: 51]
  |  Branch (86:16): [True: 0, False: 0]
  ------------------
   87|      0|		card->name = esteid_atrs[i].name;
   88|      0|		return 1;
   89|      0|	}
   90|     51|	return 0;
   91|     51|}

sc_get_esteid2025_driver:
  220|    295|{
  221|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
  222|       |
  223|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (223:6): [True: 1, False: 294]
  ------------------
  224|      1|		iso_ops = iso_drv->ops;
  225|       |
  226|    295|	esteid_ops = *iso_drv->ops;
  227|    295|	esteid_ops.match_card = esteid_match_card;
  228|    295|	esteid_ops.init = esteid_init;
  229|       |
  230|    295|	esteid_ops.select_file = esteid_select_file;
  231|       |
  232|    295|	esteid_ops.set_security_env = esteid_set_security_env;
  233|    295|	esteid_ops.compute_signature = esteid_compute_signature;
  234|    295|	esteid_ops.pin_cmd = esteid_pin_cmd;
  235|    295|	esteid_ops.logout = esteid_logout;
  236|       |
  237|    295|	return &esteid2025_driver;
  238|    295|}
card-esteid2025.c:esteid_match_card:
   65|     51|{
   66|     51|	int i = _sc_match_atr(card, esteid_atrs, &card->type);
   67|       |
   68|     51|	if (i >= 0 && gp_select_aid(card, &THALES_AID) == SC_SUCCESS) {
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (68:6): [True: 0, False: 51]
  |  Branch (68:16): [True: 0, False: 0]
  ------------------
   69|      0|		card->name = esteid_atrs[i].name;
   70|      0|		return 1;
   71|      0|	}
   72|     51|	return 0;
   73|     51|}

sc_get_cryptoflex_driver:
 1216|    295|{
 1217|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (1217:6): [True: 0, False: 295]
  ------------------
 1218|      0|		iso_ops = sc_get_iso7816_driver()->ops;
 1219|       |
 1220|    295|	cryptoflex_ops = *iso_ops;
 1221|    295|	cryptoflex_ops.match_card = cryptoflex_match_card;
 1222|    295|	cryptoflex_ops.init = flex_init;
 1223|    295|	cryptoflex_ops.finish = flex_finish;
 1224|    295|	cryptoflex_ops.process_fci = cryptoflex_process_file_attrs;
 1225|    295|	cryptoflex_ops.construct_fci = cryptoflex_construct_file_attrs;
 1226|    295|	cryptoflex_ops.select_file = flex_select_file;
 1227|    295|	cryptoflex_ops.list_files = cryptoflex_list_files;
 1228|    295|	cryptoflex_ops.delete_file = flex_delete_file;
 1229|    295|	cryptoflex_ops.create_file = flex_create_file;
 1230|    295|	cryptoflex_ops.card_ctl = flex_card_ctl;
 1231|    295|	cryptoflex_ops.set_security_env = flex_set_security_env;
 1232|    295|	cryptoflex_ops.restore_security_env = flex_restore_security_env;
 1233|    295|	cryptoflex_ops.compute_signature = cryptoflex_compute_signature;
 1234|    295|	cryptoflex_ops.decipher = flex_decipher;
 1235|    295|	cryptoflex_ops.pin_cmd = flex_pin_cmd;
 1236|    295|	cryptoflex_ops.logout = flex_logout;
 1237|    295|	return &cryptoflex_drv;
 1238|    295|}
sc_get_cyberflex_driver:
 1241|    295|{
 1242|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (1242:6): [True: 1, False: 294]
  ------------------
 1243|      1|		iso_ops = sc_get_iso7816_driver()->ops;
 1244|       |
 1245|    295|	cyberflex_ops = *iso_ops;
 1246|    295|	cyberflex_ops.match_card = cyberflex_match_card;
 1247|    295|	cyberflex_ops.init = flex_init;
 1248|    295|	cyberflex_ops.finish = flex_finish;
 1249|    295|	cyberflex_ops.process_fci = cyberflex_process_file_attrs;
 1250|    295|	cyberflex_ops.construct_fci = cyberflex_construct_file_attrs;
 1251|    295|	cyberflex_ops.select_file = flex_select_file;
 1252|    295|	cyberflex_ops.list_files = cyberflex_list_files;
 1253|    295|	cyberflex_ops.delete_file = flex_delete_file;
 1254|    295|	cyberflex_ops.create_file = flex_create_file;
 1255|    295|	cyberflex_ops.card_ctl = flex_card_ctl;
 1256|    295|	cyberflex_ops.set_security_env = flex_set_security_env;
 1257|    295|	cyberflex_ops.restore_security_env = flex_restore_security_env;
 1258|    295|	cyberflex_ops.compute_signature = cyberflex_compute_signature;
 1259|    295|	cyberflex_ops.decipher = flex_decipher;
 1260|    295|	cyberflex_ops.pin_cmd = flex_pin_cmd;
 1261|    295|	cyberflex_ops.logout = flex_logout;
 1262|    295|	return &cyberflex_drv;
 1263|    295|}
card-flex.c:cryptoflex_match_card:
  134|     51|{
  135|     51|	int i;
  136|       |
  137|     51|	i = _sc_match_atr(card, flex_atrs, NULL);
  138|     51|	if (i < 0)
  ------------------
  |  Branch (138:6): [True: 51, False: 0]
  ------------------
  139|     51|		return 0;
  140|      0|	switch (flex_atrs[i].type) {
  ------------------
  |  Branch (140:10): [True: 0, False: 0]
  ------------------
  141|      0|	case SC_CARD_TYPE_FLEX_CRYPTO:
  ------------------
  |  Branch (141:2): [True: 0, False: 0]
  ------------------
  142|      0|	case SC_CARD_TYPE_FLEX_MULTI:
  ------------------
  |  Branch (142:2): [True: 0, False: 0]
  ------------------
  143|      0|		card->name = flex_atrs[i].name;
  144|      0|		card->type = flex_atrs[i].type;
  145|      0|		card->flags = flex_atrs[i].flags;
  146|      0|		return 1;
  147|      0|	}
  148|      0|	return 0;
  149|      0|}
card-flex.c:cyberflex_match_card:
  152|     51|{
  153|     51|	int i;
  154|       |
  155|     51|	i = _sc_match_atr(card, flex_atrs, NULL);
  156|     51|	if (i < 0)
  ------------------
  |  Branch (156:6): [True: 51, False: 0]
  ------------------
  157|     51|		return 0;
  158|      0|	switch (flex_atrs[i].type) {
  ------------------
  |  Branch (158:10): [True: 0, False: 0]
  ------------------
  159|      0|	case SC_CARD_TYPE_FLEX_CYBER:
  ------------------
  |  Branch (159:2): [True: 0, False: 0]
  ------------------
  160|      0|		card->name = flex_atrs[i].name;
  161|      0|		card->type = flex_atrs[i].type;
  162|      0|		card->flags = flex_atrs[i].flags;
  163|      0|		return 1;
  164|      0|	}
  165|      0|	return 0;
  166|      0|}

sc_get_gemsafeV1_driver:
  593|    295|{
  594|    295|	return sc_get_driver();
  595|    295|}
card-gemsafeV1.c:sc_get_driver:
  568|    295|{
  569|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
  570|    295|	if (!iso_ops)
  ------------------
  |  Branch (570:6): [True: 1, False: 294]
  ------------------
  571|      1|		iso_ops = iso_drv->ops;
  572|       |	/* use the standard iso operations as default */
  573|    295|	gemsafe_ops = *iso_drv->ops;
  574|       |	/* gemsafe specific functions */
  575|    295|	gemsafe_ops.match_card	= gemsafe_match_card;
  576|    295|	gemsafe_ops.init	= gemsafe_init;
  577|    295|	gemsafe_ops.finish	= gemsafe_finish;
  578|    295|	gemsafe_ops.select_file	= gemsafe_select_file;
  579|    295|	gemsafe_ops.restore_security_env = gemsafe_restore_security_env;
  580|    295|	gemsafe_ops.set_security_env     = gemsafe_set_security_env;
  581|    295|	gemsafe_ops.decipher             = gemsafe_decipher;
  582|    295|	gemsafe_ops.compute_signature    = gemsafe_compute_signature;
  583|    295|	gemsafe_ops.get_challenge 		 = gemsafe_get_challenge;
  584|    295|	gemsafe_ops.process_fci	= gemsafe_process_fci;
  585|    295|	gemsafe_ops.pin_cmd		 = iso_ops->pin_cmd;
  586|    295|	gemsafe_ops.card_reader_lock_obtained = gemsafe_card_reader_lock_obtained;
  587|    295|	gemsafe_ops.logout = gemsafe_logout;
  588|       |
  589|    295|	return &gemsafe_drv;
  590|    295|}
card-gemsafeV1.c:gemsafe_match_card:
  124|     51|{
  125|     51|	int i;
  126|       |
  127|     51|	i = _sc_match_atr(card, gemsafe_atrs, &card->type);
  128|     51|	if (i < 0)
  ------------------
  |  Branch (128:6): [True: 51, False: 0]
  ------------------
  129|     51|		return 0;
  130|       |
  131|      0|	return 1;
  132|     51|}

sc_get_gids_driver:
 2196|    295|{
 2197|    295|	return sc_get_driver();
 2198|    295|}
card-gids.c:sc_get_driver:
 2151|    295|{
 2152|       |
 2153|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (2153:6): [True: 1, False: 294]
  ------------------
 2154|      1|		iso_ops = sc_get_iso7816_driver()->ops;
 2155|       |
 2156|    295|	gids_ops.match_card = gids_match_card;
 2157|    295|	gids_ops.init = gids_init;
 2158|    295|	gids_ops.finish = gids_finish;
 2159|    295|	gids_ops.read_binary = gids_read_binary;
 2160|    295|	gids_ops.write_binary = NULL;
 2161|    295|	gids_ops.update_binary = NULL;
 2162|    295|	gids_ops.erase_binary = NULL;
 2163|    295|	gids_ops.read_record = NULL;
 2164|    295|	gids_ops.write_record = NULL;
 2165|    295|	gids_ops.append_record = NULL;
 2166|    295|	gids_ops.update_record = NULL;
 2167|    295|	gids_ops.select_file = gids_select_file;
 2168|    295|	gids_ops.get_response = iso_ops->get_response;
 2169|    295|	gids_ops.get_challenge = NULL;
 2170|    295|	gids_ops.verify = NULL; // see pin_cmd
 2171|    295|	gids_ops.logout = gids_logout;
 2172|    295|	gids_ops.restore_security_env = NULL;
 2173|    295|	gids_ops.set_security_env = gids_set_security_env;
 2174|    295|	gids_ops.decipher = gids_decipher;
 2175|    295|	gids_ops.compute_signature = iso_ops->compute_signature;
 2176|    295|	gids_ops.change_reference_data = NULL; // see pin_cmd
 2177|    295|	gids_ops.reset_retry_counter = NULL; // see pin_cmd
 2178|    295|	gids_ops.create_file = iso_ops->create_file;
 2179|    295|	gids_ops.delete_file = NULL;
 2180|    295|	gids_ops.list_files = NULL;
 2181|    295|	gids_ops.check_sw = iso_ops->check_sw;
 2182|    295|	gids_ops.card_ctl = gids_card_ctl;
 2183|    295|	gids_ops.process_fci = iso_ops->process_fci;
 2184|    295|	gids_ops.construct_fci = iso_ops->construct_fci;
 2185|    295|	gids_ops.pin_cmd = gids_pin_cmd;
 2186|    295|	gids_ops.get_data = NULL;
 2187|    295|	gids_ops.put_data = NULL;
 2188|    295|	gids_ops.delete_record = NULL;
 2189|    295|	gids_ops.read_public_key = gids_read_public_key;
 2190|    295|	gids_ops.card_reader_lock_obtained = gids_card_reader_lock_obtained;
 2191|       |
 2192|    295|	return &gids_drv;
 2193|    295|}
card-gids.c:gids_match_card:
  567|     51|{
  568|     51|	u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
  569|     51|	int r,i;
  570|     51|	size_t resplen = sizeof(rbuf);
  571|     51|	const u8 *tag;
  572|     51|	size_t taglen;
  573|     51|	const u8 *aid;
  574|     51|	size_t aidlen;
  575|       |
  576|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
  577|       |
  578|       |	/* Detect by selecting applet */
  579|     51|	r = gids_select_aid(card, gids_aid.value, gids_aid.len, rbuf, &resplen);
  580|     51|	if (r<0) return 0;
  ------------------
  |  Branch (580:6): [True: 51, False: 0]
  ------------------
  581|       |
  582|      0|	card->type = SC_CARD_TYPE_GIDS_GENERIC;
  583|      0|	if (resplen > 2) {
  ------------------
  |  Branch (583:6): [True: 0, False: 0]
  ------------------
  584|      0|		tag = sc_asn1_find_tag(card->ctx, rbuf, resplen, GIDS_APPLICATION_TEMPLATE_TAG, &taglen);
  ------------------
  |  |  105|      0|#define GIDS_APPLICATION_TEMPLATE_TAG 0x61
  ------------------
  585|      0|		if (tag != NULL) {
  ------------------
  |  Branch (585:7): [True: 0, False: 0]
  ------------------
  586|      0|			aid = sc_asn1_find_tag(card->ctx, tag, taglen, GIDS_APPLICATION_AID_TAG, &aidlen);
  ------------------
  |  |  106|      0|#define GIDS_APPLICATION_AID_TAG 0x4F
  ------------------
  587|      0|			if (aid != NULL ) {
  ------------------
  |  Branch (587:8): [True: 0, False: 0]
  ------------------
  588|      0|				sc_log(card->ctx, "found AID");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  589|      0|				for (i = 0; gids_aids[i].len_long != 0; i++) {
  ------------------
  |  Branch (589:17): [True: 0, False: 0]
  ------------------
  590|      0|					if ( aidlen > gids_aids[i].len_long && memcmp(aid, gids_aids[i].value,
  ------------------
  |  Branch (590:11): [True: 0, False: 0]
  |  Branch (590:45): [True: 0, False: 0]
  ------------------
  591|      0|									gids_aids[i].len_long) == 0) {
  592|      0|						card->type = gids_aids[i].enumtag;
  593|      0|						break;
  594|      0|					}
  595|      0|				}
  596|      0|			}
  597|      0|		}
  598|      0|	}
  599|       |
  600|      0|	return 1;
  601|     51|}
card-gids.c:gids_select_aid:
  283|     51|{
  284|     51|	sc_apdu_t apdu;
  285|     51|	int r;
  286|       |
  287|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
  288|     51|	sc_log(card->ctx,
  ------------------
  |  |   71|    102|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  |  Branch (71:122): [True: 51, False: 0]
  |  |  ------------------
  ------------------
  289|     51|		 "Got args: aid=%p, aidlen=%"SC_FORMAT_LEN_SIZE_T"u, response=%p, responselen=%"SC_FORMAT_LEN_SIZE_T"u\n",
  290|     51|		 aid, aidlen, response, responselen ? *responselen : 0);
  291|       |
  292|     51|	sc_format_apdu(card, &apdu,
  293|     51|		response == NULL ? SC_APDU_CASE_3_SHORT : SC_APDU_CASE_4_SHORT, INS_SELECT, P1_SELECT_DF_BY_NAME, P2_SELECT_FIRST_OR_ONLY_OCCURENCE);
  ------------------
  |  |  293|      0|#define SC_APDU_CASE_3_SHORT		0x03
  ------------------
              		response == NULL ? SC_APDU_CASE_3_SHORT : SC_APDU_CASE_4_SHORT, INS_SELECT, P1_SELECT_DF_BY_NAME, P2_SELECT_FIRST_OR_ONLY_OCCURENCE);
  ------------------
  |  |  294|     51|#define SC_APDU_CASE_4_SHORT		0x04
  ------------------
              		response == NULL ? SC_APDU_CASE_3_SHORT : SC_APDU_CASE_4_SHORT, INS_SELECT, P1_SELECT_DF_BY_NAME, P2_SELECT_FIRST_OR_ONLY_OCCURENCE);
  ------------------
  |  |   68|     51|#define INS_SELECT 0xA4
  ------------------
              		response == NULL ? SC_APDU_CASE_3_SHORT : SC_APDU_CASE_4_SHORT, INS_SELECT, P1_SELECT_DF_BY_NAME, P2_SELECT_FIRST_OR_ONLY_OCCURENCE);
  ------------------
  |  |   72|     51|#define P1_SELECT_DF_BY_NAME 0x04
  ------------------
              		response == NULL ? SC_APDU_CASE_3_SHORT : SC_APDU_CASE_4_SHORT, INS_SELECT, P1_SELECT_DF_BY_NAME, P2_SELECT_FIRST_OR_ONLY_OCCURENCE);
  ------------------
  |  |   75|     51|#define P2_SELECT_FIRST_OR_ONLY_OCCURENCE 0x00
  ------------------
  |  Branch (293:3): [True: 0, False: 51]
  ------------------
  294|     51|	apdu.lc = aidlen;
  295|     51|	apdu.data = aid;
  296|     51|	apdu.datalen = aidlen;
  297|     51|	apdu.resp = response;
  298|     51|	apdu.resplen = responselen ? *responselen : 0;
  ------------------
  |  Branch (298:17): [True: 51, False: 0]
  ------------------
  299|     51|	apdu.le = response == NULL ? 0 : 256; /* could be 21 for fci */
  ------------------
  |  Branch (299:12): [True: 0, False: 51]
  ------------------
  300|       |
  301|     51|	r = sc_transmit_apdu(card, &apdu);
  302|     51|	if (responselen)
  ------------------
  |  Branch (302:6): [True: 51, False: 0]
  ------------------
  303|     51|		*responselen = apdu.resplen;
  304|     51|	LOG_TEST_RET(card->ctx, r, "gids select failed");
  ------------------
  |  |  174|     51|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|     51|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|     51|	int _ret = (r); \
  |  |  |  |  168|     51|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 51]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  305|     51|	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
  ------------------
  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  154|     51|	int _ret = r; \
  |  |  155|     51|	if (_ret <= 0) { \
  |  |  ------------------
  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  ------------------
  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  ------------------
  |  |  |  |   44|     51|#define SC_COLOR_FG_RED			0x0001
  |  |  ------------------
  |  |  |  Branch (156:65): [True: 51, False: 0]
  |  |  ------------------
  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  158|     51|	} else { \
  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  161|      0|	} \
  |  |  162|     51|	return _ret; \
  |  |  163|     51|} while(0)
  |  |  ------------------
  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  ------------------
  ------------------
  306|     51|}
card-gids.c:gids_card_reader_lock_obtained:
 2136|     51|{
 2137|     51|	int r = SC_SUCCESS;
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
 2138|       |
 2139|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
 2140|       |
 2141|     51|	if (was_reset > 0) {
  ------------------
  |  Branch (2141:6): [True: 0, False: 51]
  ------------------
 2142|      0|		u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
 2143|      0|		size_t resplen = sizeof(rbuf);
 2144|      0|		r = gids_select_aid(card, gids_aid.value, gids_aid.len, rbuf, &resplen);
 2145|      0|	}
 2146|       |
 2147|     51|	LOG_FUNC_RETURN(card->ctx, r);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2148|     51|}

sc_get_iasecc_driver:
 3688|    295|{
 3689|    295|	return sc_get_driver();
 3690|    295|}
card-iasecc.c:sc_get_driver:
 3641|    295|{
 3642|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 3643|       |
 3644|    295|	if (!iso_ops)
  ------------------
  |  Branch (3644:6): [True: 1, False: 294]
  ------------------
 3645|      1|		iso_ops = iso_drv->ops;
 3646|       |
 3647|    295|	iasecc_ops = *iso_ops;
 3648|       |
 3649|    295|	iasecc_ops.match_card = iasecc_match_card;
 3650|    295|	iasecc_ops.init = iasecc_init;
 3651|    295|	iasecc_ops.finish = iasecc_finish;
 3652|    295|	iasecc_ops.read_binary = iasecc_read_binary;
 3653|       |	/*	write_binary: ISO7816 implementation works	*/
 3654|       |	/*	update_binary: ISO7816 implementation works	*/
 3655|    295|	iasecc_ops.erase_binary = iasecc_erase_binary;
 3656|       |	/*	resize_binary	*/
 3657|       |	/* 	read_record: Untested	*/
 3658|       |	/*	write_record: Untested	*/
 3659|       |	/*	append_record: Untested	*/
 3660|       |	/*	update_record: Untested	*/
 3661|    295|	iasecc_ops.select_file = iasecc_select_file;
 3662|       |	/*	get_response: Untested	*/
 3663|    295|	iasecc_ops.get_challenge = iasecc_get_challenge;
 3664|    295|	iasecc_ops.logout = iasecc_logout;
 3665|       |	/*	restore_security_env	*/
 3666|    295|	iasecc_ops.set_security_env = iasecc_set_security_env;
 3667|    295|	iasecc_ops.decipher = iasecc_decipher;
 3668|    295|	iasecc_ops.compute_signature = iasecc_compute_signature;
 3669|    295|	iasecc_ops.create_file = iasecc_create_file;
 3670|    295|	iasecc_ops.delete_file = iasecc_delete_file;
 3671|       |	/*	list_files	*/
 3672|    295|	iasecc_ops.check_sw = iasecc_check_sw;
 3673|    295|	iasecc_ops.card_ctl = iasecc_card_ctl;
 3674|    295|	iasecc_ops.process_fci = iasecc_process_fci;
 3675|       |	/*	construct_fci: Not needed	*/
 3676|    295|	iasecc_ops.pin_cmd = iasecc_pin_cmd;
 3677|       |	/*	get_data: Not implemented	*/
 3678|       |	/*	put_data: Not implemented	*/
 3679|       |	/*	delete_record: Not implemented	*/
 3680|       |
 3681|    295|	iasecc_ops.read_public_key = iasecc_read_public_key;
 3682|       |
 3683|    295|	return &iasecc_drv;
 3684|    295|}
card-iasecc.c:iasecc_match_card:
  353|     51|{
  354|     51|	struct sc_context *ctx = card->ctx;
  355|     51|	int i;
  356|       |
  357|     51|	i = _sc_match_atr(card, iasecc_known_atrs, &card->type);
  358|     51|	if (i < 0)   {
  ------------------
  |  Branch (358:6): [True: 51, False: 0]
  ------------------
  359|     51|		sc_log(ctx, "card not matched");
  ------------------
  |  |   71|     51|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  360|     51|		return 0;
  361|     51|	}
  362|       |
  363|      0|	sc_log(ctx, "'%s' card matched", iasecc_known_atrs[i].name);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  364|      0|	return 1;
  365|     51|}

sc_get_idprime_driver:
 1279|    295|{
 1280|    295|	return sc_get_driver();
 1281|    295|}
card-idprime.c:sc_get_driver:
 1256|    295|{
 1257|    295|	if (iso_ops == NULL) {
  ------------------
  |  Branch (1257:6): [True: 1, False: 294]
  ------------------
 1258|      1|		iso_ops = sc_get_iso7816_driver()->ops;
 1259|      1|	}
 1260|       |
 1261|    295|	idprime_ops = *iso_ops;
 1262|    295|	idprime_ops.match_card = idprime_match_card;
 1263|    295|	idprime_ops.init = idprime_init;
 1264|    295|	idprime_ops.finish = idprime_finish;
 1265|       |
 1266|    295|	idprime_ops.read_binary = idprime_read_binary;
 1267|    295|	idprime_ops.select_file = idprime_select_file;
 1268|    295|	idprime_ops.card_ctl = idprime_card_ctl;
 1269|    295|	idprime_ops.set_security_env = idprime_set_security_env;
 1270|    295|	idprime_ops.compute_signature = idprime_compute_signature;
 1271|    295|	idprime_ops.decipher = idprime_decipher;
 1272|       |
 1273|    295|	idprime_ops.get_challenge = idprime_get_challenge;
 1274|       |
 1275|    295|	return &idprime_drv;
 1276|    295|}
card-idprime.c:idprime_match_card:
  750|     51|{
  751|     51|	int i, r;
  752|       |
  753|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
  754|     51|	i = _sc_match_atr(card, idprime_atrs, &card->type);
  755|     51|	if (i < 0)
  ------------------
  |  Branch (755:6): [True: 51, False: 0]
  ------------------
  756|     51|		return 0;
  757|       |
  758|      0|	r = idprime_select_file_by_path(card, "0101");
  759|      0|	LOG_FUNC_RETURN(card->ctx, r > 0);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  760|      0|}

sc_get_isoApplet_driver:
 1295|    295|{
 1296|    295|	return sc_get_driver();
 1297|    295|}
card-isoApplet.c:sc_get_driver:
 1259|    295|{
 1260|    295|	sc_card_driver_t *iso_drv = sc_get_iso7816_driver();
 1261|       |
 1262|    295|	if(iso_ops == NULL)
  ------------------
  |  Branch (1262:5): [True: 1, False: 294]
  ------------------
 1263|      1|	{
 1264|      1|		iso_ops = iso_drv->ops;
 1265|      1|	}
 1266|       |
 1267|    295|	isoApplet_ops = *iso_drv->ops;
 1268|       |
 1269|    295|	isoApplet_ops.match_card = isoApplet_match_card;
 1270|    295|	isoApplet_ops.init = isoApplet_init;
 1271|    295|	isoApplet_ops.finish = isoApplet_finish;
 1272|       |
 1273|    295|	isoApplet_ops.card_ctl = isoApplet_card_ctl;
 1274|       |
 1275|    295|	isoApplet_ops.create_file = isoApplet_create_file;
 1276|    295|	isoApplet_ops.process_fci = isoApplet_process_fci;
 1277|    295|	isoApplet_ops.set_security_env = isoApplet_set_security_env;
 1278|    295|	isoApplet_ops.compute_signature = isoApplet_compute_signature;
 1279|    295|	isoApplet_ops.get_challenge = isoApplet_get_challenge;
 1280|    295|	isoApplet_ops.card_reader_lock_obtained = isoApplet_card_reader_lock_obtained;
 1281|    295|	isoApplet_ops.logout = isoApplet_logout;
 1282|       |
 1283|       |	/* unsupported functions */
 1284|    295|	isoApplet_ops.write_binary = NULL;
 1285|    295|	isoApplet_ops.read_record = NULL;
 1286|    295|	isoApplet_ops.write_record = NULL;
 1287|    295|	isoApplet_ops.append_record = NULL;
 1288|    295|	isoApplet_ops.update_record = NULL;
 1289|    295|	isoApplet_ops.restore_security_env = NULL;
 1290|       |
 1291|    295|	return &isoApplet_drv;
 1292|    295|}
card-isoApplet.c:isoApplet_match_card:
  111|     51|{
  112|     51|	int rv;
  113|       |
  114|     51|	rv = iso7816_select_aid(card, isoApplet_aid, sizeof(isoApplet_aid), NULL, NULL);
  115|     51|	if(rv != SC_SUCCESS)
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  |  Branch (115:5): [True: 51, False: 0]
  ------------------
  116|     51|	{
  117|     51|		return 0;
  118|     51|	}
  119|       |
  120|      0|	return 1;
  121|     51|}
card-isoApplet.c:isoApplet_card_reader_lock_obtained:
 1241|     51|{
 1242|     51|	int r = SC_SUCCESS;
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
 1243|       |
 1244|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
 1245|       |
 1246|     51|	if (was_reset > 0) {
  ------------------
  |  Branch (1246:6): [True: 0, False: 51]
  ------------------
 1247|      0|		r = iso7816_select_aid(card, isoApplet_aid, sizeof(isoApplet_aid), NULL, NULL);
 1248|      0|	}
 1249|       |
 1250|     51|	LOG_FUNC_RETURN(card->ctx, r);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1251|     51|}

sc_get_itacns_driver:
  523|    295|{
  524|    295|	return sc_get_driver();
  525|    295|}
card-itacns.c:sc_get_driver:
  504|    295|{
  505|    295|	if (!default_ops)
  ------------------
  |  Branch (505:6): [True: 1, False: 294]
  ------------------
  506|      1|		default_ops = sc_get_iso7816_driver()->ops;
  507|    295|	itacns_ops = *default_ops;
  508|    295|	itacns_ops.match_card = itacns_match_card;
  509|    295|	itacns_ops.init = itacns_init;
  510|    295|	itacns_ops.finish = itacns_finish;
  511|    295|	itacns_ops.set_security_env = itacns_set_security_env;
  512|    295|	itacns_ops.restore_security_env = itacns_restore_security_env;
  513|    295|	itacns_ops.pin_cmd = itacns_pin_cmd;
  514|    295|	itacns_ops.read_binary = itacns_read_binary;
  515|    295|	itacns_ops.list_files = itacns_list_files;
  516|    295|	itacns_ops.select_file = itacns_select_file;
  517|    295|	itacns_ops.card_ctl = itacns_card_ctl;
  518|    295|	itacns_ops.get_challenge = itacns_get_challenge;
  519|    295|	return &itacns_drv;
  520|    295|}
card-itacns.c:itacns_match_card:
  122|     51|{
  123|     51|	int r = 0;
  124|       |
  125|       |	/* Try table first */
  126|     51|	r = _sc_match_atr(card, itacns_atrs, &card->type);
  127|     51|	if(r >= 0) return 1;
  ------------------
  |  Branch (127:5): [True: 0, False: 51]
  ------------------
  128|       |
  129|     51|	if (itacns_match_cns_card(card)) return 1;
  ------------------
  |  Branch (129:6): [True: 0, False: 51]
  ------------------
  130|     51|	if (itacns_match_cie_card(card)) return 1;
  ------------------
  |  Branch (130:6): [True: 0, False: 51]
  ------------------
  131|       |
  132|       |	/* No card type was matched. */
  133|     51|	return 0;
  134|     51|}
card-itacns.c:itacns_match_cns_card:
   85|     51|{
   86|     51|	u8 manufacturer_code;
   87|     51|	u8 manufacturer_mask;
   88|     51|	u8 fw_major;
   89|       |
   90|     51|	if (15 != card->reader->atr_info.hist_bytes_len ||
  ------------------
  |  Branch (90:6): [True: 51, False: 0]
  ------------------
   91|      0|	    0 != memcmp(card->reader->atr_info.hist_bytes+9, "CNS", 3))
  ------------------
  |  Branch (91:6): [True: 0, False: 0]
  ------------------
   92|     51|		return 0;
   93|       |
   94|      0|	card->type = SC_CARD_TYPE_ITACNS_CNS;
   95|       |
   96|      0|	manufacturer_code = card->reader->atr_info.hist_bytes[2];
   97|      0|	manufacturer_mask = card->reader->atr_info.hist_bytes[3];
   98|      0|	fw_major = card->reader->atr_info.hist_bytes[4];
   99|       |
  100|      0|	if (manufacturer_code == ITACNS_ICMAN_INFINEON &&
  ------------------
  |  |    9|      0|#define ITACNS_ICMAN_INFINEON		0x05
  ------------------
  |  Branch (100:6): [True: 0, False: 0]
  ------------------
  101|      0|	    manufacturer_mask == ITACNS_MASKMAN_IDEMIA &&
  ------------------
  |  |   11|      0|#define ITACNS_MASKMAN_IDEMIA		0x05
  ------------------
  |  Branch (101:6): [True: 0, False: 0]
  ------------------
  102|      0|	    fw_major >= 32) {
  ------------------
  |  Branch (102:6): [True: 0, False: 0]
  ------------------
  103|      0|			card->type = SC_CARD_TYPE_ITACNS_CNS_IDEMIA_2021;
  104|      0|	}
  105|       |
  106|      0|	return 1;
  107|     51|}
card-itacns.c:itacns_match_cie_card:
  110|     51|{
  111|     51|	u8 h7_to_h15[] = { 0x02, 'I', 'T', 'I', 'D', 0x20, 0x20, 0x31, 0x80, };
  112|     51|	if (15 != card->reader->atr_info.hist_bytes_len ||
  ------------------
  |  Branch (112:6): [True: 51, False: 0]
  ------------------
  113|      0|	    0 != memcmp(card->reader->atr_info.hist_bytes+6,
  ------------------
  |  Branch (113:6): [True: 0, False: 0]
  ------------------
  114|      0|			h7_to_h15, sizeof h7_to_h15))
  115|     51|		return 0;
  116|       |
  117|      0|	card->type = SC_CARD_TYPE_ITACNS_CIE_V2;
  118|      0|	return 1;
  119|     51|}

jpki_select_ap:
   46|     51|{
   47|     51|	int rc;
   48|     51|	sc_path_t path;
   49|       |
   50|     51|	LOG_FUNC_CALLED(card->ctx);
  ------------------
  |  |  151|     51|#define LOG_FUNC_CALLED(ctx) SC_FUNC_CALLED((ctx), SC_LOG_DEBUG_NORMAL)
  |  |  ------------------
  |  |  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  150|     51|} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   51|       |
   52|       |	/* Select JPKI application */
   53|     51|	sc_format_path(AID_JPKI, &path);
  ------------------
  |  |   27|     51|#define AID_JPKI "D392f000260100000001"
  ------------------
   54|     51|	path.type = SC_PATH_TYPE_DF_NAME;
  ------------------
  |  |  118|     51|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
   55|     51|	rc = sc_select_file(card, &path, NULL);
   56|     51|	LOG_TEST_RET(card->ctx, rc, "select JPKI AP failed");
  ------------------
  |  |  174|     51|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|     51|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|     51|	int _ret = (r); \
  |  |  |  |  168|     51|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|     51|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|     51|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|     51|		return _ret; \
  |  |  |  |  172|     51|	} \
  |  |  |  |  173|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   57|       |
   58|      0|	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   59|      0|}
sc_get_jpki_driver:
  388|    295|{
  389|    295|	return sc_get_driver();
  390|    295|}
card-jpki.c:sc_get_driver:
  369|    295|{
  370|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
  371|       |
  372|    295|	jpki_ops = *iso_drv->ops;
  373|    295|	jpki_ops.match_card = jpki_match_card;
  374|    295|	jpki_ops.init = jpki_init;
  375|    295|	jpki_ops.finish = jpki_finish;
  376|    295|	jpki_ops.select_file = jpki_select_file;
  377|    295|	jpki_ops.pin_cmd = jpki_pin_cmd;
  378|    295|	jpki_ops.set_security_env = jpki_set_security_env;
  379|    295|	jpki_ops.compute_signature = jpki_compute_signature;
  380|    295|	jpki_ops.card_reader_lock_obtained = jpki_card_reader_lock_obtained;
  381|    295|	jpki_ops.logout = jpki_logout;
  382|       |
  383|    295|	return &jpki_drv;
  384|    295|}
card-jpki.c:jpki_match_card:
   63|     51|{
   64|     51|	int i, rc;
   65|       |
   66|     51|	i = _sc_match_atr(card, jpki_atrs, &card->type);
   67|     51|	if (i >= 0) {
  ------------------
  |  Branch (67:6): [True: 0, False: 51]
  ------------------
   68|      0|		return 1;
   69|      0|	}
   70|       |
   71|     51|	rc = jpki_select_ap(card);
   72|     51|	if (rc == SC_SUCCESS) {
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  |  Branch (72:6): [True: 0, False: 51]
  ------------------
   73|      0|		card->type = SC_CARD_TYPE_JPKI_BASE;
   74|      0|		return 1;
   75|      0|	}
   76|     51|	return 0;
   77|     51|}
card-jpki.c:jpki_select_file:
  143|     51|{
  144|     51|	struct jpki_private_data *drvdata = JPKI_DRVDATA(card);
  ------------------
  |  |   36|     51|#define JPKI_DRVDATA(card) ((struct jpki_private_data *) ((card)->drv_data))
  ------------------
  145|     51|	int rc;
  146|     51|	sc_apdu_t apdu;
  147|     51|	struct sc_file *file = NULL;
  148|       |
  149|     51|	LOG_FUNC_CALLED(card->ctx);
  ------------------
  |  |  151|     51|#define LOG_FUNC_CALLED(ctx) SC_FUNC_CALLED((ctx), SC_LOG_DEBUG_NORMAL)
  |  |  ------------------
  |  |  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  150|     51|} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  150|     51|	sc_log(card->ctx,
  ------------------
  |  |   71|     51|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  151|     51|	       "jpki_select_file: path=%s, len=%"SC_FORMAT_LEN_SIZE_T"u",
  152|     51|	       sc_print_path(path), path->len);
  153|     51|	if (path->len == 2 && memcmp(path->value, "\x3F\x00", 2) == 0) {
  ------------------
  |  Branch (153:6): [True: 0, False: 51]
  |  Branch (153:24): [True: 0, False: 0]
  ------------------
  154|      0|		drvdata->selected = SELECT_MF;
  ------------------
  |  |   24|      0|#define SELECT_MF 0
  ------------------
  155|      0|		if (file_out) {
  ------------------
  |  Branch (155:7): [True: 0, False: 0]
  ------------------
  156|      0|			sc_file_dup(file_out, drvdata->mf);
  157|      0|			if (*file_out == NULL) {
  ------------------
  |  Branch (157:8): [True: 0, False: 0]
  ------------------
  158|      0|				LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  159|      0|			}
  160|      0|		}
  161|      0|		return 0;
  162|      0|	}
  163|       |
  164|     51|	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 0, 0);
  ------------------
  |  |  293|     51|#define SC_APDU_CASE_3_SHORT		0x03
  ------------------
  165|     51|	switch (path->type) {
  166|      0|	case SC_PATH_TYPE_FILE_ID:
  ------------------
  |  |  117|      0|#define SC_PATH_TYPE_FILE_ID		0
  ------------------
  |  Branch (166:2): [True: 0, False: 51]
  ------------------
  167|      0|		apdu.p1 = 2;
  168|      0|		break;
  169|     51|	case SC_PATH_TYPE_DF_NAME:
  ------------------
  |  |  118|     51|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
  |  Branch (169:2): [True: 51, False: 0]
  ------------------
  170|     51|		apdu.p1 = 4;
  171|     51|		break;
  172|      0|	default:
  ------------------
  |  Branch (172:2): [True: 0, False: 51]
  ------------------
  173|      0|		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  174|     51|	}
  175|     51|	apdu.p2 = 0x0C;
  176|     51|	apdu.data = path->value;
  177|     51|	apdu.datalen = path->len;
  178|     51|	apdu.lc = path->len;
  179|       |
  180|     51|	rc = sc_transmit_apdu(card, &apdu);
  181|     51|	LOG_TEST_RET(card->ctx, rc, "APDU transmit failed");
  ------------------
  |  |  174|     51|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|     51|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|     51|	int _ret = (r); \
  |  |  |  |  168|     51|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 51]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  182|     51|	rc = sc_check_sw(card, apdu.sw1, apdu.sw2);
  183|     51|	LOG_TEST_RET(card->ctx, rc, "SW Check failed");
  ------------------
  |  |  174|     51|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|     51|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|     51|	int _ret = (r); \
  |  |  |  |  168|     51|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|     51|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|     51|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|     51|		return _ret; \
  |  |  |  |  172|     51|	} \
  |  |  |  |  173|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  184|      0|	if (!file_out) {
  ------------------
  |  Branch (184:6): [True: 0, False: 0]
  ------------------
  185|      0|		LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  186|      0|	}
  187|       |
  188|       |	/* read certificate file size */
  189|      0|	if (path->len == 2 && (
  ------------------
  |  Branch (189:6): [True: 0, False: 0]
  ------------------
  190|      0|		    memcmp(path->value, "\x00\x0A", 2) == 0 ||
  ------------------
  |  Branch (190:7): [True: 0, False: 0]
  ------------------
  191|      0|		    memcmp(path->value, "\x00\x01", 2) == 0 ||
  ------------------
  |  Branch (191:7): [True: 0, False: 0]
  ------------------
  192|      0|		    memcmp(path->value, "\x00\x0B", 2) == 0 ||
  ------------------
  |  Branch (192:7): [True: 0, False: 0]
  ------------------
  193|      0|		    memcmp(path->value, "\x00\x02", 2) == 0 )
  ------------------
  |  Branch (193:7): [True: 0, False: 0]
  ------------------
  194|      0|		) {
  195|      0|		u8 buf[4];
  196|      0|		rc = sc_read_binary(card, 0, buf, 4, 0);
  197|      0|		LOG_TEST_RET(card->ctx, rc, "SW Check failed");
  ------------------
  |  |  174|      0|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|      0|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|      0|	int _ret = (r); \
  |  |  |  |  168|      0|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  198|      0|		if (rc < 4)
  ------------------
  |  Branch (198:7): [True: 0, False: 0]
  ------------------
  199|      0|			LOG_TEST_RET(card->ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED, "Received data too short");
  ------------------
  |  |  174|      0|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|      0|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|      0|	int _ret = (r); \
  |  |  |  |  168|      0|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  200|      0|		file = sc_file_new();
  201|      0|		if (!file) {
  ------------------
  |  Branch (201:7): [True: 0, False: 0]
  ------------------
  202|      0|			LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  203|      0|		}
  204|      0|		file->path = *path;
  205|      0|		file->size = (buf[2] << 8 | buf[3]) + 4;
  206|      0|		*file_out = file;
  207|      0|	}
  208|      0|	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  209|      0|}
card-jpki.c:jpki_card_reader_lock_obtained:
  350|     51|{
  351|     51|	int r = SC_SUCCESS;
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  352|       |
  353|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
  354|       |
  355|     51|	if (was_reset > 0) {
  ------------------
  |  Branch (355:6): [True: 0, False: 51]
  ------------------
  356|      0|		r = jpki_select_ap(card);
  357|      0|	}
  358|       |
  359|     51|	LOG_FUNC_RETURN(card->ctx, r);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  360|     51|}

sc_get_lteid_driver:
  555|    295|{
  556|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
  557|       |
  558|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (558:6): [True: 1, False: 294]
  ------------------
  559|      1|		iso_ops = iso_drv->ops;
  560|       |
  561|    295|	lteid_ops = *iso_ops;
  562|    295|	lteid_ops.init = lteid_init;
  563|    295|	lteid_ops.finish = lteid_finish;
  564|    295|	lteid_ops.set_security_env = lteid_set_security_env;
  565|    295|	lteid_ops.compute_signature = lteid_compute_signature;
  566|    295|	lteid_ops.pin_cmd = lteid_pin_cmd;
  567|    295|	lteid_ops.logout = lteid_logout;
  568|    295|	lteid_ops.process_fci = lteid_process_fci;
  569|       |
  570|    295|	return &lteid_drv;
  571|    295|}

sc_get_masktech_driver:
  374|    295|{
  375|    295|	return sc_get_driver();
  376|    295|}
card-masktech.c:sc_get_driver:
  355|    295|{
  356|       |
  357|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (357:6): [True: 1, False: 294]
  ------------------
  358|      1|		iso_ops = sc_get_iso7816_driver()->ops;
  359|       |
  360|    295|	masktech_ops = *iso_ops;
  361|       |
  362|    295|	masktech_ops.match_card = masktech_match_card;
  363|    295|	masktech_ops.init = masktech_init;
  364|    295|	masktech_ops.finish = masktech_finish;
  365|    295|	masktech_ops.set_security_env = masktech_set_security_env;
  366|    295|	masktech_ops.compute_signature = masktech_compute_signature;
  367|    295|	masktech_ops.decipher = masktech_decipher;
  368|    295|	masktech_ops.pin_cmd = masktech_pin_cmd;
  369|    295|	masktech_ops.card_ctl = masktech_card_ctl;
  370|    295|	return &masktech_drv;
  371|    295|}
card-masktech.c:masktech_match_card:
   62|     51|{
   63|       |	/* check if the ATR is in the known ATR */
   64|     51|	if (_sc_match_atr(card, masktech_atrs, &card->type) < 0)
  ------------------
  |  Branch (64:6): [True: 51, False: 0]
  ------------------
   65|     51|		return 0;
   66|       |
   67|      0|	return 1;
   68|     51|}

sc_get_mcrd_driver:
 1068|    295|{
 1069|    295|	return sc_get_driver();
 1070|    295|}
card-mcrd.c:sc_get_driver:
 1049|    295|{
 1050|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 1051|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (1051:6): [True: 1, False: 294]
  ------------------
 1052|      1|		iso_ops = iso_drv->ops;
 1053|       |
 1054|    295|	mcrd_ops = *iso_drv->ops;
 1055|    295|	mcrd_ops.match_card = mcrd_match_card;
 1056|    295|	mcrd_ops.init = mcrd_init;
 1057|    295|	mcrd_ops.finish = mcrd_finish;
 1058|    295|	mcrd_ops.select_file = mcrd_select_file;
 1059|    295|	mcrd_ops.set_security_env = mcrd_set_security_env;
 1060|    295|	mcrd_ops.compute_signature = mcrd_compute_signature;
 1061|    295|	mcrd_ops.pin_cmd = mcrd_pin_cmd;
 1062|    295|	mcrd_ops.logout = mcrd_logout;
 1063|       |
 1064|    295|	return &mcrd_drv;
 1065|    295|}
card-mcrd.c:mcrd_match_card:
  191|     51|{
  192|     51|	int i = 0;
  193|       |
  194|     51|	i = _sc_match_atr(card, mcrd_atrs, &card->type);
  195|     51|	if (i >= 0) {
  ------------------
  |  Branch (195:6): [True: 0, False: 51]
  ------------------
  196|      0|		card->name = mcrd_atrs[i].name;
  197|      0|		return 1;
  198|      0|	}
  199|       |
  200|     51|	return 0;
  201|     51|}

sc_get_muscle_driver:
  903|    295|{
  904|    295|	return sc_get_driver();
  905|    295|}
card-muscle.c:sc_get_driver:
  871|    295|{
  872|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
  873|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (873:6): [True: 1, False: 294]
  ------------------
  874|      1|		iso_ops = iso_drv->ops;
  875|       |
  876|    295|	muscle_ops = *iso_drv->ops;
  877|    295|	muscle_ops.check_sw = muscle_check_sw;
  878|    295|	muscle_ops.pin_cmd = muscle_pin_cmd;
  879|    295|	muscle_ops.match_card = muscle_match_card;
  880|    295|	muscle_ops.init = muscle_init;
  881|    295|	muscle_ops.finish = muscle_finish;
  882|       |
  883|    295|	muscle_ops.get_challenge = muscle_get_challenge;
  884|       |
  885|    295|	muscle_ops.set_security_env = muscle_set_security_env;
  886|    295|	muscle_ops.restore_security_env = muscle_restore_security_env;
  887|    295|	muscle_ops.compute_signature = muscle_compute_signature;
  888|    295|	muscle_ops.decipher = muscle_decipher;
  889|    295|	muscle_ops.card_ctl = muscle_card_ctl;
  890|    295|	muscle_ops.read_binary = muscle_read_binary;
  891|    295|	muscle_ops.update_binary = muscle_update_binary;
  892|    295|	muscle_ops.create_file = muscle_create_file;
  893|    295|	muscle_ops.select_file = muscle_select_file;
  894|    295|	muscle_ops.delete_file = muscle_delete_file;
  895|    295|	muscle_ops.list_files = muscle_list_files;
  896|    295|	muscle_ops.card_reader_lock_obtained = muscle_card_reader_lock_obtained;
  897|    295|	muscle_ops.logout = muscle_logout;
  898|       |
  899|    295|	return &muscle_drv;
  900|    295|}
card-muscle.c:muscle_match_card:
   79|     51|{
   80|     51|	sc_apdu_t apdu;
   81|     51|	u8 response[64];
   82|     51|	int r;
   83|       |
   84|     51|	if (msc_select_applet(card, muscleAppletId, sizeof muscleAppletId) == 1) {
  ------------------
  |  Branch (84:6): [True: 0, False: 51]
  ------------------
   85|       |		/* Muscle applet is present, check the protocol version to be sure */
   86|      0|		sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x3C, 0x00, 0x00);
  ------------------
  |  |  301|      0|#define SC_APDU_CASE_2			0x22
  ------------------
   87|      0|		apdu.cla = 0xB0;
   88|      0|		apdu.le = 64;
   89|      0|		apdu.resplen = 64;
   90|      0|		apdu.resp = response;
   91|      0|		r = sc_transmit_apdu(card, &apdu);
   92|      0|		if (r == SC_SUCCESS && apdu.resplen > 1 && response[0] == 0x01) {
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (92:7): [True: 0, False: 0]
  |  Branch (92:26): [True: 0, False: 0]
  |  Branch (92:46): [True: 0, False: 0]
  ------------------
   93|      0|			card->type = SC_CARD_TYPE_MUSCLE_V1;
   94|      0|		} else {
   95|      0|			card->type = SC_CARD_TYPE_MUSCLE_GENERIC;
   96|      0|		}
   97|      0|		return 1;
   98|      0|	}
   99|     51|	return 0;
  100|     51|}
card-muscle.c:muscle_card_reader_lock_obtained:
  842|     51|{
  843|     51|	int r = SC_SUCCESS;
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  844|       |
  845|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
  846|       |
  847|     51|	if (was_reset > 0) {
  ------------------
  |  Branch (847:6): [True: 0, False: 51]
  ------------------
  848|      0|		if (msc_select_applet(card, muscleAppletId, sizeof muscleAppletId) != 1) {
  ------------------
  |  Branch (848:7): [True: 0, False: 0]
  ------------------
  849|      0|			r = SC_ERROR_INVALID_CARD;
  ------------------
  |  |   60|      0|#define SC_ERROR_INVALID_CARD			-1210
  ------------------
  850|      0|		}
  851|      0|	}
  852|       |
  853|     51|	LOG_FUNC_RETURN(card->ctx, r);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  854|     51|}

sc_get_myeid_driver:
 2133|    295|{
 2134|    295|	return sc_get_driver();
 2135|    295|}
card-myeid.c:sc_get_driver:
 2098|    295|{
 2099|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 2100|       |
 2101|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (2101:6): [True: 1, False: 294]
  ------------------
 2102|      1|		iso_ops = iso_drv->ops;
 2103|       |
 2104|    295|	myeid_ops			= *iso_drv->ops;
 2105|    295|	myeid_ops.match_card		= myeid_match_card;
 2106|    295|	myeid_ops.init			= myeid_init;
 2107|    295|	myeid_ops.finish		= myeid_finish;
 2108|       |	/* no record oriented file services */
 2109|    295|	myeid_ops.read_record		= NULL;
 2110|    295|	myeid_ops.write_record		= NULL;
 2111|    295|	myeid_ops.append_record		= NULL;
 2112|       |	myeid_ops.update_record		= NULL;
 2113|    295|	myeid_ops.select_file		= myeid_select_file;
 2114|    295|	myeid_ops.get_response		= iso_ops->get_response;
 2115|    295|	myeid_ops.logout		= myeid_logout;
 2116|    295|	myeid_ops.create_file		= myeid_create_file;
 2117|    295|	myeid_ops.delete_file		= myeid_delete_file;
 2118|    295|	myeid_ops.list_files		= myeid_list_files;
 2119|    295|	myeid_ops.set_security_env	= myeid_set_security_env;
 2120|    295|	myeid_ops.compute_signature	= myeid_compute_signature;
 2121|    295|	myeid_ops.decipher		= myeid_decipher;
 2122|    295|	myeid_ops.process_fci		= myeid_process_fci;
 2123|    295|	myeid_ops.card_ctl		= myeid_card_ctl;
 2124|    295|	myeid_ops.pin_cmd		= myeid_pin_cmd;
 2125|    295|	myeid_ops.wrap			= myeid_wrap_key;
 2126|    295|	myeid_ops.unwrap		= myeid_unwrap_key;
 2127|    295|	myeid_ops.encrypt_sym		= myeid_encrypt_sym;
 2128|    295|	myeid_ops.decrypt_sym		= myeid_decrypt_sym;
 2129|    295|	return &myeid_drv;
 2130|    295|}
card-myeid.c:myeid_match_card:
  122|     51|{
  123|     51|	size_t len = card->reader->atr_info.hist_bytes_len;
  124|       |	/* Normally the historical bytes are exactly "MyEID", but there might
  125|       |	 * be some historic units which have a small prefix byte sequence. */
  126|     51|	if (len >= 5) {
  ------------------
  |  Branch (126:6): [True: 0, False: 51]
  ------------------
  127|      0|		if (!memcmp(&card->reader->atr_info.hist_bytes[len - 5], "MyEID", 5)) {
  ------------------
  |  Branch (127:7): [True: 0, False: 0]
  ------------------
  128|      0|			sc_log(card->ctx, "Matched MyEID card");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  129|      0|			card->type = SC_CARD_TYPE_MYEID_GENERIC;
  130|      0|			return 1;
  131|      0|		}
  132|       |		/* The software implementation of MyEID is identified by OsEID bytes */
  133|      0|		if (!memcmp(&card->reader->atr_info.hist_bytes[len - 5], "OsEID", 5)) {
  ------------------
  |  Branch (133:7): [True: 0, False: 0]
  ------------------
  134|      0|			sc_log(card->ctx, "Matched OsEID card");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  135|      0|			card->type = SC_CARD_TYPE_MYEID_OSEID;
  136|      0|			return 1;
  137|      0|		}
  138|      0|	}
  139|     51|	return 0;
  140|     51|}

sc_get_npa_driver:
  806|    295|{
  807|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
  808|       |
  809|    295|	npa_ops = *iso_drv->ops;
  810|    295|	npa_ops.match_card = npa_match_card;
  811|    295|	npa_ops.init = npa_init;
  812|    295|	npa_ops.finish = npa_finish;
  813|    295|	npa_ops.set_security_env = npa_set_security_env;
  814|    295|	npa_ops.pin_cmd = npa_pin_cmd;
  815|    295|	npa_ops.logout = npa_logout;
  816|       |
  817|    295|	return &npa_drv;
  818|    295|}
card-npa.c:npa_match_card:
  153|     51|{
  154|     51|	unsigned char dir_content[sizeof dir_content_ref];
  155|     51|	unsigned char id[] = {0x2F, 0x00};
  156|     51|	sc_apdu_t select_ef_dir;
  157|       |
  158|     51|	sc_format_apdu_ex(&select_ef_dir, 0x00, 0xA4, 0x02, 0x0C, id, sizeof id, NULL, 0);
  159|       |
  160|     51|	if (SC_SUCCESS == sc_select_file(card, sc_get_mf_path(), NULL)
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  |  Branch (160:6): [True: 0, False: 51]
  ------------------
  161|      0|			&& SC_SUCCESS == sc_transmit_apdu(card, &select_ef_dir)
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (161:7): [True: 0, False: 0]
  ------------------
  162|      0|			&& select_ef_dir.sw1 == 0x90 && select_ef_dir.sw2 == 0x00
  ------------------
  |  Branch (162:7): [True: 0, False: 0]
  |  Branch (162:36): [True: 0, False: 0]
  ------------------
  163|      0|			&& sizeof dir_content == sc_read_binary(card, 0, dir_content, sizeof dir_content, 0)
  ------------------
  |  Branch (163:7): [True: 0, False: 0]
  ------------------
  164|      0|			&& 0 == memcmp(dir_content_ref, dir_content, sizeof dir_content))
  ------------------
  |  Branch (164:7): [True: 0, False: 0]
  ------------------
  165|      0|		return 1;
  166|       |
  167|     51|	return 0;
  168|     51|}

sc_get_nqApplet_driver:
  471|    295|{
  472|    295|	sc_card_driver_t *iso_driver = sc_get_iso7816_driver();
  473|       |
  474|    295|	if (iso_operations == NULL) {
  ------------------
  |  Branch (474:6): [True: 1, False: 294]
  ------------------
  475|      1|		iso_operations = iso_driver->ops;
  476|      1|	}
  477|       |
  478|    295|	nqapplet_operations = *iso_driver->ops;
  479|       |
  480|       |	/* supported operations */
  481|    295|	nqapplet_operations.match_card = nqapplet_match_card;
  482|    295|	nqapplet_operations.init = nqapplet_init;
  483|    295|	nqapplet_operations.finish = nqapplet_finish;
  484|    295|	nqapplet_operations.get_response = nqapplet_get_response;
  485|    295|	nqapplet_operations.get_challenge = nqapplet_get_challenge;
  486|    295|	nqapplet_operations.logout = nqapplet_logout;
  487|    295|	nqapplet_operations.set_security_env = nqapplet_set_security_env;
  488|    295|	nqapplet_operations.decipher = nqapplet_decipher;
  489|    295|	nqapplet_operations.compute_signature = nqapplet_compute_signature;
  490|    295|	nqapplet_operations.check_sw = nqapplet_check_sw;
  491|    295|	nqapplet_operations.get_data = nqapplet_get_data;
  492|    295|	nqapplet_operations.select_file = nqapplet_select_file;
  493|    295|	nqapplet_operations.card_ctl = nqapplet_card_ctl;
  494|    295|	nqapplet_operations.pin_cmd = nqapplet_pin_cmd;
  495|       |
  496|       |	/* unsupported operations */
  497|    295|	nqapplet_operations.read_binary = NULL;
  498|    295|	nqapplet_operations.write_binary = NULL;
  499|    295|	nqapplet_operations.update_binary = NULL;
  500|    295|	nqapplet_operations.erase_binary = NULL;
  501|    295|	nqapplet_operations.read_record = NULL;
  502|    295|	nqapplet_operations.write_record = NULL;
  503|    295|	nqapplet_operations.append_record = NULL;
  504|    295|	nqapplet_operations.update_record = NULL;
  505|       |
  506|    295|	nqapplet_operations.verify = NULL;
  507|    295|	nqapplet_operations.restore_security_env = NULL;
  508|    295|	nqapplet_operations.change_reference_data = NULL;
  509|    295|	nqapplet_operations.reset_retry_counter = NULL;
  510|    295|	nqapplet_operations.create_file = NULL;
  511|    295|	nqapplet_operations.delete_file = NULL;
  512|    295|	nqapplet_operations.list_files = NULL;
  513|    295|	nqapplet_operations.process_fci = NULL;
  514|    295|	nqapplet_operations.construct_fci = NULL;
  515|    295|	nqapplet_operations.put_data = NULL;
  516|    295|	nqapplet_operations.delete_record = NULL;
  517|    295|	nqapplet_operations.read_public_key = NULL;
  518|       |
  519|       |	/* let iso driver handle these operations
  520|       |	nqapplet_operations.card_reader_lock_obtained;
  521|       |	nqapplet_operations.wrap;
  522|       |	nqapplet_operations.unwrap;
  523|       |	*/
  524|       |
  525|    295|	return &nqapplet_driver;
  526|    295|}
card-nqApplet.c:nqapplet_match_card:
  143|     51|{
  144|     51|	int rv = _sc_match_atr(card, nqapplet_atrs, &card->type);
  145|     51|	return (rv >= 0);
  146|     51|}

sc_get_oberthur_driver:
 2343|    295|{
 2344|    295|	return sc_get_driver();
 2345|    295|}
card-oberthur.c:sc_get_driver:
 2312|    295|{
 2313|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (2313:6): [True: 1, False: 294]
  ------------------
 2314|      1|		iso_ops = sc_get_iso7816_driver()->ops;
 2315|       |
 2316|    295|	auth_ops = *iso_ops;
 2317|    295|	auth_ops.match_card = auth_match_card;
 2318|    295|	auth_ops.init = auth_init;
 2319|    295|	auth_ops.finish = auth_finish;
 2320|    295|	auth_ops.select_file = auth_select_file;
 2321|    295|	auth_ops.list_files = auth_list_files;
 2322|    295|	auth_ops.delete_file = auth_delete_file;
 2323|    295|	auth_ops.create_file = auth_create_file;
 2324|    295|	auth_ops.read_binary = auth_read_binary;
 2325|    295|	auth_ops.update_binary = auth_update_binary;
 2326|    295|	auth_ops.read_record = auth_read_record;
 2327|    295|	auth_ops.delete_record = auth_delete_record;
 2328|    295|	auth_ops.card_ctl = auth_card_ctl;
 2329|    295|	auth_ops.set_security_env = auth_set_security_env;
 2330|    295|	auth_ops.restore_security_env = auth_restore_security_env;
 2331|    295|	auth_ops.compute_signature = auth_compute_signature;
 2332|    295|	auth_ops.decipher = auth_decipher;
 2333|    295|	auth_ops.process_fci = auth_process_fci;
 2334|    295|	auth_ops.pin_cmd = auth_pin_cmd;
 2335|    295|	auth_ops.logout = auth_logout;
 2336|    295|	auth_ops.check_sw = auth_check_sw;
 2337|    295|	return &auth_drv;
 2338|    295|}
card-oberthur.c:auth_match_card:
  204|     51|{
  205|     51|	if (_sc_match_atr(card, oberthur_atrs, &card->type) < 0)
  ------------------
  |  Branch (205:6): [True: 51, False: 0]
  ------------------
  206|     51|		return 0;
  207|      0|	else
  208|      0|		return 1;
  209|     51|}

sc_get_openpgp_driver:
 4211|    295|{
 4212|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 4213|       |
 4214|    295|	iso_ops = iso_drv->ops;
 4215|       |
 4216|    295|	pgp_ops = *iso_ops;
 4217|    295|	pgp_ops.match_card	= pgp_match_card;
 4218|    295|	pgp_ops.init		= pgp_init;
 4219|    295|	pgp_ops.finish		= pgp_finish;
 4220|    295|	pgp_ops.select_file	= pgp_select_file;
 4221|    295|	pgp_ops.list_files	= pgp_list_files;
 4222|    295|	pgp_ops.get_challenge	= pgp_get_challenge;
 4223|    295|	pgp_ops.read_binary	= pgp_read_binary;
 4224|    295|	pgp_ops.write_binary	= NULL;
 4225|    295|	pgp_ops.pin_cmd		= pgp_pin_cmd;
 4226|    295|	pgp_ops.logout		= pgp_logout;
 4227|    295|	pgp_ops.get_data	= pgp_get_data;
 4228|    295|	pgp_ops.put_data	= pgp_put_data;
 4229|    295|	pgp_ops.set_security_env= pgp_set_security_env;
 4230|    295|	pgp_ops.compute_signature= pgp_compute_signature;
 4231|    295|	pgp_ops.decipher	= pgp_decipher;
 4232|    295|	pgp_ops.card_ctl	= pgp_card_ctl;
 4233|    295|	pgp_ops.delete_file	= pgp_delete_file;
 4234|    295|	pgp_ops.update_binary	= pgp_update_binary;
 4235|    295|	pgp_ops.card_reader_lock_obtained = pgp_card_reader_lock_obtained;
 4236|       |
 4237|    295|	return &pgp_drv;
 4238|    295|}
card-openpgp.c:pgp_match_card:
  326|     51|{
  327|     51|	int i;
  328|       |
  329|     51|	LOG_FUNC_CALLED(card->ctx);
  ------------------
  |  |  151|     51|#define LOG_FUNC_CALLED(ctx) SC_FUNC_CALLED((ctx), SC_LOG_DEBUG_NORMAL)
  |  |  ------------------
  |  |  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  150|     51|} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  330|       |
  331|     51|	i = _sc_match_atr(card, pgp_atrs, &card->type);
  332|     51|	if (i >= 0) {
  ------------------
  |  Branch (332:6): [True: 0, False: 51]
  ------------------
  333|      0|		card->name = pgp_atrs[i].name;
  334|      0|		LOG_FUNC_RETURN(card->ctx, 1);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  335|      0|	}
  336|     51|	else {
  337|     51|		sc_path_t	partial_aid;
  338|     51|		sc_file_t *file = NULL;
  339|       |
  340|       |		/* select application "OpenPGP" */
  341|     51|		sc_format_path("D276:0001:2401", &partial_aid);
  342|     51|		partial_aid.type = SC_PATH_TYPE_DF_NAME;
  ------------------
  |  |  118|     51|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
  343|       |		/* OpenPGP card only supports selection *with* requested FCI */
  344|     51|		i = iso_ops->select_file(card, &partial_aid, &file);
  345|     51|		if (SC_SUCCESS == i) {
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  |  Branch (345:7): [True: 0, False: 51]
  ------------------
  346|      0|			card->type = SC_CARD_TYPE_OPENPGP_BASE;
  347|      0|			card->name = default_cardname;
  348|       |
  349|      0|			if (file->namelen != 16)
  ------------------
  |  Branch (349:8): [True: 0, False: 0]
  ------------------
  350|      0|				(void) get_full_pgp_aid(card, file);
  351|      0|			if (file->namelen == 16) {
  ------------------
  |  Branch (351:8): [True: 0, False: 0]
  ------------------
  352|      0|				unsigned char major = BCD2UCHAR(file->name[6]);
  ------------------
  |  |  216|      0|#define BCD2UCHAR(x) (((((x) & 0xF0) >> 4) * 10) + ((x) & 0x0F))
  ------------------
  353|       |
  354|      0|				switch (major) {
  355|      0|					case 1:
  ------------------
  |  Branch (355:6): [True: 0, False: 0]
  ------------------
  356|      0|						card->type = SC_CARD_TYPE_OPENPGP_V1;
  357|      0|						card->name = default_cardname_v1;
  358|      0|						break;
  359|      0|					case 2:
  ------------------
  |  Branch (359:6): [True: 0, False: 0]
  ------------------
  360|      0|						card->type = SC_CARD_TYPE_OPENPGP_V2;
  361|      0|						card->name = default_cardname_v2;
  362|      0|						break;
  363|      0|					case 3:
  ------------------
  |  Branch (363:6): [True: 0, False: 0]
  ------------------
  364|      0|						card->type = SC_CARD_TYPE_OPENPGP_V3;
  365|      0|						card->name = default_cardname_v3;
  366|      0|						break;
  367|      0|					default:
  ------------------
  |  Branch (367:6): [True: 0, False: 0]
  ------------------
  368|      0|						break;
  369|      0|				}
  370|      0|			}
  371|      0|			sc_file_free(file);
  372|      0|			LOG_FUNC_RETURN(card->ctx, 1);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  373|      0|		}
  374|     51|	}
  375|     51|	LOG_FUNC_RETURN(card->ctx, 0);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  376|     51|}
card-openpgp.c:pgp_card_reader_lock_obtained:
 4171|     51|{
 4172|     51|	struct pgp_priv_data *priv = DRVDATA(card); /* may be null during initialization */
  ------------------
  |  |  189|     51|#define DRVDATA(card)        ((struct pgp_priv_data *) ((card)->drv_data))
  ------------------
 4173|     51|	int r = SC_SUCCESS;
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
 4174|       |
 4175|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
 4176|       |
 4177|     51|	if (card->flags & SC_CARD_FLAG_KEEP_ALIVE
  ------------------
  |  |  544|    102|#define SC_CARD_FLAG_KEEP_ALIVE	0x00000004
  ------------------
  |  Branch (4177:6): [True: 0, False: 51]
  ------------------
 4178|      0|			&& was_reset <= 0
  ------------------
  |  Branch (4178:7): [True: 0, False: 0]
  ------------------
 4179|      0|			&& priv != NULL && priv->mf && priv->mf->file) {
  ------------------
  |  Branch (4179:7): [True: 0, False: 0]
  |  Branch (4179:23): [True: 0, False: 0]
  |  Branch (4179:35): [True: 0, False: 0]
  ------------------
 4180|       |		/* check whether applet is still selected */
 4181|      0|		unsigned char aid[16];
 4182|       |
 4183|      0|		r = sc_get_data(card, 0x004F, aid, sizeof aid);
 4184|      0|		if ((size_t) r != priv->mf->file->namelen
  ------------------
  |  Branch (4184:7): [True: 0, False: 0]
  ------------------
 4185|      0|				|| 0 != memcmp(aid, priv->mf->file->name, r)) {
  ------------------
  |  Branch (4185:8): [True: 0, False: 0]
  ------------------
 4186|       |			/* reselect is required */
 4187|      0|			was_reset = 1;
 4188|      0|		}
 4189|      0|		r = SC_SUCCESS;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
 4190|      0|	}
 4191|       |
 4192|     51|	if (was_reset > 0) {
  ------------------
  |  Branch (4192:6): [True: 0, False: 51]
  ------------------
 4193|      0|		sc_file_t	*file = NULL;
 4194|      0|		sc_path_t	path;
 4195|       |		/* select application "OpenPGP" */
 4196|      0|		sc_format_path("D276:0001:2401", &path);
 4197|      0|		path.type = SC_PATH_TYPE_DF_NAME;
  ------------------
  |  |  118|      0|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
 4198|      0|		r = iso_ops->select_file(card, &path, &file);
 4199|      0|		sc_file_free(file);
 4200|      0|	}
 4201|       |
 4202|     51|	LOG_FUNC_RETURN(card->ctx, r);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 4203|     51|}

sc_get_piv_driver:
 6476|    295|{
 6477|    295|	return sc_get_driver();
 6478|    295|}
card-piv.c:sc_get_driver:
 6449|    295|{
 6450|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 6451|       |
 6452|    295|	piv_ops = *iso_drv->ops;
 6453|    295|	piv_ops.match_card = piv_match_card;
 6454|    295|	piv_ops.init = piv_init;
 6455|    295|	piv_ops.finish = piv_finish;
 6456|       |
 6457|    295|	piv_ops.select_file = piv_select_file; /* must use get/put, could emulate? */
 6458|    295|	piv_ops.get_challenge = piv_get_challenge;
 6459|    295|	piv_ops.logout = piv_logout;
 6460|    295|	piv_ops.read_binary = piv_read_binary;
 6461|    295|	piv_ops.write_binary = piv_write_binary;
 6462|    295|	piv_ops.set_security_env = piv_set_security_env;
 6463|    295|	piv_ops.restore_security_env = piv_restore_security_env;
 6464|    295|	piv_ops.compute_signature = piv_compute_signature;
 6465|    295|	piv_ops.decipher = piv_decipher;
 6466|    295|	piv_ops.check_sw = piv_check_sw;
 6467|    295|	piv_ops.card_ctl = piv_card_ctl;
 6468|    295|	piv_ops.pin_cmd = piv_pin_cmd;
 6469|    295|	piv_ops.card_reader_lock_obtained = piv_card_reader_lock_obtained;
 6470|       |
 6471|    295|	return &piv_drv;
 6472|    295|}
card-piv.c:piv_match_card:
 5413|     51|{
 5414|     51|	int r = 0;
 5415|       |
 5416|     51|	sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d\n", card->type);
  ------------------
  |  |   70|     51|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5417|       |	/* piv_match_card may be called with card->type, set by opensc.conf */
 5418|       |	/* user provided card type must be one we know */
 5419|     51|	switch (card->type) {
 5420|     51|	case -1:
  ------------------
  |  Branch (5420:2): [True: 51, False: 0]
  ------------------
 5421|     51|	case SC_CARD_TYPE_PIV_II_BASE:
  ------------------
  |  Branch (5421:2): [True: 0, False: 51]
  ------------------
 5422|     51|	case SC_CARD_TYPE_PIV_II_GENERIC:
  ------------------
  |  Branch (5422:2): [True: 0, False: 51]
  ------------------
 5423|     51|	case SC_CARD_TYPE_PIV_II_HIST:
  ------------------
  |  Branch (5423:2): [True: 0, False: 51]
  ------------------
 5424|     51|	case SC_CARD_TYPE_PIV_II_NEO:
  ------------------
  |  Branch (5424:2): [True: 0, False: 51]
  ------------------
 5425|     51|	case SC_CARD_TYPE_PIV_II_YUBIKEY4:
  ------------------
  |  Branch (5425:2): [True: 0, False: 51]
  ------------------
 5426|     51|	case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC:
  ------------------
  |  Branch (5426:2): [True: 0, False: 51]
  ------------------
 5427|     51|	case SC_CARD_TYPE_PIV_II_GI_DE:
  ------------------
  |  Branch (5427:2): [True: 0, False: 51]
  ------------------
 5428|     51|	case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC:
  ------------------
  |  Branch (5428:2): [True: 0, False: 51]
  ------------------
 5429|     51|	case SC_CARD_TYPE_PIV_II_GEMALTO:
  ------------------
  |  Branch (5429:2): [True: 0, False: 51]
  ------------------
 5430|     51|	case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC:
  ------------------
  |  Branch (5430:2): [True: 0, False: 51]
  ------------------
 5431|     51|	case SC_CARD_TYPE_PIV_II_OBERTHUR:
  ------------------
  |  Branch (5431:2): [True: 0, False: 51]
  ------------------
 5432|     51|	case SC_CARD_TYPE_PIV_II_PIVKEY:
  ------------------
  |  Branch (5432:2): [True: 0, False: 51]
  ------------------
 5433|     51|	case SC_CARD_TYPE_PIV_II_SWISSBIT:
  ------------------
  |  Branch (5433:2): [True: 0, False: 51]
  ------------------
 5434|     51|	case SC_CARD_TYPE_PIV_II_800_73_4:
  ------------------
  |  Branch (5434:2): [True: 0, False: 51]
  ------------------
 5435|     51|	case SC_CARD_TYPE_PIV_II_NITROKEY:
  ------------------
  |  Branch (5435:2): [True: 0, False: 51]
  ------------------
 5436|     51|	case SC_CARD_TYPE_PIV_II_TOKEN2:
  ------------------
  |  Branch (5436:2): [True: 0, False: 51]
  ------------------
 5437|     51|	case SC_CARD_TYPE_PIV_II_PIVAPPLET:
  ------------------
  |  Branch (5437:2): [True: 0, False: 51]
  ------------------
 5438|     51|		break;
 5439|      0|	default:
  ------------------
  |  Branch (5439:2): [True: 0, False: 51]
  ------------------
 5440|      0|		return 0; /* can not handle the card */
 5441|     51|	}
 5442|       |
 5443|     51|	r = sc_lock(card);
 5444|     51|	if (r < 0)
  ------------------
  |  Branch (5444:6): [True: 0, False: 51]
  ------------------
 5445|      0|		return 0;
 5446|       |	/* its one we know, or we can test for it in piv_init */
 5447|     51|	r = piv_match_card_continued(card);
 5448|     51|	sc_unlock(card);
 5449|       |
 5450|     51|	if (r < 0 || !card->drv_data) {
  ------------------
  |  Branch (5450:6): [True: 51, False: 0]
  |  Branch (5450:15): [True: 0, False: 0]
  ------------------
 5451|       |		/* clean up what we left in card */
 5452|     51|		piv_finish(card);
 5453|     51|		return 0; /* match failed */
 5454|     51|	}
 5455|       |
 5456|      0|	sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r:%d\n", card->type, r);
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5457|      0|	return 1; /* matched */
 5458|     51|}
card-piv.c:piv_match_card_continued:
 5462|     51|{
 5463|     51|	int i, r = 0, r2 = 0;
 5464|     51|	int type = -1;
 5465|     51|	piv_private_data_t *priv = NULL;
 5466|     51|	int saved_type = card->type;
 5467|     51|	sc_apdu_t apdu;
 5468|     51|	u8 yubico_version_buf[3] = {0};
 5469|       |
 5470|       |	/* piv_match_card may be called with card->type, set by opensc.conf */
 5471|       |	/* User provided card type must be one we know */
 5472|       |
 5473|     51|	switch (card->type) {
 5474|     51|	case -1:
  ------------------
  |  Branch (5474:2): [True: 51, False: 0]
  ------------------
 5475|     51|	case SC_CARD_TYPE_PIV_II_BASE:
  ------------------
  |  Branch (5475:2): [True: 0, False: 51]
  ------------------
 5476|     51|	case SC_CARD_TYPE_PIV_II_GENERIC:
  ------------------
  |  Branch (5476:2): [True: 0, False: 51]
  ------------------
 5477|     51|	case SC_CARD_TYPE_PIV_II_HIST:
  ------------------
  |  Branch (5477:2): [True: 0, False: 51]
  ------------------
 5478|     51|	case SC_CARD_TYPE_PIV_II_NEO:
  ------------------
  |  Branch (5478:2): [True: 0, False: 51]
  ------------------
 5479|     51|	case SC_CARD_TYPE_PIV_II_YUBIKEY4:
  ------------------
  |  Branch (5479:2): [True: 0, False: 51]
  ------------------
 5480|     51|	case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC:
  ------------------
  |  Branch (5480:2): [True: 0, False: 51]
  ------------------
 5481|     51|	case SC_CARD_TYPE_PIV_II_GI_DE:
  ------------------
  |  Branch (5481:2): [True: 0, False: 51]
  ------------------
 5482|     51|	case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC:
  ------------------
  |  Branch (5482:2): [True: 0, False: 51]
  ------------------
 5483|     51|	case SC_CARD_TYPE_PIV_II_GEMALTO:
  ------------------
  |  Branch (5483:2): [True: 0, False: 51]
  ------------------
 5484|     51|	case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC:
  ------------------
  |  Branch (5484:2): [True: 0, False: 51]
  ------------------
 5485|     51|	case SC_CARD_TYPE_PIV_II_OBERTHUR:
  ------------------
  |  Branch (5485:2): [True: 0, False: 51]
  ------------------
 5486|     51|	case SC_CARD_TYPE_PIV_II_PIVKEY:
  ------------------
  |  Branch (5486:2): [True: 0, False: 51]
  ------------------
 5487|     51|	case SC_CARD_TYPE_PIV_II_SWISSBIT:
  ------------------
  |  Branch (5487:2): [True: 0, False: 51]
  ------------------
 5488|     51|	case SC_CARD_TYPE_PIV_II_800_73_4:
  ------------------
  |  Branch (5488:2): [True: 0, False: 51]
  ------------------
 5489|     51|	case SC_CARD_TYPE_PIV_II_NITROKEY:
  ------------------
  |  Branch (5489:2): [True: 0, False: 51]
  ------------------
 5490|     51|	case SC_CARD_TYPE_PIV_II_TOKEN2:
  ------------------
  |  Branch (5490:2): [True: 0, False: 51]
  ------------------
 5491|     51|	case SC_CARD_TYPE_PIV_II_PIVAPPLET:
  ------------------
  |  Branch (5491:2): [True: 0, False: 51]
  ------------------
 5492|     51|		type = card->type;
 5493|     51|		break;
 5494|      0|	default:
  ------------------
  |  Branch (5494:2): [True: 0, False: 51]
  ------------------
 5495|      0|		LOG_FUNC_RETURN(card->ctx, SC_ERROR_WRONG_CARD);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5496|     51|	}
 5497|     51|	sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r);
  ------------------
  |  |   70|     51|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5498|     51|	if (type == -1) {
  ------------------
  |  Branch (5498:6): [True: 51, False: 0]
  ------------------
 5499|       |		/*
 5500|       |		 * Try to identify card by ATR or historical data in ATR
 5501|       |		 * currently all PIV card will respond to piv_find_aid
 5502|       |		 * the same. But in future may need to know card type first,
 5503|       |		 * so do it here.
 5504|       |		 */
 5505|       |
 5506|     51|		if (card->reader->atr_info.hist_bytes != NULL) {
  ------------------
  |  Branch (5506:7): [True: 1, False: 50]
  ------------------
 5507|      1|			if (card->reader->atr_info.hist_bytes_len == 8 &&
  ------------------
  |  Branch (5507:8): [True: 0, False: 1]
  ------------------
 5508|      0|					!(memcmp(card->reader->atr_info.hist_bytes, "Yubikey4", 8))) {
  ------------------
  |  Branch (5508:6): [True: 0, False: 0]
  ------------------
 5509|      0|				type = SC_CARD_TYPE_PIV_II_YUBIKEY4;
 5510|      1|			} else if (card->reader->atr_info.hist_bytes_len >= 7 &&
  ------------------
  |  Branch (5510:15): [True: 0, False: 1]
  ------------------
 5511|      0|					!(memcmp(card->reader->atr_info.hist_bytes, "Yubikey", 7))) {
  ------------------
  |  Branch (5511:6): [True: 0, False: 0]
  ------------------
 5512|      0|				type = SC_CARD_TYPE_PIV_II_NEO;
 5513|      1|			} else if (card->reader->atr_info.hist_bytes_len >= 6 &&
  ------------------
  |  Branch (5513:15): [True: 0, False: 1]
  ------------------
 5514|      0|					!(memcmp(card->reader->atr_info.hist_bytes, "PIVKEY", 6))) {
  ------------------
  |  Branch (5514:6): [True: 0, False: 0]
  ------------------
 5515|      0|				type = SC_CARD_TYPE_PIV_II_PIVKEY;
 5516|      1|			} else if (card->reader->atr_info.hist_bytes_len >= 6 &&
  ------------------
  |  Branch (5516:15): [True: 0, False: 1]
  ------------------
 5517|      0|					!(memcmp(card->reader->atr_info.hist_bytes, (u8 *)"TK\x00PIV", 6))) {
  ------------------
  |  Branch (5517:6): [True: 0, False: 0]
  ------------------
 5518|      0|				type = SC_CARD_TYPE_PIV_II_TOKEN2;
 5519|      0|			}
 5520|       |			/* look for TLV historic data */
 5521|      1|			else if (card->reader->atr_info.hist_bytes_len > 0 &&
  ------------------
  |  Branch (5521:13): [True: 1, False: 0]
  ------------------
 5522|      1|					card->reader->atr_info.hist_bytes[0] == 0x80u) { /* compact TLV */
  ------------------
  |  Branch (5522:6): [True: 1, False: 0]
  ------------------
 5523|      1|				size_t datalen;
 5524|      1|				const u8 *data;
 5525|       |
 5526|       |				/* look for card issuer's data:  tag 5X where X is datalen */
 5527|      1|				if ((data = sc_compacttlv_find_tag(card->reader->atr_info.hist_bytes + 1,
  ------------------
  |  Branch (5527:9): [True: 0, False: 1]
  ------------------
 5528|      1|						     card->reader->atr_info.hist_bytes_len - 1, 0x50, &datalen))) {
 5529|      0|					if (datalen >= 8 && !(memcmp(data, "Nitrokey", 8))) { /* first 8 are Nitrokey */
  ------------------
  |  Branch (5529:10): [True: 0, False: 0]
  |  Branch (5529:26): [True: 0, False: 0]
  ------------------
 5530|      0|						type = SC_CARD_TYPE_PIV_II_NITROKEY;
 5531|      0|					} else if (datalen == 7 && !(memcmp(data, "YubiKey", 7))) {
  ------------------
  |  Branch (5531:17): [True: 0, False: 0]
  |  Branch (5531:33): [True: 0, False: 0]
  ------------------
 5532|      0|						type = SC_CARD_TYPE_PIV_II_YUBIKEY4; /* reader says 4  really 5 */
 5533|      0|					}
 5534|       |					/* Yubikey 5 NFC ATR using ACR122 contactless reader does not match
 5535|       |					 * https://developers.yubico.com/PIV/Introduction/Yubico_extensions.html
 5536|       |					 * On Windows 10, using Omnikey 5021, the ATR is correct
 5537|       |					 * will look at only 6 bytes that do match
 5538|       |					 */
 5539|      0|					else if (datalen == 7 && !(memcmp(data, "YubiKe", 6))) {
  ------------------
  |  Branch (5539:15): [True: 0, False: 0]
  |  Branch (5539:31): [True: 0, False: 0]
  ------------------
 5540|      0|						type = SC_CARD_TYPE_PIV_II_YUBIKEY4; /* reader says 4 really 5 */
 5541|      0|					}
 5542|      1|				} else if ((data = sc_compacttlv_find_tag(card->reader->atr_info.hist_bytes + 1,
  ------------------
  |  Branch (5542:16): [True: 0, False: 1]
  ------------------
 5543|      1|							    card->reader->atr_info.hist_bytes_len - 1, 0xF0, &datalen))) {
 5544|      0|					int k;
 5545|       |
 5546|      0|					for (k = 0; piv_aids[k].len_long != 0; k++) {
  ------------------
  |  Branch (5546:18): [True: 0, False: 0]
  ------------------
 5547|      0|						if (datalen == piv_aids[k].len_long &&
  ------------------
  |  Branch (5547:11): [True: 0, False: 0]
  ------------------
 5548|      0|								!memcmp(data, piv_aids[k].value, datalen)) {
  ------------------
  |  Branch (5548:9): [True: 0, False: 0]
  ------------------
 5549|      0|							type = SC_CARD_TYPE_PIV_II_HIST;
 5550|      0|							break;
 5551|      0|						}
 5552|      0|					}
 5553|      0|				}
 5554|      1|			}
 5555|      1|		}
 5556|       |
 5557|     51|		sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r);
  ------------------
  |  |   70|     51|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5558|       |
 5559|     51|		if (type == -1) {
  ------------------
  |  Branch (5559:7): [True: 51, False: 0]
  ------------------
 5560|       |			/* use known ATRs  which changes the type */
 5561|     51|			i = _sc_match_atr(card, piv_atrs, &type);
 5562|     51|			if (i < 0)
  ------------------
  |  Branch (5562:8): [True: 51, False: 0]
  ------------------
 5563|     51|				type = SC_CARD_TYPE_PIV_II_BASE; /* May be some newer unknown card including CAC or PIV-like card */
 5564|     51|		}
 5565|     51|	}
 5566|       |
 5567|     51|	card->type = type;
 5568|       |
 5569|       |	/* we either found via ATR historic bytes or ATR directly */
 5570|     51|	sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d type:%d r:%d\n", card->type, type, r);
  ------------------
  |  |   70|     51|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5571|       |
 5572|       |	/* allocate and init basic fields */
 5573|     51|	priv = calloc(1, sizeof(piv_private_data_t));
 5574|       |
 5575|     51|	if (!priv)
  ------------------
  |  Branch (5575:6): [True: 0, False: 51]
  ------------------
 5576|     51|		LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5577|       |
 5578|     51|	card->drv_data = priv; /* will free if no match, or pass on to piv_init */
 5579|       |	/*
 5580|       |	 * Largest object defined in NIST sp800-73-3 and sp800-73-4 is 12710 bytes
 5581|       |	 * If for some reason future cards have larger objects, this value needs to
 5582|       |	 * be increased here.
 5583|       |	 */
 5584|     51|	priv->max_object_size = MAX_FILE_SIZE - 256; /* fix SM apdu resplen issue */
  ------------------
  |  |  229|     51|#define MAX_FILE_SIZE 65535
  ------------------
 5585|     51|	priv->selected_obj = -1;
 5586|     51|	priv->pin_preference = 0x80; /* 800-73-3 part 1, table 3 */
 5587|     51|	priv->logged_in = SC_PIN_STATE_UNKNOWN;
  ------------------
  |  |  437|     51|#define SC_PIN_STATE_UNKNOWN	0
  ------------------
 5588|     51|	priv->pstate = PIV_STATE_MATCH;
 5589|       |
 5590|       |#ifdef ENABLE_PIV_SM
 5591|       |	memset(&card->sm_ctx, 0, sizeof card->sm_ctx);
 5592|       |	card->sm_ctx.ops.open = piv_sm_open;
 5593|       |	card->sm_ctx.ops.get_sm_apdu = piv_get_sm_apdu;
 5594|       |	card->sm_ctx.ops.free_sm_apdu = piv_free_sm_apdu;
 5595|       |	card->sm_ctx.ops.close = piv_sm_close;
 5596|       |#endif /* ENABLE_PIV_SM */
 5597|       |
 5598|       |	/* See if contactless  or run as virtual card */
 5599|       |	/* PivApplet in .github/test_piv.sh for example */
 5600|     51|	if (card->reader->atr.len >= 4 &&
  ------------------
  |  Branch (5600:6): [True: 5, False: 46]
  ------------------
 5601|      5|			card->reader->atr.value[0] == 0x3b &&
  ------------------
  |  Branch (5601:4): [True: 2, False: 3]
  ------------------
 5602|      2|			(card->reader->atr.value[1] & 0xF0) == 0x80 &&
  ------------------
  |  Branch (5602:4): [True: 0, False: 2]
  ------------------
 5603|      0|			card->reader->atr.value[2] == 0x80 &&
  ------------------
  |  Branch (5603:4): [True: 0, False: 0]
  ------------------
 5604|      0|			card->reader->atr.value[3] == 0x01) {
  ------------------
  |  Branch (5604:4): [True: 0, False: 0]
  ------------------
 5605|      0|		priv->init_flags |= PIV_INIT_CONTACTLESS;
  ------------------
  |  |  382|      0|#define PIV_INIT_CONTACTLESS			0x00000020u
  ------------------
 5606|      0|	}
 5607|       |
 5608|  3.11k|	for (i = 0; i < PIV_OBJ_LAST_ENUM - 1; i++)
  ------------------
  |  Branch (5608:14): [True: 3.06k, False: 51]
  ------------------
 5609|  3.06k|		if (piv_objects[i].flags & PIV_OBJECT_NOT_PRESENT)
  ------------------
  |  |  638|  3.06k|#define PIV_OBJECT_NOT_PRESENT		0x04
  ------------------
  |  Branch (5609:7): [True: 1.02k, False: 2.04k]
  ------------------
 5610|  1.02k|			priv->obj_cache[i].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
  ------------------
  |  |  150|  1.07k|#define PIV_OBJ_CACHE_NOT_PRESENT	8
  ------------------
 5611|       |	/*
 5612|       |	 * Detect if active AID is PIV. NIST 800-73 says only one PIV application per card
 5613|       |	 * and PIV must be the default application.
 5614|       |	 * Try to avoid doing a select_aid and losing the login state on some cards.
 5615|       |	 * We may get interference on some cards by other drivers trying SELECT_AID before
 5616|       |	 * we get to see if PIV application is still active. Putting PIV driver first might help.
 5617|       |	 *
 5618|       |	 * Discovery Object introduced in 800-73-3 so will return OK if found and PIV applet active.
 5619|       |	 * Will fail with SC_ERROR_FILE_NOT_FOUND if 800-73-3 and no Discovery object.
 5620|       |	 * But some other card could also return SC_ERROR_FILE_NOT_FOUND.
 5621|       |	 * Will fail for other reasons if wrong applet is selected or bad PIV implementation.
 5622|       |	 */
 5623|       |
 5624|       |	/*
 5625|       |	 * if ATR matched or user forced card type
 5626|       |	 * test if PIV is active applet without using AID If fails try AID
 5627|       |	 */
 5628|       |
 5629|     51|	if (card->type > SC_CARD_TYPE_PIV_II_BASE &&
  ------------------
  |  Branch (5629:6): [True: 0, False: 51]
  ------------------
 5630|      0|			!(priv->init_flags & PIV_INIT_CONTACTLESS)) {
  ------------------
  |  |  382|      0|#define PIV_INIT_CONTACTLESS			0x00000020u
  ------------------
  |  Branch (5630:4): [True: 0, False: 0]
  ------------------
 5631|      0|		r = piv_find_discovery(card);
 5632|      0|		if (r < 0) {
  ------------------
  |  Branch (5632:7): [True: 0, False: 0]
  ------------------
 5633|      0|			piv_obj_cache_free_entry(card, PIV_OBJ_DISCOVERY, 0); /* don't cache  on failure */
 5634|      0|			r = piv_find_aid(card);
 5635|      0|			LOG_TEST_GOTO_ERR(card->ctx, r, "Not a PIV card");
  ------------------
  |  |  184|      0|#define LOG_TEST_GOTO_ERR(ctx, r, text) SC_TEST_GOTO_ERR((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  176|      0|#define SC_TEST_GOTO_ERR(ctx, level, r, text) do { \
  |  |  |  |  177|      0|	int _ret = (r); \
  |  |  |  |  178|      0|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (178:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  179|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  180|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  181|      0|		goto err; \
  |  |  |  |  182|      0|	} \
  |  |  |  |  183|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (183:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5636|      0|		}
 5637|     51|	} else {
 5638|       |		/* piv_find_aid saves al_label from response */
 5639|     51|		r = piv_find_aid(card);
 5640|     51|		LOG_TEST_GOTO_ERR(card->ctx, r, "Not a PIV card");
  ------------------
  |  |  184|     51|#define LOG_TEST_GOTO_ERR(ctx, r, text) SC_TEST_GOTO_ERR((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  176|     51|#define SC_TEST_GOTO_ERR(ctx, level, r, text) do { \
  |  |  |  |  177|     51|	int _ret = (r); \
  |  |  |  |  178|     51|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (178:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  179|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|     51|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  180|     51|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  181|     51|		goto err; \
  |  |  |  |  182|     51|	} \
  |  |  |  |  183|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (183:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5641|     51|	}
 5642|       |
 5643|       |	/* Know to be PIV card but not the type */
 5644|       |
 5645|       |	/* If card type still unknown, see if Application Label is known and set card->type */
 5646|      0|	if (priv->al_label && priv->al_labellen) {
  ------------------
  |  Branch (5646:6): [True: 0, False: 0]
  |  Branch (5646:24): [True: 0, False: 0]
  ------------------
 5647|      0|		switch (card->type) {
  ------------------
  |  Branch (5647:11): [True: 0, False: 0]
  ------------------
 5648|      0|		case SC_CARD_TYPE_PIV_II_BASE:
  ------------------
  |  Branch (5648:3): [True: 0, False: 0]
  ------------------
 5649|      0|		case SC_CARD_TYPE_PIV_II_GENERIC:
  ------------------
  |  Branch (5649:3): [True: 0, False: 0]
  ------------------
 5650|      0|			for (i = 0; al_map[i].al_label; i++) {
  ------------------
  |  Branch (5650:16): [True: 0, False: 0]
  ------------------
 5651|      0|				if ((priv->al_labellen >= al_map[i].al_labellen) &&
  ------------------
  |  Branch (5651:9): [True: 0, False: 0]
  ------------------
 5652|      0|						(!memcmp(priv->al_label, al_map[i].al_label, al_map[i].al_labellen))) {
  ------------------
  |  Branch (5652:7): [True: 0, False: 0]
  ------------------
 5653|      0|					sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "AL match i:%d type:%d", i, al_map[i].al_type);
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5654|      0|					card->type = al_map[i].al_type;
 5655|      0|					break;
 5656|      0|				}
 5657|      0|			}
 5658|      0|			break;
 5659|      0|		}
 5660|      0|	}
 5661|       |
 5662|      0|	sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d  CI:%08x r:%d AI:%08x\n",
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5663|      0|			card->type, priv->card_issues, r, priv->alg_ids);
 5664|       |
 5665|       |	/*
 5666|       |	 * Assumes all Yubikey/Nitrokey/Token2/PivApplet cards are all "Yubico like"
 5667|       |	 * via ATR, ATR Historic bytes or Application Label
 5668|       |	 * Will also check if BASE cards are Yubikey like card and return a version number
 5669|       |	 * SC_CARD_TYPE_PIV_II_GENERIC can be set by user to not test for Yubico version
 5670|       |	 */
 5671|      0|	switch (card->type) {
  ------------------
  |  Branch (5671:10): [True: 0, False: 0]
  ------------------
 5672|      0|	case SC_CARD_TYPE_PIV_II_NEO:
  ------------------
  |  Branch (5672:2): [True: 0, False: 0]
  ------------------
 5673|      0|	case SC_CARD_TYPE_PIV_II_YUBIKEY4:
  ------------------
  |  Branch (5673:2): [True: 0, False: 0]
  ------------------
 5674|      0|	case SC_CARD_TYPE_PIV_II_NITROKEY:
  ------------------
  |  Branch (5674:2): [True: 0, False: 0]
  ------------------
 5675|      0|	case SC_CARD_TYPE_PIV_II_TOKEN2:
  ------------------
  |  Branch (5675:2): [True: 0, False: 0]
  ------------------
 5676|      0|	case SC_CARD_TYPE_PIV_II_PIVAPPLET:
  ------------------
  |  Branch (5676:2): [True: 0, False: 0]
  ------------------
 5677|      0|	case SC_CARD_TYPE_PIV_II_GENERIC:
  ------------------
  |  Branch (5677:2): [True: 0, False: 0]
  ------------------
 5678|      0|	case SC_CARD_TYPE_PIV_II_BASE: /* unknown PIV card */
  ------------------
  |  Branch (5678:2): [True: 0, False: 0]
  ------------------
 5679|      0|		sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xFD, 0x00, 0x00);
  ------------------
  |  |  292|      0|#define SC_APDU_CASE_2_SHORT		0x02
  ------------------
 5680|      0|		apdu.lc = 0;
 5681|      0|		apdu.data = NULL;
 5682|      0|		apdu.datalen = 0;
 5683|      0|		apdu.resp = yubico_version_buf;
 5684|      0|		apdu.resplen = sizeof(yubico_version_buf);
 5685|      0|		apdu.le = apdu.resplen;
 5686|      0|		r2 = sc_transmit_apdu(card, &apdu); /* if not supported yubico_version == 0 */
 5687|      0|		if (apdu.resplen == 3) {
  ------------------
  |  Branch (5687:7): [True: 0, False: 0]
  ------------------
 5688|      0|			priv->yubico_version = (yubico_version_buf[0] << 16) | (yubico_version_buf[1] << 8) | yubico_version_buf[2];
 5689|      0|			sc_log(card->ctx, "Yubikey version test card->type=%d, r=0x%08x version=0x%08x", card->type, r, priv->yubico_version);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5690|      0|		}
 5691|      0|		break;
 5692|      0|	}
 5693|       |
 5694|      0|	sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5695|      0|			card->type, r2, priv->card_issues, r, priv->alg_ids);
 5696|       |
 5697|       |	/* We now know PIV AID is active, test CCC object. 800-73-* say CCC is required */
 5698|       |	/* CCC not readable over contactless, unless using VCI. but dont need CCC for SC_CARD_TYPE_PIV_II_800_73_4 */
 5699|      0|	switch (card->type) {
  ------------------
  |  Branch (5699:10): [True: 0, False: 0]
  ------------------
 5700|       |	/*
 5701|       |	 * For cards that may also be CAC, try and read the CCC
 5702|       |	 * CCC is required and all Dual PIV/CAC will have a CCC
 5703|       |	 * Currently Dual PIV/CAC are based on NIST 800-73-1 which does not have Discovery or History
 5704|       |	 */
 5705|      0|	case SC_CARD_TYPE_PIV_II_BASE: /* i.e. really dont know what this is */
  ------------------
  |  Branch (5705:2): [True: 0, False: 0]
  ------------------
 5706|      0|	case SC_CARD_TYPE_PIV_II_GENERIC:
  ------------------
  |  Branch (5706:2): [True: 0, False: 0]
  ------------------
 5707|      0|	case SC_CARD_TYPE_PIV_II_HIST:
  ------------------
  |  Branch (5707:2): [True: 0, False: 0]
  ------------------
 5708|      0|	case SC_CARD_TYPE_PIV_II_GI_DE:
  ------------------
  |  Branch (5708:2): [True: 0, False: 0]
  ------------------
 5709|      0|	case SC_CARD_TYPE_PIV_II_GEMALTO:
  ------------------
  |  Branch (5709:2): [True: 0, False: 0]
  ------------------
 5710|      0|	case SC_CARD_TYPE_PIV_II_OBERTHUR:
  ------------------
  |  Branch (5710:2): [True: 0, False: 0]
  ------------------
 5711|      0|		r2 = piv_process_ccc(card);
 5712|      0|		sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5713|      0|				card->type, r2, priv->card_issues, r, priv->alg_ids);
 5714|       |		/* Ignore any error. */
 5715|       |		/* If CCC says it has CAC with PKI on card set to one of the SC_CARD_TYPE_PIV_II_*_DUAL_CAC */
 5716|      0|		if (priv->ccc_flags & PIV_CCC_F3_CAC_PKI) {
  ------------------
  |  |  171|      0|#define PIV_CCC_F3_CAC_PKI	0x00000010
  ------------------
  |  Branch (5716:7): [True: 0, False: 0]
  ------------------
 5717|      0|			switch (card->type) {
  ------------------
  |  Branch (5717:12): [True: 0, False: 0]
  ------------------
 5718|      0|			case SC_CARD_TYPE_PIV_II_BASE:
  ------------------
  |  Branch (5718:4): [True: 0, False: 0]
  ------------------
 5719|      0|			case SC_CARD_TYPE_PIV_II_GENERIC:
  ------------------
  |  Branch (5719:4): [True: 0, False: 0]
  ------------------
 5720|      0|			case SC_CARD_TYPE_PIV_II_HIST:
  ------------------
  |  Branch (5720:4): [True: 0, False: 0]
  ------------------
 5721|      0|			case SC_CARD_TYPE_PIV_II_GI_DE:
  ------------------
  |  Branch (5721:4): [True: 0, False: 0]
  ------------------
 5722|      0|				card->type = SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC;
 5723|      0|				priv->card_issues |= CI_DISCOVERY_USELESS;
  ------------------
  |  |  582|      0|#define CI_DISCOVERY_USELESS		    0x00000020U /* Discovery can not be used to query active AID invalid or no data returned */
  ------------------
 5724|      0|				priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
  ------------------
  |  |  150|      0|#define PIV_OBJ_CACHE_NOT_PRESENT	8
  ------------------
 5725|      0|				break;
 5726|      0|			case SC_CARD_TYPE_PIV_II_GEMALTO:
  ------------------
  |  Branch (5726:4): [True: 0, False: 0]
  ------------------
 5727|      0|				card->type = SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC;
 5728|      0|				priv->card_issues |= CI_DISCOVERY_USELESS;
  ------------------
  |  |  582|      0|#define CI_DISCOVERY_USELESS		    0x00000020U /* Discovery can not be used to query active AID invalid or no data returned */
  ------------------
 5729|      0|				priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
  ------------------
  |  |  150|      0|#define PIV_OBJ_CACHE_NOT_PRESENT	8
  ------------------
 5730|      0|				break;
 5731|      0|			case SC_CARD_TYPE_PIV_II_OBERTHUR:
  ------------------
  |  Branch (5731:4): [True: 0, False: 0]
  ------------------
 5732|      0|				card->type = SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC;
 5733|      0|				priv->card_issues |= CI_DISCOVERY_USELESS;
  ------------------
  |  |  582|      0|#define CI_DISCOVERY_USELESS		    0x00000020U /* Discovery can not be used to query active AID invalid or no data returned */
  ------------------
 5734|      0|				priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
  ------------------
  |  |  150|      0|#define PIV_OBJ_CACHE_NOT_PRESENT	8
  ------------------
 5735|      0|				break;
 5736|      0|			}
 5737|      0|		}
 5738|      0|		break;
 5739|       |
 5740|      0|	case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC:
  ------------------
  |  Branch (5740:2): [True: 0, False: 0]
  ------------------
 5741|      0|	case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC:
  ------------------
  |  Branch (5741:2): [True: 0, False: 0]
  ------------------
 5742|      0|	case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC:
  ------------------
  |  Branch (5742:2): [True: 0, False: 0]
  ------------------
 5743|      0|		priv->card_issues |= CI_DISCOVERY_USELESS;
  ------------------
  |  |  582|      0|#define CI_DISCOVERY_USELESS		    0x00000020U /* Discovery can not be used to query active AID invalid or no data returned */
  ------------------
 5744|      0|		priv->obj_cache[PIV_OBJ_DISCOVERY].flags |= PIV_OBJ_CACHE_NOT_PRESENT;
  ------------------
  |  |  150|      0|#define PIV_OBJ_CACHE_NOT_PRESENT	8
  ------------------
 5745|      0|		break;
 5746|      0|	}
 5747|      0|	sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5748|      0|			card->type, r2, priv->card_issues, r, priv->alg_ids);
 5749|       |
 5750|       |	/* If contactless or run as virtual card try to get alg refs from AC entries in response to SELECT AID */
 5751|      0|	if (!(priv->init_flags & PIV_INIT_AID_PARSED) && priv->init_flags & PIV_INIT_CONTACTLESS) {
  ------------------
  |  |  377|      0|#define PIV_INIT_AID_PARSED			0x00000001u
  ------------------
              	if (!(priv->init_flags & PIV_INIT_AID_PARSED) && priv->init_flags & PIV_INIT_CONTACTLESS) {
  ------------------
  |  |  382|      0|#define PIV_INIT_CONTACTLESS			0x00000020u
  ------------------
  |  Branch (5751:6): [True: 0, False: 0]
  |  Branch (5751:51): [True: 0, False: 0]
  ------------------
 5752|      0|		r2 = piv_find_aid(card);
 5753|      0|	}
 5754|       |
 5755|       |	/* Read AID if needed for these cards types */
 5756|      0|	if (!(priv->init_flags & PIV_INIT_AID_PARSED)) {
  ------------------
  |  |  377|      0|#define PIV_INIT_AID_PARSED			0x00000001u
  ------------------
  |  Branch (5756:6): [True: 0, False: 0]
  ------------------
 5757|      0|		switch (card->type) {
  ------------------
  |  Branch (5757:11): [True: 0, False: 0]
  ------------------
 5758|      0|		case SC_CARD_TYPE_PIV_II_BASE:
  ------------------
  |  Branch (5758:3): [True: 0, False: 0]
  ------------------
 5759|      0|		case SC_CARD_TYPE_PIV_II_GENERIC:
  ------------------
  |  Branch (5759:3): [True: 0, False: 0]
  ------------------
 5760|      0|		case SC_CARD_TYPE_PIV_II_800_73_4:
  ------------------
  |  Branch (5760:3): [True: 0, False: 0]
  ------------------
 5761|      0|		case SC_CARD_TYPE_PIV_II_NITROKEY:
  ------------------
  |  Branch (5761:3): [True: 0, False: 0]
  ------------------
 5762|      0|		case SC_CARD_TYPE_PIV_II_TOKEN2:
  ------------------
  |  Branch (5762:3): [True: 0, False: 0]
  ------------------
 5763|      0|		case SC_CARD_TYPE_PIV_II_PIVAPPLET:
  ------------------
  |  Branch (5763:3): [True: 0, False: 0]
  ------------------
 5764|      0|			r2 = piv_find_aid(card);
 5765|      0|		}
 5766|      0|	}
 5767|       |
 5768|      0|	sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5769|      0|			card->type, r2, priv->card_issues, r, priv->alg_ids);
 5770|       |
 5771|       |	/* if card did not specify any of the NIST basic alg_ids add them */
 5772|      0|	if ((priv->alg_ids & AI_NIST) == 0) {
  ------------------
  |  |  601|      0|#define AI_NIST (AI_RSA_1024 | AI_RSA_2048 | AI_RSA_3072 | AI_EC_256 | AI_EC_384)
  |  |  ------------------
  |  |  |  |  592|      0|#define AI_RSA_1024			    0x00000001U
  |  |  ------------------
  |  |               #define AI_NIST (AI_RSA_1024 | AI_RSA_2048 | AI_RSA_3072 | AI_EC_256 | AI_EC_384)
  |  |  ------------------
  |  |  |  |  593|      0|#define AI_RSA_2048			    0x00000002U
  |  |  ------------------
  |  |               #define AI_NIST (AI_RSA_1024 | AI_RSA_2048 | AI_RSA_3072 | AI_EC_256 | AI_EC_384)
  |  |  ------------------
  |  |  |  |  594|      0|#define AI_RSA_3072			    0x00000004U
  |  |  ------------------
  |  |               #define AI_NIST (AI_RSA_1024 | AI_RSA_2048 | AI_RSA_3072 | AI_EC_256 | AI_EC_384)
  |  |  ------------------
  |  |  |  |  596|      0|#define AI_EC_256			    0x00000100U
  |  |  ------------------
  |  |               #define AI_NIST (AI_RSA_1024 | AI_RSA_2048 | AI_RSA_3072 | AI_EC_256 | AI_EC_384)
  |  |  ------------------
  |  |  |  |  597|      0|#define AI_EC_384			    0x00000200U
  |  |  ------------------
  ------------------
  |  Branch (5772:6): [True: 0, False: 0]
  ------------------
 5773|      0|		priv->alg_ids |= AI_NIST;
  ------------------
  |  |  601|      0|#define AI_NIST (AI_RSA_1024 | AI_RSA_2048 | AI_RSA_3072 | AI_EC_256 | AI_EC_384)
  |  |  ------------------
  |  |  |  |  592|      0|#define AI_RSA_1024			    0x00000001U
  |  |  ------------------
  |  |               #define AI_NIST (AI_RSA_1024 | AI_RSA_2048 | AI_RSA_3072 | AI_EC_256 | AI_EC_384)
  |  |  ------------------
  |  |  |  |  593|      0|#define AI_RSA_2048			    0x00000002U
  |  |  ------------------
  |  |               #define AI_NIST (AI_RSA_1024 | AI_RSA_2048 | AI_RSA_3072 | AI_EC_256 | AI_EC_384)
  |  |  ------------------
  |  |  |  |  594|      0|#define AI_RSA_3072			    0x00000004U
  |  |  ------------------
  |  |               #define AI_NIST (AI_RSA_1024 | AI_RSA_2048 | AI_RSA_3072 | AI_EC_256 | AI_EC_384)
  |  |  ------------------
  |  |  |  |  596|      0|#define AI_EC_256			    0x00000100U
  |  |  ------------------
  |  |               #define AI_NIST (AI_RSA_1024 | AI_RSA_2048 | AI_RSA_3072 | AI_EC_256 | AI_EC_384)
  |  |  ------------------
  |  |  |  |  597|      0|#define AI_EC_384			    0x00000200U
  |  |  ------------------
  ------------------
 5774|      0|	}
 5775|       |
 5776|       |	/* If unknown card has 800-73-4 features, it must be based on 800-73-4 or above */
 5777|      0|	switch (card->type) {
  ------------------
  |  Branch (5777:10): [True: 0, False: 0]
  ------------------
 5778|      0|	case SC_CARD_TYPE_PIV_II_BASE:
  ------------------
  |  Branch (5778:2): [True: 0, False: 0]
  ------------------
 5779|      0|	case SC_CARD_TYPE_PIV_II_GENERIC:
  ------------------
  |  Branch (5779:2): [True: 0, False: 0]
  ------------------
 5780|      0|		if (priv->init_flags & PIV_INIT_AID_AC_SM) {
  ------------------
  |  |  378|      0|#define PIV_INIT_AID_AC_SM			0x00000002u
  ------------------
  |  Branch (5780:7): [True: 0, False: 0]
  ------------------
 5781|      0|			card->type = SC_CARD_TYPE_PIV_II_800_73_4;
 5782|      0|		}
 5783|       |
 5784|       |#ifdef ENABLE_PIV_SM
 5785|       |		/* Discovery object has pin policy. 800-74-4 bits, its at least SC_CARD_TYPE_PIV_II_800_73_4 */
 5786|       |		if ((priv->pin_policy & (PIV_PP_OCC | PIV_PP_VCI_IMPL | PIV_PP_VCI_WITHOUT_PC)) != 0) {
 5787|       |			card->type = SC_CARD_TYPE_PIV_II_800_73_4;
 5788|       |		}
 5789|       |#endif
 5790|      0|		break;
 5791|      0|	}
 5792|       |
 5793|      0|	sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5794|      0|			card->type, r2, priv->card_issues, r, priv->alg_ids);
 5795|       |
 5796|       |	/*
 5797|       |	 * Set card_issues flags based card->type and version numbers if available.
 5798|       |	 *
 5799|       |	 * YubiKey NEO, Yubikey 4 and other devices with PIV applets, have compliance
 5800|       |	 * issues with the NIST 800-73-3 specs. The OpenSC developers do not have
 5801|       |	 * access to all the different devices or versions of the devices.
 5802|       |	 * Vendor and user input is welcome on any compliance issues.
 5803|       |	 *
 5804|       |	 * For the Yubico devices The assumption is also made that if a bug is
 5805|       |	 * fixed in a Yubico version that means it is fixed on both NEO and Yubikey 4.
 5806|       |	 *
 5807|       |	 * The flags CI_CANT_USE_GETDATA_FOR_STATE and CI_DISCOVERY_USELESS
 5808|       |	 * may be set earlier or later then in the following code.
 5809|       |	 */
 5810|       |
 5811|      0|	sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5812|      0|			card->type, r2, priv->card_issues, r, priv->alg_ids);
 5813|      0|	switch (card->type) {
 5814|      0|	case SC_CARD_TYPE_PIV_II_NEO:
  ------------------
  |  Branch (5814:2): [True: 0, False: 0]
  ------------------
 5815|      0|		priv->card_issues |= CI_NO_EC384 |
  ------------------
  |  |  588|      0|#define CI_NO_EC384			    0x00000400U /* does not have EC 384 */
  ------------------
 5816|      0|				     CI_VERIFY_630X |
  ------------------
  |  |  576|      0|#define CI_VERIFY_630X			    0x00000001U /* VERIFY tries left returns 630X rather then 63CX */
  ------------------
 5817|      0|				     CI_OTHER_AID_LOSE_STATE |
  ------------------
  |  |  585|      0|#define CI_OTHER_AID_LOSE_STATE		    0x00000100U /* Other drivers match routines may reset our security state and lose AID!!! */
  ------------------
 5818|      0|				     CI_LEAKS_FILE_NOT_FOUND |
  ------------------
  |  |  581|      0|#define CI_LEAKS_FILE_NOT_FOUND		    0x00000010U /* GET DATA of empty object returns 6A 82 even if PIN not verified */
  ------------------
 5819|      0|				     CI_NFC_EXPOSE_TOO_MUCH;
  ------------------
  |  |  586|      0|#define CI_NFC_EXPOSE_TOO_MUCH		    0x00000200U /* PIN, crypto and objects exposed over NFS in violation of 800-73-3 */
  ------------------
 5820|      0|		if (priv->yubico_version < 0x00040302)
  ------------------
  |  Branch (5820:7): [True: 0, False: 0]
  ------------------
 5821|      0|			priv->card_issues |= CI_VERIFY_LC0_FAIL;
  ------------------
  |  |  577|      0|#define CI_VERIFY_LC0_FAIL		    0x00000002U /* VERIFY Lc=0 never returns 90 00 if PIN not needed */
  ------------------
 5822|      0|		break;
 5823|       |
 5824|      0|	case SC_CARD_TYPE_PIV_II_YUBIKEY4:
  ------------------
  |  Branch (5824:2): [True: 0, False: 0]
  ------------------
 5825|      0|	case SC_CARD_TYPE_PIV_II_PIVAPPLET:
  ------------------
  |  Branch (5825:2): [True: 0, False: 0]
  ------------------
 5826|      0|	case SC_CARD_TYPE_PIV_II_TOKEN2:
  ------------------
  |  Branch (5826:2): [True: 0, False: 0]
  ------------------
 5827|      0|		priv->card_issues |= CI_OTHER_AID_LOSE_STATE |
  ------------------
  |  |  585|      0|#define CI_OTHER_AID_LOSE_STATE		    0x00000100U /* Other drivers match routines may reset our security state and lose AID!!! */
  ------------------
 5828|      0|				     CI_LEAKS_FILE_NOT_FOUND;
  ------------------
  |  |  581|      0|#define CI_LEAKS_FILE_NOT_FOUND		    0x00000010U /* GET DATA of empty object returns 6A 82 even if PIN not verified */
  ------------------
 5829|      0|		if (priv->yubico_version < 0x00040302)
  ------------------
  |  Branch (5829:7): [True: 0, False: 0]
  ------------------
 5830|      0|			priv->card_issues |= CI_VERIFY_LC0_FAIL;
  ------------------
  |  |  577|      0|#define CI_VERIFY_LC0_FAIL		    0x00000002U /* VERIFY Lc=0 never returns 90 00 if PIN not needed */
  ------------------
 5831|      0|		if (priv->yubico_version >= 0x00050700) /* Also used by Token2 */
  ------------------
  |  Branch (5831:7): [True: 0, False: 0]
  ------------------
 5832|      0|			priv->alg_ids |= AI_RSA_4096 | AI_25519 | AI_X25519;
  ------------------
  |  |  595|      0|#define AI_RSA_4096			    0x00000008U
  ------------------
              			priv->alg_ids |= AI_RSA_4096 | AI_25519 | AI_X25519;
  ------------------
  |  |  598|      0|#define AI_25519			    0x00100000U
  ------------------
              			priv->alg_ids |= AI_RSA_4096 | AI_25519 | AI_X25519;
  ------------------
  |  |  599|      0|#define AI_X25519			    0x00200000U
  ------------------
 5833|      0|		break;
 5834|       |
 5835|      0|	case SC_CARD_TYPE_PIV_II_NITROKEY:
  ------------------
  |  Branch (5835:2): [True: 0, False: 0]
  ------------------
 5836|      0|		priv->card_issues |= CI_OTHER_AID_LOSE_STATE;
  ------------------
  |  |  585|      0|#define CI_OTHER_AID_LOSE_STATE		    0x00000100U /* Other drivers match routines may reset our security state and lose AID!!! */
  ------------------
 5837|      0|		if (priv->yubico_version >= 0x00010802) /* use for NitroKey too */
  ------------------
  |  Branch (5837:7): [True: 0, False: 0]
  ------------------
 5838|      0|			priv->alg_ids |= AI_RSA_4096;
  ------------------
  |  |  595|      0|#define AI_RSA_4096			    0x00000008U
  ------------------
 5839|      0|		break;
 5840|       |
 5841|      0|	case SC_CARD_TYPE_PIV_II_GI_DE:
  ------------------
  |  Branch (5841:2): [True: 0, False: 0]
  ------------------
 5842|      0|	case SC_CARD_TYPE_PIV_II_OBERTHUR:
  ------------------
  |  Branch (5842:2): [True: 0, False: 0]
  ------------------
 5843|      0|	case SC_CARD_TYPE_PIV_II_GEMALTO:
  ------------------
  |  Branch (5843:2): [True: 0, False: 0]
  ------------------
 5844|      0|	case SC_CARD_TYPE_PIV_II_SWISSBIT:
  ------------------
  |  Branch (5844:2): [True: 0, False: 0]
  ------------------
 5845|      0|		priv->card_issues |= 0; /* could add others here */
 5846|      0|		break;
 5847|       |
 5848|      0|	case SC_CARD_TYPE_PIV_II_BASE:
  ------------------
  |  Branch (5848:2): [True: 0, False: 0]
  ------------------
 5849|      0|	case SC_CARD_TYPE_PIV_II_HIST:
  ------------------
  |  Branch (5849:2): [True: 0, False: 0]
  ------------------
 5850|      0|	case SC_CARD_TYPE_PIV_II_800_73_4:
  ------------------
  |  Branch (5850:2): [True: 0, False: 0]
  ------------------
 5851|      0|		priv->card_issues |= 0; /* could add others here */
 5852|      0|		break;
 5853|       |
 5854|      0|	case SC_CARD_TYPE_PIV_II_GI_DE_DUAL_CAC:
  ------------------
  |  Branch (5854:2): [True: 0, False: 0]
  ------------------
 5855|      0|	case SC_CARD_TYPE_PIV_II_GEMALTO_DUAL_CAC:
  ------------------
  |  Branch (5855:2): [True: 0, False: 0]
  ------------------
 5856|      0|	case SC_CARD_TYPE_PIV_II_OBERTHUR_DUAL_CAC:
  ------------------
  |  Branch (5856:2): [True: 0, False: 0]
  ------------------
 5857|      0|		priv->card_issues |= CI_VERIFY_LC0_FAIL |
  ------------------
  |  |  577|      0|#define CI_VERIFY_LC0_FAIL		    0x00000002U /* VERIFY Lc=0 never returns 90 00 if PIN not needed */
  ------------------
 5858|      0|				     CI_PIV_AID_LOSE_STATE |
  ------------------
  |  |  583|      0|#define CI_PIV_AID_LOSE_STATE		    0x00000040U /* PIV AID can lose the login state run with out it*/
  ------------------
 5859|      0|				     CI_NO_RANDOM |
  ------------------
  |  |  579|      0|#define CI_NO_RANDOM			    0x00000004U /* can not use Challenge to get random data or no 9B key */
  ------------------
 5860|      0|				     CI_OTHER_AID_LOSE_STATE;
  ------------------
  |  |  585|      0|#define CI_OTHER_AID_LOSE_STATE		    0x00000100U /* Other drivers match routines may reset our security state and lose AID!!! */
  ------------------
 5861|      0|		break;
 5862|       |
 5863|      0|	case SC_CARD_TYPE_PIV_II_GENERIC:
  ------------------
  |  Branch (5863:2): [True: 0, False: 0]
  ------------------
 5864|      0|		priv->card_issues |= CI_VERIFY_LC0_FAIL |
  ------------------
  |  |  577|      0|#define CI_VERIFY_LC0_FAIL		    0x00000002U /* VERIFY Lc=0 never returns 90 00 if PIN not needed */
  ------------------
 5865|      0|				     CI_OTHER_AID_LOSE_STATE;
  ------------------
  |  |  585|      0|#define CI_OTHER_AID_LOSE_STATE		    0x00000100U /* Other drivers match routines may reset our security state and lose AID!!! */
  ------------------
 5866|      0|		break;
 5867|       |
 5868|      0|	case SC_CARD_TYPE_PIV_II_PIVKEY:
  ------------------
  |  Branch (5868:2): [True: 0, False: 0]
  ------------------
 5869|      0|		priv->card_issues |= CI_VERIFY_LC0_FAIL |
  ------------------
  |  |  577|      0|#define CI_VERIFY_LC0_FAIL		    0x00000002U /* VERIFY Lc=0 never returns 90 00 if PIN not needed */
  ------------------
 5870|      0|				     CI_PIV_AID_LOSE_STATE | /* be conservative */
  ------------------
  |  |  583|      0|#define CI_PIV_AID_LOSE_STATE		    0x00000040U /* PIV AID can lose the login state run with out it*/
  ------------------
 5871|      0|				     CI_NO_RANDOM;	     /* does not have 9B key */
  ------------------
  |  |  579|      0|#define CI_NO_RANDOM			    0x00000004U /* can not use Challenge to get random data or no 9B key */
  ------------------
 5872|       |							     /* Discovery object returns 6A 82 so is not on card by default */
 5873|      0|		break;
 5874|       |
 5875|      0|	default:
  ------------------
  |  Branch (5875:2): [True: 0, False: 0]
  ------------------
 5876|      0|		priv->card_issues |= CI_VERIFY_LC0_FAIL |
  ------------------
  |  |  577|      0|#define CI_VERIFY_LC0_FAIL		    0x00000002U /* VERIFY Lc=0 never returns 90 00 if PIN not needed */
  ------------------
 5877|      0|				     CI_OTHER_AID_LOSE_STATE;
  ------------------
  |  |  585|      0|#define CI_OTHER_AID_LOSE_STATE		    0x00000100U /* Other drivers match routines may reset our security state and lose AID!!! */
  ------------------
 5878|       |		/* opensc.conf may have it wrong, continue anyway */
 5879|      0|		sc_log(card->ctx, "Unknown PIV card->type %d", card->type);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5880|      0|		card->type = SC_CARD_TYPE_PIV_II_GENERIC;
 5881|      0|	}
 5882|      0|	sc_log(card->ctx, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5883|      0|			card->type, r2, priv->card_issues, r, priv->alg_ids);
 5884|       |
 5885|      0|	if (!(priv->card_issues & CI_DISCOVERY_USELESS) && !(priv->init_flags & PIV_INIT_DISCOVERY_PARSED)) {
  ------------------
  |  |  582|      0|#define CI_DISCOVERY_USELESS		    0x00000020U /* Discovery can not be used to query active AID invalid or no data returned */
  ------------------
              	if (!(priv->card_issues & CI_DISCOVERY_USELESS) && !(priv->init_flags & PIV_INIT_DISCOVERY_PARSED)) {
  ------------------
  |  |  379|      0|#define PIV_INIT_DISCOVERY_PARSED		0x00000004u
  ------------------
  |  Branch (5885:6): [True: 0, False: 0]
  |  Branch (5885:53): [True: 0, False: 0]
  ------------------
 5886|       |		/*
 5887|       |		 * We now know PIV AID is active, test DISCOVERY object again
 5888|       |		 * Some PIV don't support DISCOVERY and return
 5889|       |		 * SC_ERROR_INCORRECT_PARAMETERS. Any error
 5890|       |		 * including SC_ERROR_FILE_NOT_FOUND means we cannot use discovery
 5891|       |		 * to test for active AID.
 5892|       |		 */
 5893|      0|		r2 = piv_find_discovery(card);
 5894|       |
 5895|      0|		if (r2 < 0) {
  ------------------
  |  Branch (5895:7): [True: 0, False: 0]
  ------------------
 5896|      0|			priv->card_issues |= CI_DISCOVERY_USELESS;
  ------------------
  |  |  582|      0|#define CI_DISCOVERY_USELESS		    0x00000020U /* Discovery can not be used to query active AID invalid or no data returned */
  ------------------
 5897|      0|			piv_obj_cache_free_entry(card, PIV_OBJ_DISCOVERY, PIV_OBJ_CACHE_NOT_PRESENT);
  ------------------
  |  |  150|      0|#define PIV_OBJ_CACHE_NOT_PRESENT	8
  ------------------
 5898|      0|		}
 5899|      0|	}
 5900|       |
 5901|      0|	sc_log(card->ctx, "PIV_MATCH card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5902|      0|			card->type, r2, priv->card_issues, r, priv->alg_ids);
 5903|       |	/* Matched, caller will use or free priv and sc_lock as needed */
 5904|      0|	LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5905|       |
 5906|     51|err:
 5907|     51|	sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "PIV_MATCH failed card->type:%d r2:%d CI:%08x r:%d AI:%08x\n",
  ------------------
  |  |   70|     51|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5908|     51|			card->type, r2, priv->card_issues, r, priv->alg_ids);
 5909|       |	/* don't match. Does not have a PIV applet. */
 5910|     51|	piv_finish(card);
 5911|     51|	card->type = saved_type;
 5912|     51|	LOG_FUNC_RETURN(card->ctx, r);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|     51|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 5913|     51|}
card-piv.c:piv_obj_cache_free_entry:
 5360|  3.06k|{
 5361|  3.06k|	piv_private_data_t *priv = PIV_DATA(card);
  ------------------
  |  |  432|  3.06k|#define PIV_DATA(card) ((piv_private_data_t*)card->drv_data)
  ------------------
 5362|       |
 5363|  3.06k|	if (priv->obj_cache[enumtag].obj_data)
  ------------------
  |  Branch (5363:6): [True: 0, False: 3.06k]
  ------------------
 5364|      0|		free(priv->obj_cache[enumtag].obj_data);
 5365|  3.06k|	priv->obj_cache[enumtag].obj_data = NULL;
 5366|  3.06k|	priv->obj_cache[enumtag].obj_len = 0;
 5367|       |
 5368|  3.06k|	if (priv->obj_cache[enumtag].internal_obj_data)
  ------------------
  |  Branch (5368:6): [True: 0, False: 3.06k]
  ------------------
 5369|      0|		free(priv->obj_cache[enumtag].internal_obj_data);
 5370|  3.06k|	priv->obj_cache[enumtag].internal_obj_data = NULL;
 5371|  3.06k|	priv->obj_cache[enumtag].internal_obj_len = 0;
 5372|  3.06k|	priv->obj_cache[enumtag].flags = flags;
 5373|       |
 5374|  3.06k|	return SC_SUCCESS;
  ------------------
  |  |   28|  3.06k|#define SC_SUCCESS				0
  ------------------
 5375|  3.06k|}
card-piv.c:piv_find_aid:
 2894|     51|{
 2895|     51|	piv_private_data_t *priv = PIV_DATA(card);
  ------------------
  |  |  432|     51|#define PIV_DATA(card) ((piv_private_data_t*)card->drv_data)
  ------------------
 2896|     51|	u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
 2897|     51|	int r, i, j;
 2898|     51|	const u8 *tag;
 2899|     51|	size_t taglen;
 2900|     51|	const u8 *nextac;
 2901|     51|	const u8 *next80;
 2902|     51|	const u8 *pix;
 2903|     51|	size_t pixlen;
 2904|     51|	const u8 *al_label;
 2905|     51|	size_t al_labellen;
 2906|     51|	const u8 *actag; /* Cipher Suite */
 2907|     51|	size_t actaglen;
 2908|     51|	const u8 *csai; /* Cipher Suite Algorithm Identifier */
 2909|     51|	size_t csailen;
 2910|     51|	size_t resplen = sizeof(rbuf);
 2911|       |#ifdef ENABLE_PIV_SM
 2912|       |	int found_csai = 0;
 2913|       |#endif
 2914|       |
 2915|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
 2916|       |
 2917|       |	/* first  see if the default application will return a template
 2918|       |	 * that we know about.
 2919|       |	 */
 2920|       |
 2921|     51|	r = iso7816_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, rbuf, &resplen);
 2922|     51|	if (r > 0 && priv->aid_der.value && resplen == priv->aid_der.len && !memcmp(priv->aid_der.value, rbuf, resplen)) {
  ------------------
  |  Branch (2922:6): [True: 0, False: 51]
  |  Branch (2922:15): [True: 0, False: 0]
  |  Branch (2922:38): [True: 0, False: 0]
  |  Branch (2922:70): [True: 0, False: 0]
  ------------------
 2923|      0|		LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2924|       |		/* no need to parse again, same as last time */
 2925|      0|	}
 2926|     51|	if (r >= 0 && resplen > 2) {
  ------------------
  |  Branch (2926:6): [True: 0, False: 51]
  |  Branch (2926:16): [True: 0, False: 0]
  ------------------
 2927|      0|		tag = sc_asn1_find_tag(card->ctx, rbuf, resplen, 0x61, &taglen);
 2928|      0|		if (tag != NULL) {
  ------------------
  |  Branch (2928:7): [True: 0, False: 0]
  ------------------
 2929|      0|			priv->init_flags |= PIV_INIT_AID_PARSED;
  ------------------
  |  |  377|      0|#define PIV_INIT_AID_PARSED			0x00000001u
  ------------------
 2930|       |			/* look for 800-73-4 0xAC for Cipher Suite Algorithm Identifier Table 14 */
 2931|       |			/* 800-73-4 only expects 1 0xAC tag len 6 with a 80 01 xx 06 01 00
 2932|       |			 * where xx is the SM csID either 27 or 2E.
 2933|       |			 * Some vendors may include entries for supported Algorithms even when
 2934|       |			 * not required. We will use these if possible
 2935|       |			 * Will look for multiple 0x80 with in 0xAC value too.
 2936|       |			 */
 2937|      0|			nextac = tag;
 2938|      0|			while ((actag = sc_asn1_find_tag(card->ctx, nextac, taglen - (nextac - tag),
  ------------------
  |  Branch (2938:11): [True: 0, False: 0]
  ------------------
 2939|      0|						0xAC, &actaglen)) != NULL) {
 2940|      0|				nextac = actag + actaglen;
 2941|       |
 2942|      0|				next80 = actag;
 2943|      0|				while ((csai = sc_asn1_find_tag(card->ctx, next80, actaglen - (next80 - actag),
  ------------------
  |  Branch (2943:12): [True: 0, False: 0]
  ------------------
 2944|      0|							0x80, &csailen)) != NULL) {
 2945|      0|					next80 = csai + csailen;
 2946|      0|					if (csailen == 1) {
  ------------------
  |  Branch (2946:10): [True: 0, False: 0]
  ------------------
 2947|      0|						sc_log(card->ctx, "0xAC 0x80 entry:0x%2.2x found", *csai);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 2948|      0|						j = piv_ai_map_find_by_id(card, *csai);
 2949|      0|						if (j >= 0) {
  ------------------
  |  Branch (2949:11): [True: 0, False: 0]
  ------------------
 2950|      0|							priv->alg_ids |= ai_map[j].ai_flag;
 2951|      0|							continue;
 2952|      0|						}
 2953|       |#ifdef ENABLE_PIV_SM
 2954|       |						/* check if id is NIST SM */
 2955|       |						for (i = 0; i < PIV_CSS_SIZE; i++) {
 2956|       |							if (*csai != css[i].id)
 2957|       |								continue;
 2958|       |							if (found_csai) {
 2959|       |								sc_log(card->ctx, "found multiple csIDs, using first");
 2960|       |							} else {
 2961|       |								priv->cs = &css[i];
 2962|       |								priv->csID = *csai;
 2963|       |								found_csai++;
 2964|       |								priv->init_flags |= PIV_INIT_AID_AC_SM;
 2965|       |							}
 2966|       |						}
 2967|       |#endif /* ENABLE_PIV_SM */
 2968|      0|					}
 2969|      0|				}
 2970|      0|			}
 2971|       |
 2972|       |			/* Last chance to distinguish card type based on Application Label '50' */
 2973|      0|			al_label = sc_asn1_find_tag(card->ctx, tag, taglen, 0x50, &al_labellen);
 2974|      0|			if (al_label != NULL) {
  ------------------
  |  Branch (2974:8): [True: 0, False: 0]
  ------------------
 2975|      0|				sc_log_hex(card->ctx, "Application Label", al_label, al_labellen);
  ------------------
  |  |  129|      0|    sc_debug_hex(ctx, SC_LOG_DEBUG_NORMAL, label, data, len)
  |  |  ------------------
  |  |  |  |  127|      0|    _sc_debug_hex(ctx, level, FILENAME, __LINE__, __FUNCTION__, label, data, len)
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2976|      0|				if ((priv->al_label = malloc(al_labellen)) == NULL) {
  ------------------
  |  Branch (2976:9): [True: 0, False: 0]
  ------------------
 2977|      0|					LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2978|      0|				}
 2979|      0|				memcpy(priv->al_label, al_label, al_labellen);
 2980|      0|				priv->al_labellen = (int)al_labellen;
 2981|      0|			}
 2982|       |
 2983|      0|			pix = sc_asn1_find_tag(card->ctx, tag, taglen, 0x4F, &pixlen);
 2984|      0|			if (pix != NULL) {
  ------------------
  |  Branch (2984:8): [True: 0, False: 0]
  ------------------
 2985|      0|				sc_log(card->ctx, "found PIX");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 2986|       |
 2987|       |				/* early cards returned full AID, rather then just the pix */
 2988|      0|				for (i = 0; piv_aids[i].len_long != 0; i++) {
  ------------------
  |  Branch (2988:17): [True: 0, False: 0]
  ------------------
 2989|      0|					if ((pixlen >= piv_aids[i].len_long - 5 &&
  ------------------
  |  Branch (2989:11): [True: 0, False: 0]
  ------------------
 2990|      0|							    memcmp(pix, piv_aids[i].value + 5, piv_aids[i].len_long - 5) == 0) ||
  ------------------
  |  Branch (2990:12): [True: 0, False: 0]
  ------------------
 2991|      0|							((pixlen >= piv_aids[i].len_short && memcmp(pix, piv_aids[i].value,
  ------------------
  |  Branch (2991:10): [True: 0, False: 0]
  |  Branch (2991:45): [True: 0, False: 0]
  ------------------
 2992|      0|													     piv_aids[i].len_short) == 0))) {
 2993|      0|						free(priv->aid_der.value); /* free previous value if any */
 2994|      0|						if ((priv->aid_der.value = malloc(resplen)) == NULL) {
  ------------------
  |  Branch (2994:11): [True: 0, False: 0]
  ------------------
 2995|      0|							LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 2996|      0|						}
 2997|      0|						memcpy(priv->aid_der.value, rbuf, resplen);
 2998|      0|						priv->aid_der.len = resplen;
 2999|      0|						LOG_FUNC_RETURN(card->ctx, i);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3000|      0|					}
 3001|      0|				}
 3002|      0|			}
 3003|      0|		}
 3004|      0|	}
 3005|       |
 3006|     51|	LOG_FUNC_RETURN(card->ctx, SC_ERROR_NO_CARD_SUPPORT);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|     51|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 3007|     51|}
card-piv.c:piv_finish:
 5379|    102|{
 5380|    102|	piv_private_data_t *priv = PIV_DATA(card);
  ------------------
  |  |  432|    102|#define PIV_DATA(card) ((piv_private_data_t*)card->drv_data)
  ------------------
 5381|    102|	int i;
 5382|       |
 5383|    102|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|    102|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|    102|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|    102|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 102]
  |  |  ------------------
  ------------------
 5384|    102|	if (priv) {
  ------------------
  |  Branch (5384:6): [True: 51, False: 51]
  ------------------
 5385|     51|		if (priv->context_specific) {
  ------------------
  |  Branch (5385:7): [True: 0, False: 51]
  ------------------
 5386|      0|			sc_log(card->ctx, "Clearing CONTEXT_SPECIFIC lock");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 5387|      0|			priv->context_specific = 0;
 5388|      0|			sc_unlock(card);
 5389|      0|		}
 5390|     51|		free(priv->aid_der.value);
 5391|     51|		free(priv->al_label);
 5392|     51|		if (priv->w_buf)
  ------------------
  |  Branch (5392:7): [True: 0, False: 51]
  ------------------
 5393|      0|			free(priv->w_buf);
 5394|     51|		if (priv->offCardCertURL)
  ------------------
  |  Branch (5394:7): [True: 0, False: 51]
  ------------------
 5395|      0|			free(priv->offCardCertURL);
 5396|  3.11k|		for (i = 0; i < PIV_OBJ_LAST_ENUM - 1; i++) {
  ------------------
  |  Branch (5396:15): [True: 3.06k, False: 51]
  ------------------
 5397|  3.06k|			piv_obj_cache_free_entry(card, i, 0);
 5398|  3.06k|		}
 5399|       |#ifdef ENABLE_PIV_SM
 5400|       |		piv_clear_cvc_content(&priv->sm_cvc);
 5401|       |		piv_clear_cvc_content(&priv->sm_in_cvc);
 5402|       |		piv_clear_sm_session(&priv->sm_session);
 5403|       |#endif /* ENABLE_PIV_SM */
 5404|       |
 5405|     51|		free(priv);
 5406|       |		card->drv_data = NULL; /* priv */
 5407|     51|	}
 5408|    102|	return 0;
 5409|    102|}
card-piv.c:piv_check_sw:
 6073|     51|{
 6074|     51|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 6075|       |
 6076|     51|	int r;
 6077|       |#ifdef ENABLE_PIV_SM
 6078|       |	int i;
 6079|       |#endif
 6080|     51|	piv_private_data_t *priv = PIV_DATA(card);
  ------------------
  |  |  432|     51|#define PIV_DATA(card) ((piv_private_data_t*)card->drv_data)
  ------------------
 6081|       |
 6082|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
 6083|       |
 6084|       |	/* may be called before piv_init has allocated priv */
 6085|     51|	if (priv) {
  ------------------
  |  Branch (6085:6): [True: 51, False: 0]
  ------------------
 6086|       |		/* need to save sw1 and sw2 if trying to determine card_state from pin_cmd */
 6087|       |
 6088|     51|		if (priv->pin_cmd_verify) {
  ------------------
  |  Branch (6088:7): [True: 0, False: 51]
  ------------------
 6089|      0|			priv->pin_cmd_verify_sw1 = sw1;
 6090|      0|			priv->pin_cmd_verify_sw2 = sw2;
 6091|     51|		} else {
 6092|       |			/* a command has completed and it is not verify
 6093|       |			 * If we are in a context_specific sequence, unlock
 6094|       |			 * This just decrements the extra lock count
 6095|       |			 */
 6096|     51|			if (priv->context_specific) {
  ------------------
  |  Branch (6096:8): [True: 0, False: 51]
  ------------------
 6097|      0|				sc_log(card->ctx, "Clearing CONTEXT_SPECIFIC lock");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 6098|      0|				priv->context_specific = 0;
 6099|      0|				sc_unlock(card);
 6100|      0|			}
 6101|     51|		}
 6102|       |
 6103|     51|		if (priv->card_issues & CI_VERIFY_630X) {
  ------------------
  |  |  576|     51|#define CI_VERIFY_630X			    0x00000001U /* VERIFY tries left returns 630X rather then 63CX */
  ------------------
  |  Branch (6103:7): [True: 0, False: 51]
  ------------------
 6104|       |
 6105|       |			/* Handle the Yubikey NEO or any other PIV card which returns in response to a verify
 6106|       |			 * 63 0X rather than 63 CX indicate the number of remaining PIN retries.
 6107|       |			 * Perhaps they misread the spec and thought 0xCX meant "clear" or "don't care", not a literal 0xC!
 6108|       |			 */
 6109|      0|			if (priv->pin_cmd_verify && sw1 == 0x63U) {
  ------------------
  |  Branch (6109:8): [True: 0, False: 0]
  |  Branch (6109:32): [True: 0, False: 0]
  ------------------
 6110|      0|				priv->pin_cmd_verify_sw2 |= 0xC0U; /* make it easier to test in other code */
 6111|      0|				if ((sw2 & ~0x0fU) == 0x00U) {
  ------------------
  |  Branch (6111:9): [True: 0, False: 0]
  ------------------
 6112|      0|					sc_log(card->ctx, "Verification failed (remaining tries: %d)", (sw2 & 0x0f));
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 6113|      0|					return SC_ERROR_PIN_CODE_INCORRECT;
  ------------------
  |  |   64|      0|#define SC_ERROR_PIN_CODE_INCORRECT		-1214
  ------------------
 6114|       |					/* this is what the iso_check_sw returns for 63 C0 */
 6115|      0|				}
 6116|      0|			}
 6117|      0|		}
 6118|     51|	}
 6119|       |#ifdef ENABLE_PIV_SM
 6120|       |	/* Note 6982 is map to SC_ERROR_SM_NO_SESSION_KEYS but iso maps it to SC_ERROR_SECURITY_STATUS_NOT_SATISFIED */
 6121|       |	/* we do this because 6982 could also mean a verify is not allowed over contactless without VCI */
 6122|       |	/* we stashed the sw1 and sw2 above for verify */
 6123|       |	/* Check specific NIST sp800-73-4 SM  errors */
 6124|       |	for (i = 0; piv_sm_errors[i].SWs != 0; i++) {
 6125|       |		if (piv_sm_errors[i].SWs == ((sw1 << 8) | sw2)) {
 6126|       |			sc_log(card->ctx, "%s", piv_sm_errors[i].errorstr);
 6127|       |			return piv_sm_errors[i].errorno;
 6128|       |		}
 6129|       |	}
 6130|       |#endif
 6131|     51|	r = iso_drv->ops->check_sw(card, sw1, sw2);
 6132|     51|	return r;
 6133|     51|}
card-piv.c:piv_card_reader_lock_obtained:
 6380|     51|{
 6381|     51|	int r = 0;
 6382|     51|	u8 temp[SC_MAX_APDU_BUFFER_SIZE];
 6383|     51|	size_t templen = sizeof(temp);
 6384|     51|	piv_private_data_t *priv = PIV_DATA(card); /* may be null */
  ------------------
  |  |  432|     51|#define PIV_DATA(card) ((piv_private_data_t*)card->drv_data)
  ------------------
 6385|       |
 6386|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
 6387|       |
 6388|       |	/* We have a PCSC transaction and sc_lock */
 6389|     51|	if (priv == NULL || priv->pstate == PIV_STATE_MATCH) {
  ------------------
  |  Branch (6389:6): [True: 51, False: 0]
  |  Branch (6389:22): [True: 0, False: 0]
  ------------------
 6390|     51|		sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE,
  ------------------
  |  |   70|    102|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  |  Branch (70:103): [True: 0, False: 51]
  |  |  ------------------
  ------------------
 6391|     51|				priv ? "PIV_STATE_MATCH" : "priv==NULL");
 6392|     51|		r = 0; /* do nothing, piv_match will take care of it */
 6393|     51|		goto err;
 6394|     51|	}
 6395|       |
 6396|      0|	priv->init_flags |= PIV_INIT_IN_READER_LOCK_OBTAINED;
  ------------------
  |  |  381|      0|#define PIV_INIT_IN_READER_LOCK_OBTAINED	0x00000010u
  ------------------
 6397|       |
 6398|       |	/* make sure our application is active */
 6399|       |
 6400|       |	/* first see if AID is active AID by reading discovery object '7E' */
 6401|       |	/* If not try selecting AID */
 6402|       |
 6403|       |	/* but if card does not support DISCOVERY object we can not use it */
 6404|      0|	if (priv->card_issues & CI_DISCOVERY_USELESS) {
  ------------------
  |  |  582|      0|#define CI_DISCOVERY_USELESS		    0x00000020U /* Discovery can not be used to query active AID invalid or no data returned */
  ------------------
  |  Branch (6404:6): [True: 0, False: 0]
  ------------------
 6405|      0|		r = SC_ERROR_NO_CARD_SUPPORT;
  ------------------
  |  |   58|      0|#define SC_ERROR_NO_CARD_SUPPORT		-1208
  ------------------
 6406|      0|	} else {
 6407|      0|		r = piv_find_discovery(card);
 6408|       |#ifdef ENABLE_PIV_SM
 6409|       |		/*
 6410|       |		 * All 800-73-4 cards that support SM, also have a discovery object with
 6411|       |		 * the pin_policy, so can not have CI_DISCOVERY_USELESS
 6412|       |		 * Discovery object can be read with contact or contactless
 6413|       |		 * If read with SM and fails with 69 88  SC_ERROR_SM_INVALID_SESSION_KEY
 6414|       |		 * sm.c will close the SM connectrion, and set defer
 6415|       |		 */
 6416|       |		if (was_reset == 0 && (r == SC_ERROR_SM_INVALID_SESSION_KEY || priv->sm_flags & PIV_SM_FLAGS_DEFER_OPEN)) {
 6417|       |			sc_log(card->ctx, "SC_ERROR_SM_INVALID_SESSION_KEY || PIV_SM_FLAGS_DEFER_OPEN");
 6418|       |			piv_sm_open(card);
 6419|       |			r = piv_find_discovery(card);
 6420|       |		}
 6421|       |#endif /* ENABLE_PIV_SM */
 6422|      0|	}
 6423|       |
 6424|      0|	if (r < 0) {
  ------------------
  |  Branch (6424:6): [True: 0, False: 0]
  ------------------
 6425|      0|		if (was_reset > 0 || !(priv->card_issues & CI_PIV_AID_LOSE_STATE)) {
  ------------------
  |  |  583|      0|#define CI_PIV_AID_LOSE_STATE		    0x00000040U /* PIV AID can lose the login state run with out it*/
  ------------------
  |  Branch (6425:7): [True: 0, False: 0]
  |  Branch (6425:24): [True: 0, False: 0]
  ------------------
 6426|      0|			r = iso7816_select_aid(card, piv_aids[0].value, piv_aids[0].len_short, temp, &templen);
 6427|      0|			sc_debug(card->ctx, SC_LOG_DEBUG_MATCH, "iso7816_select_aid card->type:%d r:%d\n", card->type, r);
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 6428|      0|		} else {
 6429|      0|			r = 0; /* can't do anything with this card, hope there was no interference */
 6430|      0|		}
 6431|      0|	}
 6432|       |
 6433|      0|	if (r < 0) /* bad error return will show up in sc_lock as error*/
  ------------------
  |  Branch (6433:6): [True: 0, False: 0]
  ------------------
 6434|      0|		goto err;
 6435|       |
 6436|      0|	if (was_reset > 0)
  ------------------
  |  Branch (6436:6): [True: 0, False: 0]
  ------------------
 6437|      0|		priv->logged_in = SC_PIN_STATE_UNKNOWN;
  ------------------
  |  |  437|      0|#define SC_PIN_STATE_UNKNOWN	0
  ------------------
 6438|       |
 6439|      0|	r = 0;
 6440|       |
 6441|     51|err:
 6442|     51|	if (priv)
  ------------------
  |  Branch (6442:6): [True: 0, False: 51]
  ------------------
 6443|      0|		priv->init_flags &= ~PIV_INIT_IN_READER_LOCK_OBTAINED;
  ------------------
  |  |  381|      0|#define PIV_INIT_IN_READER_LOCK_OBTAINED	0x00000010u
  ------------------
 6444|     51|	LOG_FUNC_RETURN(card->ctx, r);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 6445|     51|}

sc_get_rtecp_driver:
  869|    295|{
  870|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (870:6): [True: 1, False: 294]
  ------------------
  871|      1|		iso_ops = sc_get_iso7816_driver()->ops;
  872|    295|	rtecp_ops = *iso_ops;
  873|       |
  874|    295|	rtecp_ops.match_card = rtecp_match_card;
  875|    295|	rtecp_ops.init = rtecp_init;
  876|       |	/* read_binary */
  877|    295|	rtecp_ops.write_binary = NULL;
  878|       |	/* update_binary */
  879|    295|	rtecp_ops.read_record = NULL;
  880|    295|	rtecp_ops.write_record = NULL;
  881|    295|	rtecp_ops.append_record = NULL;
  882|    295|	rtecp_ops.update_record = NULL;
  883|    295|	rtecp_ops.select_file = rtecp_select_file;
  884|       |	/* get_response */
  885|       |	/* get_challenge */
  886|    295|	rtecp_ops.verify = rtecp_verify;
  887|    295|	rtecp_ops.logout = rtecp_logout;
  888|       |	/* restore_security_env */
  889|    295|	rtecp_ops.set_security_env = rtecp_set_security_env;
  890|    295|	rtecp_ops.decipher = rtecp_decipher;
  891|    295|	rtecp_ops.compute_signature = rtecp_compute_signature;
  892|    295|	rtecp_ops.change_reference_data = rtecp_change_reference_data;
  893|    295|	rtecp_ops.reset_retry_counter = rtecp_reset_retry_counter;
  894|    295|	rtecp_ops.create_file = rtecp_create_file;
  895|       |	/* delete_file */
  896|    295|	rtecp_ops.list_files = rtecp_list_files;
  897|       |	/* check_sw */
  898|    295|	rtecp_ops.card_ctl = rtecp_card_ctl;
  899|       |	/* process_fci */
  900|    295|	rtecp_ops.construct_fci = rtecp_construct_fci;
  901|       |	rtecp_ops.pin_cmd = NULL;
  902|    295|	return &rtecp_drv;
  903|    295|}
card-rtecp.c:rtecp_match_card:
   73|     51|{
   74|     51|	int i = -1;
   75|     51|	i = _sc_match_atr(card, rtecp_atrs, &card->type);
   76|     51|	if (i >= 0) {
  ------------------
  |  Branch (76:6): [True: 0, False: 51]
  ------------------
   77|      0|		card->name = rtecp_atrs[i].name;
   78|      0|		LOG_FUNC_RETURN(card->ctx, 1);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   79|      0|	}
   80|     51|	LOG_FUNC_RETURN(card->ctx, 0);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   81|     51|}

sc_get_rutoken_driver:
 1326|    295|{
 1327|    295|	return get_rutoken_driver();
 1328|    295|}
card-rutoken.c:get_rutoken_driver:
 1287|    295|{
 1288|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (1288:6): [True: 1, False: 294]
  ------------------
 1289|      1|		iso_ops = sc_get_iso7816_driver()->ops;
 1290|    295|	rutoken_ops = *iso_ops;
 1291|       |
 1292|    295|	rutoken_ops.match_card = rutoken_match_card;
 1293|    295|	rutoken_ops.init = rutoken_init;
 1294|    295|	rutoken_ops.finish = rutoken_finish;
 1295|       |	/* read_binary */
 1296|    295|	rutoken_ops.write_binary = NULL;
 1297|       |	/* update_binary */
 1298|    295|	rutoken_ops.read_record = NULL;
 1299|    295|	rutoken_ops.write_record = NULL;
 1300|    295|	rutoken_ops.append_record = NULL;
 1301|    295|	rutoken_ops.update_record = NULL;
 1302|    295|	rutoken_ops.select_file = rutoken_select_file;
 1303|    295|	rutoken_ops.get_response = NULL;
 1304|    295|	rutoken_ops.get_challenge = rutoken_get_challenge;
 1305|    295|	rutoken_ops.verify = rutoken_verify;
 1306|    295|	rutoken_ops.logout = rutoken_logout;
 1307|    295|	rutoken_ops.restore_security_env = rutoken_restore_security_env;
 1308|    295|	rutoken_ops.set_security_env = rutoken_set_security_env;
 1309|    295|	rutoken_ops.decipher = NULL;
 1310|    295|	rutoken_ops.compute_signature = rutoken_compute_signature;
 1311|    295|	rutoken_ops.change_reference_data = rutoken_change_reference_data;
 1312|    295|	rutoken_ops.reset_retry_counter = rutoken_reset_retry_counter;
 1313|    295|	rutoken_ops.create_file = rutoken_create_file;
 1314|    295|	rutoken_ops.delete_file = rutoken_delete_file;
 1315|    295|	rutoken_ops.list_files = rutoken_list_files;
 1316|    295|	rutoken_ops.check_sw = rutoken_check_sw;
 1317|    295|	rutoken_ops.card_ctl = rutoken_card_ctl;
 1318|    295|	rutoken_ops.process_fci = rutoken_process_fci;
 1319|    295|	rutoken_ops.construct_fci = rutoken_construct_fci;
 1320|    295|	rutoken_ops.pin_cmd = NULL;
 1321|       |
 1322|    295|	return &rutoken_drv;
 1323|    295|}
card-rutoken.c:rutoken_match_card:
  103|     51|{
  104|     51|	SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
  105|     51|	if (_sc_match_atr(card, rutoken_atrs, &card->type) >= 0)
  ------------------
  |  Branch (105:6): [True: 0, False: 51]
  ------------------
  106|      0|	{
  107|      0|		sc_log(card->ctx,  "ATR recognized as Rutoken\n");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  108|      0|		LOG_FUNC_RETURN(card->ctx, 1);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  109|      0|	}
  110|     51|	LOG_FUNC_RETURN(card->ctx, 0);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  111|     51|}

sc_get_sc_hsm_driver:
 1976|    295|{
 1977|    295|	return sc_get_driver();
 1978|    295|}
card-sc-hsm.c:sc_get_driver:
 1940|    295|{
 1941|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 1942|       |
 1943|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (1943:6): [True: 1, False: 294]
  ------------------
 1944|      1|		iso_ops = iso_drv->ops;
 1945|       |
 1946|    295|	sc_hsm_ops                   = *iso_drv->ops;
 1947|    295|	sc_hsm_ops.match_card        = sc_hsm_match_card;
 1948|    295|	sc_hsm_ops.select_file       = sc_hsm_select_file;
 1949|    295|	sc_hsm_ops.get_challenge     = sc_hsm_get_challenge;
 1950|    295|	sc_hsm_ops.read_binary       = sc_hsm_read_binary;
 1951|    295|	sc_hsm_ops.update_binary     = sc_hsm_update_binary;
 1952|    295|	sc_hsm_ops.list_files        = sc_hsm_list_files;
 1953|    295|	sc_hsm_ops.create_file       = sc_hsm_create_file;
 1954|    295|	sc_hsm_ops.delete_file       = sc_hsm_delete_file;
 1955|    295|	sc_hsm_ops.set_security_env  = sc_hsm_set_security_env;
 1956|    295|	sc_hsm_ops.compute_signature = sc_hsm_compute_signature;
 1957|    295|	sc_hsm_ops.decipher          = sc_hsm_decipher;
 1958|    295|	sc_hsm_ops.init              = sc_hsm_init;
 1959|    295|	sc_hsm_ops.finish            = sc_hsm_finish;
 1960|    295|	sc_hsm_ops.card_ctl          = sc_hsm_card_ctl;
 1961|    295|	sc_hsm_ops.pin_cmd           = sc_hsm_pin_cmd;
 1962|    295|	sc_hsm_ops.logout            = sc_hsm_logout;
 1963|       |
 1964|       |	/* no record oriented file services */
 1965|    295|	sc_hsm_ops.read_record       = NULL;
 1966|    295|	sc_hsm_ops.write_record      = NULL;
 1967|    295|	sc_hsm_ops.append_record     = NULL;
 1968|    295|	sc_hsm_ops.update_record     = NULL;
 1969|       |
 1970|    295|	return &sc_hsm_drv;
 1971|    295|}
card-sc-hsm.c:sc_hsm_match_card:
  266|     51|{
  267|     51|	sc_path_t path;
  268|     51|	int i, r, type = 0;
  269|     51|	sc_file_t *file = NULL;
  270|       |
  271|     51|	i = _sc_match_atr(card, sc_hsm_atrs, &type);
  272|     51|	if (i >= 0 && type != SC_CARD_TYPE_SC_HSM_SOC) {
  ------------------
  |  Branch (272:6): [True: 0, False: 51]
  |  Branch (272:16): [True: 0, False: 0]
  ------------------
  273|      0|		card->type = type;
  274|      0|		return 1;
  275|      0|	}
  276|       |
  277|     51|	sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);
  ------------------
  |  |  118|     51|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
  278|     51|	r = sc_hsm_select_file(card, &path, &file);
  279|     51|	LOG_TEST_RET(card->ctx, r, "Could not select SmartCard-HSM application");
  ------------------
  |  |  174|     51|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|     51|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|     51|	int _ret = (r); \
  |  |  |  |  168|     51|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|     51|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|     51|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|     51|		return _ret; \
  |  |  |  |  172|     51|	} \
  |  |  |  |  173|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  280|       |
  281|       |	// Validate that card returns a FCP with a proprietary tag 85 with value longer than 2 byte (Fixes #1377)
  282|      0|	if (file != NULL) {
  ------------------
  |  Branch (282:6): [True: 0, False: 0]
  ------------------
  283|      0|		size_t sz = file->prop_attr_len;
  284|      0|		sc_file_free(file);
  285|      0|		if (sz < 2) {
  ------------------
  |  Branch (285:7): [True: 0, False: 0]
  ------------------
  286|      0|			return 0;
  287|      0|		}
  288|      0|	}
  289|       |
  290|      0|	if (type == SC_CARD_TYPE_SC_HSM_SOC) {
  ------------------
  |  Branch (290:6): [True: 0, False: 0]
  ------------------
  291|      0|		card->type = SC_CARD_TYPE_SC_HSM_SOC;
  292|      0|	} else {
  293|      0|		card->type = SC_CARD_TYPE_SC_HSM;
  294|      0|	}
  295|       |
  296|      0|	return 1;
  297|      0|}
card-sc-hsm.c:sc_hsm_select_file:
  246|     51|{
  247|     51|	return sc_hsm_select_file_ex(card, in_path, 0, file_out);
  248|     51|}
card-sc-hsm.c:sc_hsm_select_file_ex:
  148|     51|{
  149|     51|	int rv;
  150|     51|	sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data;
  151|     51|	sc_file_t *file = NULL;
  152|     51|	sc_path_t cpath;
  153|     51|	size_t card_max_recv_size = card->max_recv_size;
  154|     51|	size_t reader_max_recv_size = card->reader->max_recv_size;
  155|       |
  156|     51|	if (file_out == NULL) {				// Versions before 0.16 of the SmartCard-HSM do not support P2='0C'
  ------------------
  |  Branch (156:6): [True: 0, False: 51]
  ------------------
  157|      0|		rv = sc_hsm_select_file_ex(card, in_path, forceselect, &file);
  158|      0|		sc_file_free(file);
  159|      0|		return rv;
  160|      0|	}
  161|       |
  162|     51|	if ((in_path->type == SC_PATH_TYPE_FILE_ID) && in_path->aid.len) {
  ------------------
  |  |  117|     51|#define SC_PATH_TYPE_FILE_ID		0
  ------------------
  |  Branch (162:6): [True: 0, False: 51]
  |  Branch (162:49): [True: 0, False: 0]
  ------------------
  163|       |		// Split applet selection and file selection into two separate calls
  164|      0|		cpath = *in_path;
  165|      0|		cpath.len = 0;
  166|      0|		cpath.type = SC_PATH_TYPE_DF_NAME;
  ------------------
  |  |  118|      0|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
  167|      0|		rv = sc_hsm_select_file_ex(card, &cpath, forceselect, NULL);
  168|      0|		LOG_TEST_RET(card->ctx, rv, "Could not select SmartCard-HSM application");
  ------------------
  |  |  174|      0|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|      0|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|      0|	int _ret = (r); \
  |  |  |  |  168|      0|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  169|       |
  170|      0|		if (in_path->len) {
  ------------------
  |  Branch (170:7): [True: 0, False: 0]
  ------------------
  171|      0|			cpath = *in_path;
  172|      0|			cpath.aid.len = 0;
  173|      0|			rv = sc_hsm_select_file_ex(card, &cpath, forceselect, file_out);
  174|      0|		}
  175|      0|		return rv;
  176|      0|	}
  177|       |
  178|       |	// Prevent selection of applet unless this is the first time, selection is forced or the device is not authenticated
  179|     51|	if (in_path->type == SC_PATH_TYPE_DF_NAME
  ------------------
  |  |  118|    102|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
  |  Branch (179:6): [True: 51, False: 0]
  ------------------
  180|      0|			|| (in_path->type == SC_PATH_TYPE_PATH
  ------------------
  |  |  119|      0|#define SC_PATH_TYPE_PATH		2
  ------------------
  |  Branch (180:8): [True: 0, False: 0]
  ------------------
  181|      0|				&& in_path->len == sc_hsm_aid.len
  ------------------
  |  Branch (181:8): [True: 0, False: 0]
  ------------------
  182|      0|				&& !memcmp(in_path->value, sc_hsm_aid.value, sc_hsm_aid.len))
  ------------------
  |  Branch (182:8): [True: 0, False: 0]
  ------------------
  183|      0|			|| (in_path->type == SC_PATH_TYPE_PATH
  ------------------
  |  |  119|      0|#define SC_PATH_TYPE_PATH		2
  ------------------
  |  Branch (183:8): [True: 0, False: 0]
  ------------------
  184|      0|				&& in_path->len == 0
  ------------------
  |  Branch (184:8): [True: 0, False: 0]
  ------------------
  185|      0|				&& in_path->aid.len == sc_hsm_aid.len
  ------------------
  |  Branch (185:8): [True: 0, False: 0]
  ------------------
  186|     51|				&& !memcmp(in_path->aid.value, sc_hsm_aid.value, sc_hsm_aid.len))) {
  ------------------
  |  Branch (186:8): [True: 0, False: 0]
  ------------------
  187|     51|		if (!priv || (priv->dffcp == NULL) || forceselect) {
  ------------------
  |  Branch (187:7): [True: 51, False: 0]
  |  Branch (187:16): [True: 0, False: 0]
  |  Branch (187:41): [True: 0, False: 0]
  ------------------
  188|       |			/* Force use of Le = 0x00 in iso7816_select_file as required by SC-HSM */
  189|     51|			card->max_recv_size = card->reader->max_recv_size = SC_READER_SHORT_APDU_MAX_RECV_SIZE;
  ------------------
  |  |  391|     51|#define SC_READER_SHORT_APDU_MAX_RECV_SIZE 256
  ------------------
  190|     51|			rv = (*iso_ops->select_file)(card, in_path, file_out);
  191|     51|			card->max_recv_size = card_max_recv_size;
  192|     51|			card->reader->max_recv_size = reader_max_recv_size;
  193|     51|			LOG_TEST_RET(card->ctx, rv, "Could not select SmartCard-HSM application");
  ------------------
  |  |  174|     51|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|     51|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|     51|	int _ret = (r); \
  |  |  |  |  168|     51|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|     51|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|     51|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|     51|		return _ret; \
  |  |  |  |  172|     51|	} \
  |  |  |  |  173|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  194|       |
  195|      0|			if (priv) {
  ------------------
  |  Branch (195:8): [True: 0, False: 0]
  ------------------
  196|      0|				sc_file_free(priv->dffcp);
  197|       |				// Cache the FCP returned when selecting the applet
  198|      0|				sc_file_dup(&priv->dffcp, *file_out);
  199|      0|			}
  200|      0|		} else {
  201|      0|			sc_file_dup(file_out, priv->dffcp);
  202|      0|			rv = SC_SUCCESS;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  203|      0|		}
  204|      0|		return rv;
  205|     51|	}
  206|       |
  207|      0|	if ((in_path->len >= 2) && (in_path->value[0] == 0x3F) && (in_path->value[1] == 0x00)) {
  ------------------
  |  Branch (207:6): [True: 0, False: 0]
  |  Branch (207:29): [True: 0, False: 0]
  |  Branch (207:60): [True: 0, False: 0]
  ------------------
  208|       |		// The SmartCard-HSM is an applet that is not default selected. Simulate selection of the MF
  209|      0|		if (in_path->len == 2) {
  ------------------
  |  Branch (209:7): [True: 0, False: 0]
  ------------------
  210|      0|			file = sc_file_new();
  211|      0|			if (file == NULL)
  ------------------
  |  Branch (211:8): [True: 0, False: 0]
  ------------------
  212|      0|				LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  213|      0|			file->path = *in_path;
  214|      0|			file->id = 0x3F00;
  215|      0|			file->type = SC_FILE_TYPE_DF;
  ------------------
  |  |  214|      0|#define SC_FILE_TYPE_DF			0x04
  ------------------
  216|      0|			file->magic = SC_FILE_MAGIC;
  ------------------
  |  |   57|      0|#define SC_FILE_MAGIC			0x14426950
  ------------------
  217|       |
  218|      0|			*file_out = file;
  219|      0|			return SC_SUCCESS;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  220|      0|		} else {
  221|       |			/* Force use of Le = 0x00 in iso7816_select_file as required by SC-HSM */
  222|      0|			card->max_recv_size = card->reader->max_recv_size = SC_READER_SHORT_APDU_MAX_RECV_SIZE;
  ------------------
  |  |  391|      0|#define SC_READER_SHORT_APDU_MAX_RECV_SIZE 256
  ------------------
  223|      0|			sc_path_t truncated;
  224|      0|			memcpy(&truncated, in_path, sizeof truncated);
  225|      0|			truncated.len = in_path->len - 2;
  226|      0|			memcpy(truncated.value, in_path->value+2, truncated.len);
  227|      0|			rv = (*iso_ops->select_file)(card, &truncated, file_out);
  228|      0|			card->max_recv_size = card_max_recv_size;
  229|      0|			card->reader->max_recv_size = reader_max_recv_size;
  230|      0|			return rv;
  231|      0|		}
  232|      0|	}
  233|       |	/* Force use of Le = 0x00 in iso7816_select_file as required by SC-HSM */
  234|      0|	card->max_recv_size = card->reader->max_recv_size = SC_READER_SHORT_APDU_MAX_RECV_SIZE;
  ------------------
  |  |  391|      0|#define SC_READER_SHORT_APDU_MAX_RECV_SIZE 256
  ------------------
  235|      0|	rv = (*iso_ops->select_file)(card, in_path, file_out);
  236|      0|	card->max_recv_size = card_max_recv_size;
  237|      0|	card->reader->max_recv_size = reader_max_recv_size;
  238|      0|	return rv;
  239|      0|}

sc_get_setcos_driver:
 1130|    295|{
 1131|    295|	return sc_get_driver();
 1132|    295|}
card-setcos.c:sc_get_driver:
 1110|    295|{
 1111|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 1112|       |
 1113|    295|	setcos_ops = *iso_drv->ops;
 1114|    295|	setcos_ops.match_card = setcos_match_card;
 1115|    295|	setcos_ops.init = setcos_init;
 1116|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (1116:6): [True: 1, False: 294]
  ------------------
 1117|      1|		iso_ops = iso_drv->ops;
 1118|    295|	setcos_ops.create_file = setcos_create_file;
 1119|    295|	setcos_ops.set_security_env = setcos_set_security_env;
 1120|    295|	setcos_ops.select_file = setcos_select_file;
 1121|    295|	setcos_ops.list_files = setcos_list_files;
 1122|    295|	setcos_ops.process_fci = setcos_process_fci;
 1123|    295|	setcos_ops.construct_fci = setcos_construct_fci;
 1124|    295|	setcos_ops.card_ctl = setcos_card_ctl;
 1125|       |
 1126|    295|	return &setcos_drv;
 1127|    295|}
card-setcos.c:setcos_match_card:
   83|     51|{
   84|     51|	sc_apdu_t apdu;
   85|     51|	u8 buf[6];
   86|     51|	int i;
   87|       |
   88|     51|	i = _sc_match_atr(card, setcos_atrs, &card->type);
   89|     51|	if (i < 0) {
  ------------------
  |  Branch (89:6): [True: 51, False: 0]
  ------------------
   90|     51|		if (match_hist_bytes(card, "FISE", 0)) {
  ------------------
  |  Branch (90:7): [True: 0, False: 51]
  ------------------
   91|      0|			card->type = SC_CARD_TYPE_SETCOS_GENERIC;
   92|      0|			return 1;
   93|      0|		}
   94|       |		/* Check if it's a EID2.x applet by reading the version info */
   95|     51|		sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xCA, 0xDF, 0x30);
  ------------------
  |  |  292|     51|#define SC_APDU_CASE_2_SHORT		0x02
  ------------------
   96|     51|		apdu.cla = 0x00;
   97|     51|		apdu.resp = buf;
   98|     51|		apdu.resplen = 5;
   99|     51|		apdu.le = 5;
  100|     51|		i = sc_transmit_apdu(card, &apdu);
  101|     51|		if (i == 0 && apdu.sw1 == 0x90 && apdu.sw2 == 0x00 && apdu.resplen == 5) {
  ------------------
  |  Branch (101:7): [True: 51, False: 0]
  |  Branch (101:17): [True: 0, False: 51]
  |  Branch (101:37): [True: 0, False: 0]
  |  Branch (101:57): [True: 0, False: 0]
  ------------------
  102|      0|			if (memcmp(buf, "v2.0", 4) == 0)
  ------------------
  |  Branch (102:8): [True: 0, False: 0]
  ------------------
  103|      0|				card->type = SC_CARD_TYPE_SETCOS_EID_V2_0;
  104|      0|			else if (memcmp(buf, "v2.1", 4) == 0)
  ------------------
  |  Branch (104:13): [True: 0, False: 0]
  ------------------
  105|      0|				card->type = SC_CARD_TYPE_SETCOS_EID_V2_1;
  106|      0|			else {
  107|      0|				buf[sizeof(buf) - 1] = '\0';
  108|      0|				sc_log(card->ctx,  "SetCOS EID applet %s is not supported", (char *) buf);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  109|      0|				return 0;
  110|      0|			}
  111|      0|			return 1;
  112|      0|		}
  113|       |
  114|     51|		return 0;
  115|     51|	}
  116|      0|	card->flags = setcos_atrs[i].flags;
  117|      0|	return 1;
  118|     51|}
card-setcos.c:match_hist_bytes:
   64|     51|{
   65|     51|	const char *src = (const char *) card->reader->atr_info.hist_bytes;
   66|     51|	size_t srclen = card->reader->atr_info.hist_bytes_len;
   67|     51|	size_t offset = 0;
   68|       |
   69|     51|	if (len == 0)
  ------------------
  |  Branch (69:6): [True: 51, False: 0]
  ------------------
   70|     51|		len = strlen(str);
   71|     51|	if (srclen < len)
  ------------------
  |  Branch (71:6): [True: 51, False: 0]
  ------------------
   72|     51|		return 0;
   73|      0|	while (srclen - offset > len) {
  ------------------
  |  Branch (73:9): [True: 0, False: 0]
  ------------------
   74|      0|		if (memcmp(src + offset, str, len) == 0) {
  ------------------
  |  Branch (74:7): [True: 0, False: 0]
  ------------------
   75|      0|			return 1;
   76|      0|		}
   77|      0|		offset++;
   78|      0|	}
   79|      0|	return 0;
   80|      0|}

sc_get_skeid_driver:
  179|    295|{
  180|    295|	if (iso_ops == NULL) iso_ops = sc_get_iso7816_driver()->ops;
  ------------------
  |  Branch (180:6): [True: 1, False: 294]
  ------------------
  181|    295|	skeid_ops = *iso_ops;
  182|    295|	skeid_ops.match_card = skeid_match_card;
  183|    295|	skeid_ops.init = skeid_init;
  184|    295|	skeid_ops.set_security_env = skeid_set_security_env;
  185|    295|	skeid_ops.logout = skeid_logout;
  186|    295|	return &skeid_drv;
  187|    295|}
card-skeid.c:skeid_match_card:
   73|     51|{
   74|     51|	if (_sc_match_atr(card, skeid_atrs, &card->type) < 0 || skeid_known_url(card) != SC_SUCCESS)
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (74:6): [True: 51, False: 0]
  |  Branch (74:58): [True: 0, False: 0]
  ------------------
   75|     51|		return 0;
   76|       |
   77|      0|	sc_log(card->ctx,  "Slovak eID card v3 (CardOS 5.4)");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
   78|       |
   79|      0|	return 1;
   80|     51|}

sc_get_srbeid_driver:
  305|    295|{
  306|       |	/* Save ISO ops for delegation, then override what we handle. */
  307|    295|	iso_ops = sc_get_iso7816_driver()->ops;
  308|    295|	srbeid_ops = *iso_ops;
  309|    295|	srbeid_ops.match_card = srbeid_match_card;
  310|    295|	srbeid_ops.init = srbeid_init;
  311|    295|	srbeid_ops.select_file = srbeid_select_file;
  312|    295|	srbeid_ops.set_security_env = srbeid_set_security_env;
  313|    295|	srbeid_ops.compute_signature = srbeid_compute_signature;
  314|    295|	srbeid_ops.decipher = srbeid_decipher;
  315|       |
  316|    295|	return &srbeid_drv;
  317|    295|}
card-srbeid.c:srbeid_match_card:
   72|     51|{
   73|     51|	int i = _sc_match_atr(card, srbeid_atrs, &card->type);
   74|     51|	if (i >= 0 && iso7816_select_aid(card, AID_PKCS15, AID_PKCS15_LEN, NULL, NULL) == SC_SUCCESS) {
  ------------------
  |  |   30|      0|#define AID_PKCS15_LEN (sizeof(AID_PKCS15))
  ------------------
              	if (i >= 0 && iso7816_select_aid(card, AID_PKCS15, AID_PKCS15_LEN, NULL, NULL) == SC_SUCCESS) {
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (74:6): [True: 0, False: 51]
  |  Branch (74:16): [True: 0, False: 0]
  ------------------
   75|      0|		card->name = srbeid_atrs[i].name;
   76|      0|		return 1;
   77|      0|	}
   78|     51|	return 0;
   79|     51|}

sc_get_starcos_driver:
 2118|    295|{
 2119|    295|	return sc_get_driver();
 2120|    295|}
card-starcos.c:sc_get_driver:
 2093|    295|{
 2094|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 2095|    295|	if (iso_ops == NULL)
  ------------------
  |  Branch (2095:6): [True: 1, False: 294]
  ------------------
 2096|      1|		iso_ops = iso_drv->ops;
 2097|       |
 2098|    295|	starcos_ops = *iso_drv->ops;
 2099|    295|	starcos_ops.match_card = starcos_match_card;
 2100|    295|	starcos_ops.init   = starcos_init;
 2101|    295|	starcos_ops.finish = starcos_finish;
 2102|    295|	starcos_ops.select_file = starcos_select_file;
 2103|    295|	starcos_ops.get_challenge = starcos_get_challenge;
 2104|    295|	starcos_ops.check_sw    = starcos_check_sw;
 2105|    295|	starcos_ops.create_file = starcos_create_file;
 2106|    295|	starcos_ops.delete_file = NULL;
 2107|    295|	starcos_ops.set_security_env  = starcos_set_security_env;
 2108|    295|	starcos_ops.compute_signature = starcos_compute_signature;
 2109|    295|	starcos_ops.decipher = starcos_decipher;
 2110|    295|	starcos_ops.card_ctl    = starcos_card_ctl;
 2111|    295|	starcos_ops.logout      = starcos_logout;
 2112|    295|	starcos_ops.pin_cmd     = starcos_pin_cmd;
 2113|       |
 2114|    295|	return &starcos_drv;
 2115|    295|}
card-starcos.c:starcos_match_card:
  125|     51|{
  126|     51|	int i;
  127|       |
  128|     51|	i = _sc_match_atr(card, starcos_atrs, &card->type);
  129|     51|	if (i < 0)
  ------------------
  |  Branch (129:6): [True: 51, False: 0]
  ------------------
  130|     51|		return 0;
  131|      0|	return 1;
  132|     51|}

sc_get_tcos_driver:
  739|    295|{
  740|    295|	struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
  741|       |
  742|    295|	if (iso_ops == NULL) iso_ops = iso_drv->ops;
  ------------------
  |  Branch (742:6): [True: 1, False: 294]
  ------------------
  743|    295|	tcos_ops = *iso_drv->ops;
  744|       |
  745|    295|	tcos_ops.match_card           = tcos_match_card;
  746|    295|	tcos_ops.init                 = tcos_init;
  747|    295|	tcos_ops.finish               = tcos_finish;
  748|    295|	tcos_ops.create_file          = tcos_create_file;
  749|    295|	tcos_ops.set_security_env     = tcos_set_security_env;
  750|    295|	tcos_ops.select_file          = tcos_select_file;
  751|    295|	tcos_ops.list_files           = tcos_list_files;
  752|    295|	tcos_ops.delete_file          = tcos_delete_file;
  753|    295|	tcos_ops.compute_signature    = tcos_compute_signature;
  754|    295|	tcos_ops.decipher             = tcos_decipher;
  755|    295|	tcos_ops.restore_security_env = tcos_restore_security_env;
  756|    295|	tcos_ops.card_ctl             = tcos_card_ctl;
  757|       |
  758|    295|	return &tcos_drv;
  759|    295|}
card-tcos.c:tcos_match_card:
   77|     51|{
   78|     51|	int i;
   79|       |
   80|     51|	i = _sc_match_atr(card, tcos_atrs, &card->type);
   81|     51|	if (i < 0)
  ------------------
  |  Branch (81:6): [True: 51, False: 0]
  ------------------
   82|     51|		return 0;
   83|      0|	return 1;
   84|     51|}

sc_check_sw:
   45|  2.14k|{
   46|  2.14k|	if (card == NULL)
  ------------------
  |  Branch (46:6): [True: 0, False: 2.14k]
  ------------------
   47|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
   48|  2.14k|	if (card->ops->check_sw == NULL)
  ------------------
  |  Branch (48:6): [True: 0, False: 2.14k]
  ------------------
   49|      0|		return SC_ERROR_NOT_SUPPORTED;
  ------------------
  |  |   89|      0|#define SC_ERROR_NOT_SUPPORTED			-1408
  ------------------
   50|  2.14k|	return card->ops->check_sw(card, sw1, sw2);
   51|  2.14k|}
sc_format_apdu:
   55|  2.24k|{
   56|  2.24k|	if (card == NULL || apdu == NULL) {
  ------------------
  |  Branch (56:6): [True: 0, False: 2.24k]
  |  Branch (56:22): [True: 0, False: 2.24k]
  ------------------
   57|      0|		return;
   58|      0|	}
   59|  2.24k|	memset(apdu, 0, sizeof(*apdu));
   60|  2.24k|	apdu->cla = (u8) card->cla;
   61|  2.24k|	apdu->cse = cse;
   62|  2.24k|	apdu->ins = (u8) ins;
   63|  2.24k|	apdu->p1 = (u8) p1;
   64|  2.24k|	apdu->p2 = (u8) p2;
   65|  2.24k|}
sc_format_apdu_cse_lc_le:
   68|     51|{
   69|       |	/* TODO calculating the APDU case, Lc and Le should actually only be
   70|       |	 * done in sc_apdu2bytes, but to gradually change OpenSC we start here. */
   71|       |	/* Let sc_detect_apdu_cse set short or extended  and test for chaining */
   72|       |
   73|     51|	if (!apdu)
  ------------------
  |  Branch (73:6): [True: 0, False: 51]
  ------------------
   74|      0|		return;
   75|     51|	if (apdu->datalen > SC_MAX_APDU_DATA_SIZE
  ------------------
  |  |   35|    102|#define SC_MAX_APDU_DATA_SIZE		0xFF
  ------------------
  |  Branch (75:6): [True: 0, False: 51]
  ------------------
   76|     51|			|| apdu->resplen > SC_MAX_APDU_RESP_SIZE) {
  ------------------
  |  |   36|     51|#define SC_MAX_APDU_RESP_SIZE		(0xFF+1)
  ------------------
  |  Branch (76:7): [True: 0, False: 51]
  ------------------
   77|       |		/* extended length  or data chaining and/or get response */
   78|      0|		if (apdu->datalen <= SC_MAX_EXT_APDU_DATA_SIZE)
  ------------------
  |  |   38|      0|#define SC_MAX_EXT_APDU_DATA_SIZE		0xFFFF
  ------------------
  |  Branch (78:7): [True: 0, False: 0]
  ------------------
   79|      0|			apdu->lc = apdu->datalen;
   80|      0|		if (apdu->resplen <= SC_MAX_EXT_APDU_RESP_SIZE)
  ------------------
  |  |   39|      0|#define SC_MAX_EXT_APDU_RESP_SIZE		(0xFFFF+1)
  ------------------
  |  Branch (80:7): [True: 0, False: 0]
  ------------------
   81|      0|			apdu->le = apdu->resplen;
   82|      0|		if (apdu->resplen && !apdu->datalen)
  ------------------
  |  Branch (82:7): [True: 0, False: 0]
  |  Branch (82:24): [True: 0, False: 0]
  ------------------
   83|      0|			apdu->cse = SC_APDU_CASE_2;
  ------------------
  |  |  301|      0|#define SC_APDU_CASE_2			0x22
  ------------------
   84|      0|		if (!apdu->resplen && apdu->datalen)
  ------------------
  |  Branch (84:7): [True: 0, False: 0]
  |  Branch (84:25): [True: 0, False: 0]
  ------------------
   85|      0|			apdu->cse = SC_APDU_CASE_3;
  ------------------
  |  |  302|      0|#define SC_APDU_CASE_3			0x23
  ------------------
   86|      0|		if (apdu->resplen && apdu->datalen)
  ------------------
  |  Branch (86:7): [True: 0, False: 0]
  |  Branch (86:24): [True: 0, False: 0]
  ------------------
   87|      0|			apdu->cse = SC_APDU_CASE_4;
  ------------------
  |  |  303|      0|#define SC_APDU_CASE_4			0x24
  ------------------
   88|     51|	} else {
   89|       |		/* short length */
   90|     51|		if (apdu->datalen <= SC_MAX_APDU_DATA_SIZE)
  ------------------
  |  |   35|     51|#define SC_MAX_APDU_DATA_SIZE		0xFF
  ------------------
  |  Branch (90:7): [True: 51, False: 0]
  ------------------
   91|     51|			apdu->lc = apdu->datalen;
   92|     51|		if (apdu->resplen <= SC_MAX_APDU_RESP_SIZE)
  ------------------
  |  |   36|     51|#define SC_MAX_APDU_RESP_SIZE		(0xFF+1)
  ------------------
  |  Branch (92:7): [True: 51, False: 0]
  ------------------
   93|     51|			apdu->le = apdu->resplen;
   94|     51|		if (!apdu->resplen && !apdu->datalen)
  ------------------
  |  Branch (94:7): [True: 51, False: 0]
  |  Branch (94:25): [True: 0, False: 51]
  ------------------
   95|      0|			apdu->cse = SC_APDU_CASE_1;
  ------------------
  |  |  291|      0|#define SC_APDU_CASE_1			0x01
  ------------------
   96|     51|		if (apdu->resplen && !apdu->datalen)
  ------------------
  |  Branch (96:7): [True: 0, False: 51]
  |  Branch (96:24): [True: 0, False: 0]
  ------------------
   97|      0|			apdu->cse = SC_APDU_CASE_2_SHORT;
  ------------------
  |  |  292|      0|#define SC_APDU_CASE_2_SHORT		0x02
  ------------------
   98|     51|		if (!apdu->resplen && apdu->datalen)
  ------------------
  |  Branch (98:7): [True: 51, False: 0]
  |  Branch (98:25): [True: 51, False: 0]
  ------------------
   99|     51|			apdu->cse = SC_APDU_CASE_3_SHORT;
  ------------------
  |  |  293|     51|#define SC_APDU_CASE_3_SHORT		0x03
  ------------------
  100|     51|		if (apdu->resplen && apdu->datalen)
  ------------------
  |  Branch (100:7): [True: 0, False: 51]
  |  Branch (100:24): [True: 0, False: 0]
  ------------------
  101|      0|			apdu->cse = SC_APDU_CASE_4_SHORT;
  ------------------
  |  |  294|      0|#define SC_APDU_CASE_4_SHORT		0x04
  ------------------
  102|     51|	}
  103|     51|}
sc_format_apdu_ex:
  109|     51|{
  110|     51|	if (!apdu) {
  ------------------
  |  Branch (110:6): [True: 0, False: 51]
  ------------------
  111|      0|		return;
  112|      0|	}
  113|       |
  114|     51|	memset(apdu, 0, sizeof(*apdu));
  115|     51|	apdu->cla = cla;
  116|     51|	apdu->ins = ins;
  117|     51|	apdu->p1 = p1;
  118|     51|	apdu->p2 = p2;
  119|     51|	apdu->resp = resp;
  120|     51|	apdu->resplen = resplen;
  121|     51|	apdu->data = data;
  122|     51|	apdu->datalen = datalen;
  123|     51|	sc_format_apdu_cse_lc_le(apdu);
  124|     51|}
sc_get_max_recv_size:
  188|  1.83k|{
  189|  1.83k|	size_t max_recv_size;
  190|  1.83k|	if (card == NULL || card->reader == NULL) {
  ------------------
  |  Branch (190:6): [True: 0, False: 1.83k]
  |  Branch (190:22): [True: 0, False: 1.83k]
  ------------------
  191|      0|		return 0;
  192|      0|	}
  193|  1.83k|	max_recv_size = card->max_recv_size;
  194|       |
  195|       |	/* initialize max_recv_size to a meaningful value */
  196|  1.83k|	if (card->caps & SC_CARD_CAP_APDU_EXT) {
  ------------------
  |  |  554|  1.83k|#define SC_CARD_CAP_APDU_EXT		0x00000001
  ------------------
  |  Branch (196:6): [True: 0, False: 1.83k]
  ------------------
  197|      0|		if (!max_recv_size)
  ------------------
  |  Branch (197:7): [True: 0, False: 0]
  ------------------
  198|      0|			max_recv_size = 65536;
  199|  1.83k|	} else {
  200|  1.83k|		if (!max_recv_size)
  ------------------
  |  Branch (200:7): [True: 1.78k, False: 51]
  ------------------
  201|  1.78k|			max_recv_size = 256;
  202|  1.83k|	}
  203|       |
  204|       |	/*  Override card limitations with reader limitations. */
  205|  1.83k|	if (card->reader->max_recv_size != 0
  ------------------
  |  Branch (205:6): [True: 51, False: 1.78k]
  ------------------
  206|     51|			&& (card->reader->max_recv_size < card->max_recv_size))
  ------------------
  |  Branch (206:7): [True: 0, False: 51]
  ------------------
  207|      0|		max_recv_size = card->reader->max_recv_size;
  208|       |
  209|  1.83k|	return max_recv_size;
  210|  1.83k|}
sc_connect_card:
  241|     51|{
  242|     51|	sc_card_t *card;
  243|     51|	sc_context_t *ctx;
  244|     51|	struct sc_card_driver *driver;
  245|     51|	int i, r = 0, idx, connected = 0;
  246|       |
  247|     51|	if (card_out == NULL || reader == NULL)
  ------------------
  |  Branch (247:6): [True: 0, False: 51]
  |  Branch (247:26): [True: 0, False: 51]
  ------------------
  248|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  249|     51|	ctx = reader->ctx;
  250|     51|	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|     51|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|     51|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|     51|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 51]
  |  |  ------------------
  ------------------
  251|     51|	if (reader->ops->connect == NULL)
  ------------------
  |  Branch (251:6): [True: 0, False: 51]
  ------------------
  252|     51|		LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  253|       |
  254|     51|	card = sc_card_new(ctx);
  255|     51|	if (card == NULL)
  ------------------
  |  Branch (255:6): [True: 0, False: 51]
  ------------------
  256|     51|		LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  257|     51|	r = reader->ops->connect(reader);
  258|     51|	if (r)
  ------------------
  |  Branch (258:6): [True: 0, False: 51]
  ------------------
  259|      0|		goto err;
  260|       |
  261|     51|	connected = 1;
  262|     51|	card->reader = reader;
  263|     51|	card->ctx = ctx;
  264|       |
  265|     51|	if (reader->flags & SC_READER_ENABLE_ESCAPE)
  ------------------
  |  |  379|     51|#define SC_READER_ENABLE_ESCAPE		0x00000040
  ------------------
  |  Branch (265:6): [True: 0, False: 51]
  ------------------
  266|      0|		sc_detect_escape_cmds(reader);
  267|       |
  268|     51|	memcpy(&card->atr, &reader->atr, sizeof(card->atr));
  269|     51|	memcpy(&card->uid, &reader->uid, sizeof(card->uid));
  270|       |
  271|     51|	_sc_parse_atr(reader);
  272|       |
  273|       |	/* See if the ATR matches any ATR specified in the config file */
  274|     51|	if ((driver = ctx->forced_driver) == NULL) {
  ------------------
  |  Branch (274:6): [True: 51, False: 0]
  ------------------
  275|     51|		sc_log(ctx, "matching configured ATRs");
  ------------------
  |  |   71|     51|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  276|  2.29k|		for (i = 0; ctx->card_drivers[i] != NULL; i++) {
  ------------------
  |  Branch (276:15): [True: 2.24k, False: 51]
  ------------------
  277|  2.24k|			driver = ctx->card_drivers[i];
  278|       |
  279|  2.24k|			if (driver->atr_map == NULL ||
  ------------------
  |  Branch (279:8): [True: 2.24k, False: 0]
  ------------------
  280|  2.24k|			    !strcmp(driver->short_name, "default")) {
  ------------------
  |  Branch (280:8): [True: 0, False: 0]
  ------------------
  281|  2.24k|				driver = NULL;
  282|  2.24k|				continue;
  283|  2.24k|			}
  284|      0|			sc_log(ctx, "trying driver '%s'", driver->short_name);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  285|      0|			idx = _sc_match_atr(card, driver->atr_map, NULL);
  286|      0|			if (idx >= 0) {
  ------------------
  |  Branch (286:8): [True: 0, False: 0]
  ------------------
  287|      0|				struct sc_atr_table *src = &driver->atr_map[idx];
  288|       |
  289|      0|				sc_log(ctx, "matched driver '%s'", driver->name);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  290|       |				/* It's up to card driver to notice these correctly */
  291|      0|				card->name = src->name;
  292|      0|				card->type = src->type;
  293|      0|				card->flags = src->flags;
  294|      0|				break;
  295|      0|			}
  296|      0|			driver = NULL;
  297|      0|		}
  298|     51|	}
  299|       |
  300|     51|	if (driver != NULL) {
  ------------------
  |  Branch (300:6): [True: 0, False: 51]
  ------------------
  301|       |		/* Forced driver, or matched via ATR mapping from config file */
  302|      0|		card->driver = driver;
  303|       |
  304|      0|		memcpy(card->ops, card->driver->ops, sizeof(struct sc_card_operations));
  305|      0|		if (card->ops->match_card != NULL)
  ------------------
  |  Branch (305:7): [True: 0, False: 0]
  ------------------
  306|      0|			if (card->ops->match_card(card) != 1)
  ------------------
  |  Branch (306:8): [True: 0, False: 0]
  ------------------
  307|      0|				sc_log(ctx, "driver '%s' match_card() failed: %s (will continue anyway)", card->driver->name, sc_strerror(r));
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  308|       |
  309|      0|		if (card->ops->init != NULL) {
  ------------------
  |  Branch (309:7): [True: 0, False: 0]
  ------------------
  310|      0|			r = card->ops->init(card);
  311|      0|			if (r) {
  ------------------
  |  Branch (311:8): [True: 0, False: 0]
  ------------------
  312|      0|				sc_log(ctx, "driver '%s' init() failed: %s", card->driver->name, sc_strerror(r));
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  313|      0|				goto err;
  314|      0|			}
  315|      0|		}
  316|      0|	}
  317|     51|	else {
  318|     51|		sc_card_t uninitialized = *card;
  319|     51|		sc_log(ctx, "matching built-in ATRs");
  ------------------
  |  |   71|     51|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  320|  2.29k|		for (i = 0; ctx->card_drivers[i] != NULL; i++) {
  ------------------
  |  Branch (320:15): [True: 2.24k, False: 51]
  ------------------
  321|       |			/* FIXME If we had a clean API description, we'd probably get a
  322|       |			 * cleaner implementation of the driver's match_card and init,
  323|       |			 * which should normally *not* modify the card object if
  324|       |			 * unsuccessful. However, after years of relentless hacking, reality
  325|       |			 * is different: The card object is changed in virtually every card
  326|       |			 * driver so in order to prevent unwanted interaction, we reset the
  327|       |			 * card object here and hope that the card driver at least doesn't
  328|       |			 * allocate any internal resources that need to be freed. If we
  329|       |			 * had more time, we should refactor the existing code to not
  330|       |			 * modify sc_card_t until complete success (possibly by combining
  331|       |			 * `match_card()` and `init()`) */
  332|  2.24k|			*card = uninitialized;
  333|       |
  334|  2.24k|			struct sc_card_driver *drv = ctx->card_drivers[i];
  335|  2.24k|			const struct sc_card_operations *ops = drv->ops;
  336|       |
  337|  2.24k|			sc_log(ctx, "trying driver '%s'", drv->short_name);
  ------------------
  |  |   71|  2.24k|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  338|  2.24k|			if (ops == NULL || ops->match_card == NULL)   {
  ------------------
  |  Branch (338:8): [True: 0, False: 2.24k]
  |  Branch (338:23): [True: 0, False: 2.24k]
  ------------------
  339|      0|				continue;
  340|      0|			}
  341|  2.24k|			else if (!(ctx->flags & SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER)
  ------------------
  |  |  867|  2.24k|#define SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER	0x00000008
  ------------------
  |  Branch (341:13): [True: 2.24k, False: 0]
  ------------------
  342|  2.24k|				   	&& !strcmp("default", drv->short_name))   {
  ------------------
  |  Branch (342:12): [True: 51, False: 2.19k]
  ------------------
  343|     51|				sc_log(ctx , "ignore 'default' card driver");
  ------------------
  |  |   71|     51|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  344|     51|				continue;
  345|     51|			}
  346|       |
  347|       |			/* Needed if match_card() needs to talk with the card (e.g. card-muscle) */
  348|  2.19k|			*card->ops = *ops;
  349|  2.19k|			if (ops->match_card(card) != 1)
  ------------------
  |  Branch (349:8): [True: 2.19k, False: 0]
  ------------------
  350|  2.19k|				continue;
  351|      0|			sc_log(ctx, "matched: %s", drv->name);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  352|      0|			memcpy(card->ops, ops, sizeof(struct sc_card_operations));
  353|      0|			card->driver = drv;
  354|      0|			r = ops->init(card);
  355|      0|			if (r) {
  ------------------
  |  Branch (355:8): [True: 0, False: 0]
  ------------------
  356|      0|				sc_log(ctx, "driver '%s' init() failed: %s", drv->name, sc_strerror(r));
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  357|      0|				if (r == SC_ERROR_INVALID_CARD) {
  ------------------
  |  |   60|      0|#define SC_ERROR_INVALID_CARD			-1210
  ------------------
  |  Branch (357:9): [True: 0, False: 0]
  ------------------
  358|      0|					card->driver = NULL;
  359|      0|					continue;
  360|      0|				}
  361|      0|				goto err;
  362|      0|			}
  363|      0|			break;
  364|      0|		}
  365|     51|	}
  366|     51|	if (card->driver == NULL) {
  ------------------
  |  Branch (366:6): [True: 51, False: 0]
  ------------------
  367|     51|		sc_log(ctx, "unable to find driver for inserted card");
  ------------------
  |  |   71|     51|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  368|     51|		r = SC_ERROR_INVALID_CARD;
  ------------------
  |  |   60|     51|#define SC_ERROR_INVALID_CARD			-1210
  ------------------
  369|     51|		goto err;
  370|     51|	}
  371|      0|	if (card->name == NULL)
  ------------------
  |  Branch (371:6): [True: 0, False: 0]
  ------------------
  372|      0|		card->name = card->driver->name;
  373|       |
  374|       |	/* initialize max_send_size/max_recv_size to a meaningful value */
  375|      0|	card->max_recv_size = sc_get_max_recv_size(card);
  376|      0|	card->max_send_size = sc_get_max_send_size(card);
  377|       |
  378|      0|	sc_log(ctx,
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  379|      0|	       "card info name:'%s', type:%i, flags:0x%lX, max_send/recv_size:%"SC_FORMAT_LEN_SIZE_T"u/%"SC_FORMAT_LEN_SIZE_T"u",
  380|      0|	       card->name, card->type, card->flags, card->max_send_size,
  381|      0|	       card->max_recv_size);
  382|       |
  383|      0|#ifdef ENABLE_SM
  384|       |        /* Check, if secure messaging module present. */
  385|      0|	r = sc_card_sm_check(card);
  386|      0|	if (r)   {
  ------------------
  |  Branch (386:6): [True: 0, False: 0]
  ------------------
  387|      0|		sc_log(ctx, "cannot load secure messaging module");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  388|      0|		goto err;
  389|      0|	}
  390|      0|#endif
  391|      0|	*card_out = card;
  392|       |
  393|      0|	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  394|     51|err:
  395|     51|	if (connected)
  ------------------
  |  Branch (395:6): [True: 51, False: 0]
  ------------------
  396|     51|		reader->ops->disconnect(reader);
  397|     51|	if (card != NULL)
  ------------------
  |  Branch (397:6): [True: 51, False: 0]
  ------------------
  398|     51|		sc_card_free(card);
  399|     51|	LOG_FUNC_RETURN(ctx, r);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|     51|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  400|     51|}
sc_disconnect_card:
  403|    295|{
  404|    295|	sc_context_t *ctx;
  405|       |
  406|    295|	if (!card)
  ------------------
  |  Branch (406:6): [True: 295, False: 0]
  ------------------
  407|    295|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|    295|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  408|       |
  409|      0|	ctx = card->ctx;
  410|      0|	LOG_FUNC_CALLED(ctx);
  ------------------
  |  |  151|      0|#define LOG_FUNC_CALLED(ctx) SC_FUNC_CALLED((ctx), SC_LOG_DEBUG_NORMAL)
  |  |  ------------------
  |  |  |  |  148|      0|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  |  |  149|      0|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  150|      0|} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (150:10): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  411|       |
  412|      0|	if (card->ops->finish) {
  ------------------
  |  Branch (412:6): [True: 0, False: 0]
  ------------------
  413|      0|		int r = card->ops->finish(card);
  414|      0|		if (r)
  ------------------
  |  Branch (414:7): [True: 0, False: 0]
  ------------------
  415|      0|			sc_log(ctx, "card driver finish() failed: %s", sc_strerror(r));
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  416|      0|	}
  417|       |
  418|      0|	if (card->reader->ops->disconnect) {
  ------------------
  |  Branch (418:6): [True: 0, False: 0]
  ------------------
  419|      0|		int r = card->reader->ops->disconnect(card->reader);
  420|      0|		if (r)
  ------------------
  |  Branch (420:7): [True: 0, False: 0]
  ------------------
  421|      0|			sc_log(ctx, "disconnect() failed: %s", sc_strerror(r));
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  422|      0|	}
  423|       |
  424|      0|#ifdef ENABLE_SM
  425|       |	/* release SM related resources */
  426|      0|	sc_card_sm_unload(card);
  427|      0|#endif
  428|       |
  429|      0|	sc_card_free(card);
  430|      0|	LOG_FUNC_RETURN(ctx, SC_SUCCESS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  431|      0|}
sc_lock:
  458|  2.29k|{
  459|  2.29k|	int r = 0, r2 = 0;
  460|  2.29k|	int was_reset = 0;
  461|  2.29k|	int reader_lock_obtained  = 0;
  462|       |
  463|  2.29k|	if (card == NULL)
  ------------------
  |  Branch (463:6): [True: 0, False: 2.29k]
  ------------------
  464|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  465|       |
  466|  2.29k|	LOG_FUNC_CALLED(card->ctx);
  ------------------
  |  |  151|  2.29k|#define LOG_FUNC_CALLED(ctx) SC_FUNC_CALLED((ctx), SC_LOG_DEBUG_NORMAL)
  |  |  ------------------
  |  |  |  |  148|  2.29k|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  |  |  149|  2.29k|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  150|  2.29k|} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (150:10): [Folded, False: 2.29k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  467|       |
  468|  2.29k|	r = sc_mutex_lock(card->ctx, card->mutex);
  469|  2.29k|	if (r != SC_SUCCESS)
  ------------------
  |  |   28|  2.29k|#define SC_SUCCESS				0
  ------------------
  |  Branch (469:6): [True: 0, False: 2.29k]
  ------------------
  470|      0|		return r;
  471|  2.29k|	if (card->lock_count == 0) {
  ------------------
  |  Branch (471:6): [True: 2.24k, False: 51]
  ------------------
  472|  2.24k|		if (card->reader->ops->lock != NULL) {
  ------------------
  |  Branch (472:7): [True: 2.24k, False: 0]
  ------------------
  473|  2.24k|			r = card->reader->ops->lock(card->reader);
  474|  2.24k|			while (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) {
  ------------------
  |  |   37|  4.48k|#define SC_ERROR_CARD_RESET			-1106
  ------------------
              			while (r == SC_ERROR_CARD_RESET || r == SC_ERROR_READER_REATTACHED) {
  ------------------
  |  |   46|  2.24k|#define SC_ERROR_READER_REATTACHED		-1115
  ------------------
  |  Branch (474:11): [True: 0, False: 2.24k]
  |  Branch (474:39): [True: 0, False: 2.24k]
  ------------------
  475|      0|				if (was_reset++ > 4) /* TODO retry a few times */
  ------------------
  |  Branch (475:9): [True: 0, False: 0]
  ------------------
  476|      0|					break;
  477|      0|				r = card->reader->ops->lock(card->reader);
  478|      0|			}
  479|  2.24k|			if (r == 0)
  ------------------
  |  Branch (479:8): [True: 2.24k, False: 0]
  ------------------
  480|  2.24k|				reader_lock_obtained = 1;
  481|  2.24k|		}
  482|  2.24k|	}
  483|  2.29k|	if (r == 0)
  ------------------
  |  Branch (483:6): [True: 2.29k, False: 0]
  ------------------
  484|  2.29k|		card->lock_count++;
  485|       |
  486|  2.29k|	r2 = sc_mutex_unlock(card->ctx, card->mutex);
  487|  2.29k|	if (r2 != SC_SUCCESS) {
  ------------------
  |  |   28|  2.29k|#define SC_SUCCESS				0
  ------------------
  |  Branch (487:6): [True: 0, False: 2.29k]
  ------------------
  488|      0|		sc_log(card->ctx, "unable to release card->mutex lock");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  489|      0|		r = r != SC_SUCCESS ? r : r2;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (489:7): [True: 0, False: 0]
  ------------------
  490|      0|	}
  491|       |
  492|  2.29k|	if (r == 0 && was_reset > 0) {
  ------------------
  |  Branch (492:6): [True: 2.29k, False: 0]
  |  Branch (492:16): [True: 0, False: 2.29k]
  ------------------
  493|      0|#ifdef ENABLE_SM
  494|      0|		if (card->sm_ctx.ops.open)
  ------------------
  |  Branch (494:7): [True: 0, False: 0]
  ------------------
  495|      0|			card->sm_ctx.ops.open(card);
  496|      0|#endif
  497|      0|	}
  498|       |
  499|       |	/* give card driver a chance to do something when reader lock first obtained */
  500|  2.29k|	if (r == 0 && reader_lock_obtained == 1  && card->ops->card_reader_lock_obtained) {
  ------------------
  |  Branch (500:6): [True: 2.29k, False: 0]
  |  Branch (500:16): [True: 2.24k, False: 51]
  |  Branch (500:46): [True: 357, False: 1.88k]
  ------------------
  501|    357|		if (SC_SUCCESS != card->ops->card_reader_lock_obtained(card, was_reset))
  ------------------
  |  |   28|    357|#define SC_SUCCESS				0
  ------------------
  |  Branch (501:7): [True: 0, False: 357]
  ------------------
  502|      0|			sc_log(card->ctx, "card_reader_lock_obtained failed");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  503|    357|	}
  504|       |
  505|  2.29k|	LOG_FUNC_RETURN(card->ctx, r);
  ------------------
  |  |  164|  2.29k|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|  2.29k|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|  2.29k|	int _ret = r; \
  |  |  |  |  155|  2.29k|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 2.29k, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|  2.29k|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 2.29k]
  |  |  |  |  ------------------
  |  |  |  |  157|  2.29k|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|  2.29k|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|  2.29k|	return _ret; \
  |  |  |  |  163|  2.29k|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  506|  2.29k|}
sc_unlock:
  509|  2.29k|{
  510|  2.29k|	int r, r2;
  511|       |
  512|  2.29k|	if (!card)
  ------------------
  |  Branch (512:6): [True: 0, False: 2.29k]
  ------------------
  513|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  514|       |
  515|  2.29k|	LOG_FUNC_CALLED(card->ctx);
  ------------------
  |  |  151|  2.29k|#define LOG_FUNC_CALLED(ctx) SC_FUNC_CALLED((ctx), SC_LOG_DEBUG_NORMAL)
  |  |  ------------------
  |  |  |  |  148|  2.29k|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  |  |  149|  2.29k|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  150|  2.29k|} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (150:10): [Folded, False: 2.29k]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  516|       |
  517|  2.29k|	r = sc_mutex_lock(card->ctx, card->mutex);
  518|  2.29k|	if (r != SC_SUCCESS)
  ------------------
  |  |   28|  2.29k|#define SC_SUCCESS				0
  ------------------
  |  Branch (518:6): [True: 0, False: 2.29k]
  ------------------
  519|  2.29k|		LOG_FUNC_RETURN(card->ctx, r);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  520|       |
  521|  2.29k|	if (card->lock_count < 1) {
  ------------------
  |  Branch (521:6): [True: 0, False: 2.29k]
  ------------------
  522|      0|		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  523|      0|	}
  524|  2.29k|	if (--card->lock_count == 0) {
  ------------------
  |  Branch (524:6): [True: 2.24k, False: 51]
  ------------------
  525|       |		/* release reader lock */
  526|  2.24k|		if (card->reader->ops->unlock != NULL)
  ------------------
  |  Branch (526:7): [True: 2.24k, False: 0]
  ------------------
  527|  2.24k|			r = card->reader->ops->unlock(card->reader);
  528|  2.24k|	}
  529|  2.29k|	r2 = sc_mutex_unlock(card->ctx, card->mutex);
  530|  2.29k|	if (r2 != SC_SUCCESS) {
  ------------------
  |  |   28|  2.29k|#define SC_SUCCESS				0
  ------------------
  |  Branch (530:6): [True: 0, False: 2.29k]
  ------------------
  531|      0|		sc_log(card->ctx, "unable to release lock");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  532|      0|		r = (r == SC_SUCCESS) ? r2 : r;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (532:7): [True: 0, False: 0]
  ------------------
  533|      0|	}
  534|       |
  535|  2.29k|	return r;
  536|  2.29k|}
sc_select_file:
  818|    102|{
  819|    102|	int r;
  820|    102|	char pbuf[SC_MAX_PATH_STRING_SIZE];
  821|       |
  822|    102|	if (card == NULL || in_path == NULL) {
  ------------------
  |  Branch (822:6): [True: 0, False: 102]
  |  Branch (822:22): [True: 0, False: 102]
  ------------------
  823|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  824|      0|	}
  825|       |
  826|    102|	r = sc_path_print(pbuf, sizeof(pbuf), in_path);
  827|    102|	if (r != SC_SUCCESS)
  ------------------
  |  |   28|    102|#define SC_SUCCESS				0
  ------------------
  |  Branch (827:6): [True: 0, False: 102]
  ------------------
  828|      0|		pbuf[0] = '\0';
  829|       |
  830|       |	/* FIXME We should be a bit less strict and let the upper layers do
  831|       |	 * the initialization (including reuse of existing file objects). We
  832|       |	 * implemented this here because we are lazy. */
  833|    102|	if (file != NULL)
  ------------------
  |  Branch (833:6): [True: 0, False: 102]
  ------------------
  834|      0|		*file = NULL;
  835|       |
  836|    102|	sc_log(card->ctx, "called; type=%d, path=%s", in_path->type, pbuf);
  ------------------
  |  |   71|    102|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  837|    102|	if (in_path->len > SC_MAX_PATH_SIZE)
  ------------------
  |  |   47|    102|#define SC_MAX_PATH_SIZE		16
  ------------------
  |  Branch (837:6): [True: 0, False: 102]
  ------------------
  838|    102|		LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  839|       |
  840|    102|	if (in_path->type == SC_PATH_TYPE_PATH) {
  ------------------
  |  |  119|    102|#define SC_PATH_TYPE_PATH		2
  ------------------
  |  Branch (840:6): [True: 51, False: 51]
  ------------------
  841|       |		/* Perform a sanity check */
  842|     51|		size_t i;
  843|       |
  844|     51|		if ((in_path->len & 1) != 0)
  ------------------
  |  Branch (844:7): [True: 0, False: 51]
  ------------------
  845|     51|			LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  846|       |
  847|    102|		for (i = 0; i < in_path->len/2; i++) {
  ------------------
  |  Branch (847:15): [True: 51, False: 51]
  ------------------
  848|     51|			u8 p1 = in_path->value[2*i],
  849|     51|			   p2 = in_path->value[2*i+1];
  850|       |
  851|     51|			if ((p1 == 0x3F && p2 == 0x00) && i != 0)
  ------------------
  |  Branch (851:9): [True: 51, False: 0]
  |  Branch (851:23): [True: 51, False: 0]
  |  Branch (851:38): [True: 0, False: 51]
  ------------------
  852|     51|				LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  853|     51|		}
  854|     51|	}
  855|    102|	if (card->ops->select_file == NULL)
  ------------------
  |  Branch (855:6): [True: 0, False: 102]
  ------------------
  856|    102|		LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  857|    102|	r = card->ops->select_file(card, in_path, file);
  858|    102|	LOG_TEST_RET(card->ctx, r, "'SELECT' error");
  ------------------
  |  |  174|    102|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|    102|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|    102|	int _ret = (r); \
  |  |  |  |  168|    102|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 102, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|    102|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|    102|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|    102|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|    102|		return _ret; \
  |  |  |  |  172|    102|	} \
  |  |  |  |  173|    102|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  859|       |
  860|      0|	if (file) {
  ------------------
  |  Branch (860:6): [True: 0, False: 0]
  ------------------
  861|      0|		if (*file)
  ------------------
  |  Branch (861:7): [True: 0, False: 0]
  ------------------
  862|       |			/* Remember file path */
  863|      0|			(*file)->path = *in_path;
  864|      0|		else
  865|       |			/* FIXME We should be a bit less strict and let the upper layers do
  866|       |			 * the error checking. We implemented this here because we are
  867|       |			 * lazy.  */
  868|      0|			r = SC_ERROR_INVALID_DATA;
  ------------------
  |  |   78|      0|#define SC_ERROR_INVALID_DATA			-1305
  ------------------
  869|      0|	}
  870|       |
  871|      0|	LOG_FUNC_RETURN(card->ctx, r);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  872|      0|}
_sc_match_atr:
 1341|  1.68k|{
 1342|  1.68k|	int res;
 1343|       |
 1344|  1.68k|	if (card == NULL)
  ------------------
  |  Branch (1344:6): [True: 0, False: 1.68k]
  ------------------
 1345|      0|		return -1;
 1346|  1.68k|	res = match_atr_table(card->ctx, table, &card->atr);
 1347|  1.68k|	if (res < 0)
  ------------------
  |  Branch (1347:6): [True: 1.68k, False: 0]
  ------------------
 1348|  1.68k|		return res;
 1349|      0|	if (type_out != NULL)
  ------------------
  |  Branch (1349:6): [True: 0, False: 0]
  ------------------
 1350|      0|		*type_out = table[res].type;
 1351|      0|	return res;
 1352|  1.68k|}
sc_get_conf_block:
 1453|    539|{
 1454|    539|	int i;
 1455|    539|	scconf_block *conf_block = NULL;
 1456|       |
 1457|  1.07k|	for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
  ------------------
  |  Branch (1457:14): [True: 539, False: 539]
  ------------------
 1458|    539|		scconf_block **blocks;
 1459|       |
 1460|    539|		blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], name1, name2);
 1461|    539|		if (blocks != NULL) {
  ------------------
  |  Branch (1461:7): [True: 539, False: 0]
  ------------------
 1462|    539|			conf_block = blocks[0];
 1463|    539|			free(blocks);
 1464|    539|		}
 1465|    539|		if (conf_block != NULL && priority)
  ------------------
  |  Branch (1465:7): [True: 0, False: 539]
  |  Branch (1465:29): [True: 0, False: 0]
  ------------------
 1466|      0|			break;
 1467|    539|	}
 1468|    539|	return conf_block;
 1469|    539|}
card.c:sc_card_new:
  127|     51|{
  128|     51|	sc_card_t *card;
  129|       |
  130|     51|	if (ctx == NULL)
  ------------------
  |  Branch (130:6): [True: 0, False: 51]
  ------------------
  131|      0|		return NULL;
  132|       |
  133|     51|	card = calloc(1, sizeof(struct sc_card));
  134|     51|	if (card == NULL)
  ------------------
  |  Branch (134:6): [True: 0, False: 51]
  ------------------
  135|      0|		return NULL;
  136|     51|	card->ops = malloc(sizeof(struct sc_card_operations));
  137|     51|	if (card->ops == NULL) {
  ------------------
  |  Branch (137:6): [True: 0, False: 51]
  ------------------
  138|      0|		free(card);
  139|      0|		return NULL;
  140|      0|	}
  141|       |
  142|     51|	card->ctx = ctx;
  143|     51|	if (sc_mutex_create(ctx, &card->mutex) != SC_SUCCESS) {
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  |  Branch (143:6): [True: 0, False: 51]
  ------------------
  144|      0|		free(card->ops);
  145|      0|		free(card);
  146|      0|		return NULL;
  147|      0|	}
  148|       |
  149|     51|	card->type = -1;
  150|     51|	card->app_count = -1;
  151|       |
  152|     51|	return card;
  153|     51|}
card.c:sc_card_free:
  156|     51|{
  157|     51|	sc_free_apps(card);
  158|     51|	sc_free_ef_atr(card);
  159|       |
  160|     51|	free(card->ops);
  161|       |
  162|     51|	if (card->algorithms != NULL)   {
  ------------------
  |  Branch (162:6): [True: 0, False: 51]
  ------------------
  163|      0|		int i;
  164|      0|		for (i=0; i<card->algorithm_count; i++)   {
  ------------------
  |  Branch (164:13): [True: 0, False: 0]
  ------------------
  165|      0|			struct sc_algorithm_info *info = (card->algorithms + i);
  166|      0|			if (info->algorithm == SC_ALGORITHM_EC ||
  ------------------
  |  |   79|      0|#define SC_ALGORITHM_EC		2
  ------------------
  |  Branch (166:8): [True: 0, False: 0]
  ------------------
  167|      0|					info->algorithm == SC_ALGORITHM_EDDSA ||
  ------------------
  |  |   81|      0|#define SC_ALGORITHM_EDDSA		4
  ------------------
  |  Branch (167:6): [True: 0, False: 0]
  ------------------
  168|      0|					info->algorithm == SC_ALGORITHM_XEDDSA) {
  ------------------
  |  |   82|      0|#define SC_ALGORITHM_XEDDSA		5
  ------------------
  |  Branch (168:6): [True: 0, False: 0]
  ------------------
  169|      0|				sc_clear_ec_params(&info->u._ec.params);
  170|      0|			}
  171|      0|		}
  172|      0|		free(card->algorithms);
  173|       |
  174|      0|		card->algorithms = NULL;
  175|      0|		card->algorithm_count = 0;
  176|      0|	}
  177|       |
  178|     51|	if (card->mutex != NULL) {
  ------------------
  |  Branch (178:6): [True: 0, False: 51]
  ------------------
  179|      0|		int r = sc_mutex_destroy(card->ctx, card->mutex);
  180|      0|		if (r != SC_SUCCESS)
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (180:7): [True: 0, False: 0]
  ------------------
  181|      0|			sc_log(card->ctx, "unable to destroy mutex");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  182|      0|	}
  183|     51|	sc_mem_clear(card, sizeof(*card));
  184|     51|	free(card);
  185|     51|}
card.c:match_atr_table:
 1278|  1.68k|{
 1279|  1.68k|	u8 *card_atr_bin;
 1280|  1.68k|	size_t card_atr_bin_len;
 1281|  1.68k|	char card_atr_hex[3 * SC_MAX_ATR_SIZE];
 1282|  1.68k|	size_t card_atr_hex_len;
 1283|  1.68k|	unsigned int i = 0;
 1284|       |
 1285|  1.68k|	if (ctx == NULL || table == NULL || atr == NULL)
  ------------------
  |  Branch (1285:6): [True: 0, False: 1.68k]
  |  Branch (1285:21): [True: 0, False: 1.68k]
  |  Branch (1285:38): [True: 0, False: 1.68k]
  ------------------
 1286|      0|		return -1;
 1287|  1.68k|	card_atr_bin = atr->value;
 1288|  1.68k|	card_atr_bin_len = atr->len;
 1289|  1.68k|	sc_bin_to_hex(card_atr_bin, card_atr_bin_len, card_atr_hex, sizeof(card_atr_hex), ':');
 1290|  1.68k|	card_atr_hex_len = strlen(card_atr_hex);
 1291|       |
 1292|  1.68k|	sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ATR     : %s", card_atr_hex);
  ------------------
  |  |   70|  1.68k|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1293|       |
 1294|  14.3k|	for (i = 0; table[i].atr != NULL; i++) {
  ------------------
  |  Branch (1294:14): [True: 12.6k, False: 1.68k]
  ------------------
 1295|  12.6k|		const char *tatr = table[i].atr;
 1296|  12.6k|		const char *matr = table[i].atrmask;
 1297|  12.6k|		size_t tatr_len = strlen(tatr);
 1298|  12.6k|		u8 mbin[SC_MAX_ATR_SIZE], tbin[SC_MAX_ATR_SIZE];
 1299|  12.6k|		size_t mbin_len, tbin_len, s, matr_len;
 1300|  12.6k|		size_t fix_hex_len = card_atr_hex_len;
 1301|  12.6k|		size_t fix_bin_len = card_atr_bin_len;
 1302|       |
 1303|  12.6k|		sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ATR try : %s", tatr);
  ------------------
  |  |   70|  12.6k|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1304|       |
 1305|  12.6k|		if (tatr_len != fix_hex_len) {
  ------------------
  |  Branch (1305:7): [True: 12.6k, False: 10]
  ------------------
 1306|  12.6k|			sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ignored - wrong length");
  ------------------
  |  |   70|  12.6k|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1307|  12.6k|			continue;
 1308|  12.6k|		}
 1309|     10|		if (matr != NULL) {
  ------------------
  |  Branch (1309:7): [True: 0, False: 10]
  ------------------
 1310|      0|			sc_debug(ctx, SC_LOG_DEBUG_MATCH, "ATR mask: %s", matr);
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1311|       |
 1312|      0|			matr_len = strlen(matr);
 1313|      0|			if (tatr_len != matr_len)
  ------------------
  |  Branch (1313:8): [True: 0, False: 0]
  ------------------
 1314|      0|				continue;
 1315|      0|			tbin_len = sizeof(tbin);
 1316|      0|			sc_hex_to_bin(tatr, tbin, &tbin_len);
 1317|      0|			mbin_len = sizeof(mbin);
 1318|      0|			sc_hex_to_bin(matr, mbin, &mbin_len);
 1319|      0|			if (mbin_len != fix_bin_len) {
  ------------------
  |  Branch (1319:8): [True: 0, False: 0]
  ------------------
 1320|      0|				sc_debug(ctx, SC_LOG_DEBUG_MATCH, "length of atr and atr mask do not match - ignored: %s - %s", tatr, matr);
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1321|      0|				continue;
 1322|      0|			}
 1323|      0|			for (s = 0; s < tbin_len; s++) {
  ------------------
  |  Branch (1323:16): [True: 0, False: 0]
  ------------------
 1324|       |				/* reduce tatr with mask */
 1325|      0|				tbin[s] = (tbin[s] & mbin[s]);
 1326|       |				/* create copy of card_atr_bin masked) */
 1327|      0|				mbin[s] = (card_atr_bin[s] & mbin[s]);
 1328|      0|			}
 1329|      0|			if (memcmp(tbin, mbin, tbin_len) != 0)
  ------------------
  |  Branch (1329:8): [True: 0, False: 0]
  ------------------
 1330|      0|				continue;
 1331|     10|		} else {
 1332|     10|			if (strncasecmp(tatr, card_atr_hex, tatr_len) != 0)
  ------------------
  |  Branch (1332:8): [True: 10, False: 0]
  ------------------
 1333|     10|				continue;
 1334|     10|		}
 1335|      0|		return i;
 1336|     10|	}
 1337|  1.68k|	return -1;
 1338|  1.68k|}

_sc_delete_reader:
   86|     51|{
   87|     51|	if (reader == NULL) {
  ------------------
  |  Branch (87:6): [True: 0, False: 51]
  ------------------
   88|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
   89|      0|	}
   90|     51|	if (reader->ops->release)
  ------------------
  |  Branch (90:6): [True: 51, False: 0]
  ------------------
   91|     51|			reader->ops->release(reader);
   92|     51|	free(reader->name);
   93|     51|	free(reader->vendor);
   94|     51|	list_delete(&ctx->readers, reader);
   95|     51|	free(reader);
   96|     51|	return SC_SUCCESS;
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
   97|     51|}
sc_ctx_detect_readers:
  781|    295|{
  782|    295|	int r = 0;
  783|    295|	const struct sc_reader_driver *drv = ctx->reader_driver;
  784|       |
  785|    295|	sc_mutex_lock(ctx, ctx->mutex);
  786|       |
  787|    295|	if (drv->ops->detect_readers != NULL)
  ------------------
  |  Branch (787:6): [True: 0, False: 295]
  ------------------
  788|      0|		r = drv->ops->detect_readers(ctx);
  789|       |
  790|    295|	sc_mutex_unlock(ctx, ctx->mutex);
  791|       |
  792|    295|	return r;
  793|    295|}
sc_ctx_get_reader:
  796|     51|{
  797|     51|	return list_get_at(&ctx->readers, i);
  798|     51|}
sc_context_create:
  945|    295|{
  946|    295|	sc_context_t		*ctx;
  947|    295|	struct _sc_ctx_options	opts;
  948|    295|	int			r;
  949|    295|	char			*driver;
  950|       |
  951|    295|	if (ctx_out == NULL || parm == NULL)
  ------------------
  |  Branch (951:6): [True: 0, False: 295]
  |  Branch (951:25): [True: 0, False: 295]
  ------------------
  952|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  953|       |
  954|    295|	ctx = calloc(1, sizeof(sc_context_t));
  955|    295|	if (ctx == NULL)
  ------------------
  |  Branch (955:6): [True: 0, False: 295]
  ------------------
  956|      0|		return SC_ERROR_OUT_OF_MEMORY;
  ------------------
  |  |   85|      0|#define SC_ERROR_OUT_OF_MEMORY			-1404
  ------------------
  957|    295|	memset(&opts, 0, sizeof(opts));
  958|       |
  959|       |	/* set the application name if set in the parameter options */
  960|    295|	if (parm->app_name != NULL)
  ------------------
  |  Branch (960:6): [True: 295, False: 0]
  ------------------
  961|    295|		ctx->app_name = strdup(parm->app_name);
  962|      0|	else
  963|      0|		ctx->app_name = strdup("default");
  964|    295|	if (ctx->app_name == NULL) {
  ------------------
  |  Branch (964:6): [True: 0, False: 295]
  ------------------
  965|      0|		sc_release_context(ctx);
  966|      0|		return SC_ERROR_OUT_OF_MEMORY;
  ------------------
  |  |   85|      0|#define SC_ERROR_OUT_OF_MEMORY			-1404
  ------------------
  967|      0|	}
  968|       |
  969|    295|	ctx->exe_path = get_exe_path();
  970|    295|	if (ctx->exe_path == NULL) {
  ------------------
  |  Branch (970:6): [True: 0, False: 295]
  ------------------
  971|      0|		sc_release_context(ctx);
  972|      0|		return SC_ERROR_OUT_OF_MEMORY;
  ------------------
  |  |   85|      0|#define SC_ERROR_OUT_OF_MEMORY			-1404
  ------------------
  973|      0|	}
  974|       |
  975|    295|	ctx->flags = parm->flags;
  976|    295|	set_defaults(ctx, &opts);
  977|       |
  978|    295|	if (0 != list_init(&ctx->readers)) {
  ------------------
  |  Branch (978:6): [True: 0, False: 295]
  ------------------
  979|      0|		del_drvs(&opts);
  980|      0|		sc_release_context(ctx);
  981|      0|		return SC_ERROR_OUT_OF_MEMORY;
  ------------------
  |  |   85|      0|#define SC_ERROR_OUT_OF_MEMORY			-1404
  ------------------
  982|      0|	}
  983|    295|	list_attributes_seeker(&ctx->readers, reader_list_seeker);
  984|       |	/* set thread context and create mutex object (if specified) */
  985|    295|	if (parm->thread_ctx != NULL)
  ------------------
  |  Branch (985:6): [True: 0, False: 295]
  ------------------
  986|      0|		ctx->thread_ctx = parm->thread_ctx;
  987|    295|	r = sc_mutex_create(ctx, &ctx->mutex);
  988|    295|	if (r != SC_SUCCESS) {
  ------------------
  |  |   28|    295|#define SC_SUCCESS				0
  ------------------
  |  Branch (988:6): [True: 0, False: 295]
  ------------------
  989|      0|		del_drvs(&opts);
  990|      0|		sc_release_context(ctx);
  991|      0|		return r;
  992|      0|	}
  993|       |
  994|       |#if defined(ENABLE_OPENSSL) && defined(OPENSSL_SECURE_MALLOC_SIZE) && !defined(LIBRESSL_VERSION_NUMBER)
  995|       |	if (!CRYPTO_secure_malloc_initialized()) {
  996|       |		CRYPTO_secure_malloc_init(OPENSSL_SECURE_MALLOC_SIZE, OPENSSL_SECURE_MALLOC_SIZE/8);
  997|       |	}
  998|       |#endif
  999|       |
 1000|    295|	process_config_file(ctx, &opts);
 1001|       |
 1002|       |	/* overwrite with caller's parameters if explicitly given */
 1003|    295|	if (parm->debug) {
  ------------------
  |  Branch (1003:6): [True: 295, False: 0]
  ------------------
 1004|    295|		ctx->debug = parm->debug;
 1005|    295|	}
 1006|    295|	if (parm->debug_file) {
  ------------------
  |  Branch (1006:6): [True: 295, False: 0]
  ------------------
 1007|    295|		if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout))
  ------------------
  |  Branch (1007:7): [True: 295, False: 0]
  |  Branch (1007:27): [True: 0, False: 295]
  |  Branch (1007:56): [True: 0, False: 0]
  ------------------
 1008|      0|			fclose(ctx->debug_file);
 1009|    295|		ctx->debug_file = parm->debug_file;
 1010|    295|	}
 1011|       |
 1012|    295|	sc_log(ctx, "==================================="); /* first thing in the log */
  ------------------
  |  |   71|    295|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1013|    295|	sc_log(ctx, "OpenSC version: %s", sc_get_version());
  ------------------
  |  |   71|    295|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1014|    295|	sc_log(ctx, "Configured for %s (%s)", ctx->app_name, ctx->exe_path);
  ------------------
  |  |   71|    295|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1015|       |
 1016|       |#ifdef USE_OPENSSL3_LIBCTX
 1017|       |	r = sc_openssl3_init(ctx);
 1018|       |	if (r != SC_SUCCESS) {
 1019|       |		del_drvs(&opts);
 1020|       |		sc_release_context(ctx);
 1021|       |		return r;
 1022|       |	}
 1023|       |#endif
 1024|       |
 1025|       |#ifdef ENABLE_PCSC
 1026|       |	ctx->reader_driver = sc_get_pcsc_driver();
 1027|       |#elif defined(ENABLE_CRYPTOTOKENKIT)
 1028|       |	ctx->reader_driver = sc_get_cryptotokenkit_driver();
 1029|       |#elif defined(ENABLE_CTAPI)
 1030|       |	ctx->reader_driver = sc_get_ctapi_driver();
 1031|       |#elif defined(ENABLE_OPENCT)
 1032|       |	ctx->reader_driver = sc_get_openct_driver();
 1033|       |#else
 1034|       |	ctx->reader_driver = sc_get_empty_driver();
 1035|       |#endif
 1036|       |
 1037|    295|	r = ctx->reader_driver->ops->init(ctx);
 1038|    295|	if (r != SC_SUCCESS)   {
  ------------------
  |  |   28|    295|#define SC_SUCCESS				0
  ------------------
  |  Branch (1038:6): [True: 0, False: 295]
  ------------------
 1039|      0|		del_drvs(&opts);
 1040|      0|		sc_release_context(ctx);
 1041|      0|		return r;
 1042|      0|	}
 1043|       |
 1044|    295|	driver = getenv("OPENSC_DRIVER");
 1045|    295|	if (driver) {
  ------------------
  |  Branch (1045:6): [True: 0, False: 295]
  ------------------
 1046|      0|		scconf_list *list = NULL;
 1047|      0|		scconf_list_add(&list, driver);
 1048|      0|		set_drivers(&opts, list);
 1049|      0|		scconf_list_destroy(list);
 1050|      0|	}
 1051|       |
 1052|    295|	load_card_drivers(ctx, &opts);
 1053|    295|	load_card_atrs(ctx);
 1054|       |
 1055|    295|	del_drvs(&opts);
 1056|    295|	sc_ctx_detect_readers(ctx);
 1057|    295|	*ctx_out = ctx;
 1058|       |
 1059|    295|	return SC_SUCCESS;
  ------------------
  |  |   28|    295|#define SC_SUCCESS				0
  ------------------
 1060|    295|}
sc_release_context:
 1093|    295|{
 1094|    295|	unsigned int i;
 1095|       |
 1096|    295|	if (ctx == NULL) {
  ------------------
  |  Branch (1096:6): [True: 0, False: 295]
  ------------------
 1097|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
 1098|      0|	}
 1099|    295|	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|    295|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|    295|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|    295|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 295]
  |  |  ------------------
  ------------------
 1100|    346|	while (list_size(&ctx->readers)) {
  ------------------
  |  Branch (1100:9): [True: 51, False: 295]
  ------------------
 1101|     51|		sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0);
 1102|     51|		_sc_delete_reader(ctx, rdr);
 1103|     51|	}
 1104|       |
 1105|    295|	if (ctx->reader_driver != NULL && ctx->reader_driver->ops->finish != NULL)
  ------------------
  |  Branch (1105:6): [True: 295, False: 0]
  |  Branch (1105:36): [True: 244, False: 51]
  ------------------
 1106|    244|		ctx->reader_driver->ops->finish(ctx);
 1107|       |
 1108|  13.2k|	for (i = 0; ctx->card_drivers[i]; i++) {
  ------------------
  |  Branch (1108:14): [True: 12.9k, False: 295]
  ------------------
 1109|  12.9k|		struct sc_card_driver *drv = ctx->card_drivers[i];
 1110|       |
 1111|  12.9k|		if (drv->atr_map)
  ------------------
  |  Branch (1111:7): [True: 0, False: 12.9k]
  ------------------
 1112|      0|			_sc_free_atr(ctx, drv);
 1113|  12.9k|		if (drv->dll)
  ------------------
  |  Branch (1113:7): [True: 0, False: 12.9k]
  ------------------
 1114|      0|			sc_dlclose(drv->dll);
 1115|  12.9k|	}
 1116|       |#ifdef USE_OPENSSL3_LIBCTX
 1117|       |	sc_openssl3_deinit(ctx);
 1118|       |#endif
 1119|    295|	if (ctx->preferred_language != NULL)
  ------------------
  |  Branch (1119:6): [True: 0, False: 295]
  ------------------
 1120|      0|		free(ctx->preferred_language);
 1121|    295|	if (ctx->mutex != NULL) {
  ------------------
  |  Branch (1121:6): [True: 0, False: 295]
  ------------------
 1122|      0|		int r = sc_mutex_destroy(ctx, ctx->mutex);
 1123|      0|		if (r != SC_SUCCESS) {
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (1123:7): [True: 0, False: 0]
  ------------------
 1124|      0|			sc_log(ctx, "unable to destroy mutex");
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
 1125|      0|			return r;
 1126|      0|		}
 1127|      0|	}
 1128|    295|	if (ctx->conf != NULL)
  ------------------
  |  Branch (1128:6): [True: 295, False: 0]
  ------------------
 1129|    295|		scconf_free(ctx->conf);
 1130|    295|	if (ctx->debug_file && (ctx->debug_file != stdout && ctx->debug_file != stderr))
  ------------------
  |  Branch (1130:6): [True: 295, False: 0]
  |  Branch (1130:26): [True: 0, False: 295]
  |  Branch (1130:55): [True: 0, False: 0]
  ------------------
 1131|      0|		fclose(ctx->debug_file);
 1132|    295|	free(ctx->debug_filename);
 1133|    295|	free(ctx->app_name);
 1134|    295|	free(ctx->exe_path);
 1135|    295|	list_destroy(&ctx->readers);
 1136|    295|	sc_mem_clear(ctx, sizeof(*ctx));
 1137|    295|	free(ctx);
 1138|    295|	return SC_SUCCESS;
  ------------------
  |  |   28|    295|#define SC_SUCCESS				0
  ------------------
 1139|    295|}
sc_get_cache_dir:
 1166|    244|{
 1167|    244|	char *homedir;
 1168|    244|	const char *cache_dir;
 1169|    244|        scconf_block *conf_block = NULL;
 1170|       |#ifdef _WIN32
 1171|       |	char temp_path[PATH_MAX];
 1172|       |#endif
 1173|    244|	conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);
 1174|    244|	cache_dir = scconf_get_str(conf_block, "file_cache_dir", NULL);
 1175|    244|	if (cache_dir != NULL) {
  ------------------
  |  Branch (1175:6): [True: 0, False: 244]
  ------------------
 1176|      0|		strlcpy(buf, cache_dir, bufsize);
  ------------------
  |  |   43|      0|#define strlcpy _strlcpy
  ------------------
 1177|      0|		return SC_SUCCESS;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
 1178|      0|	}
 1179|       |
 1180|    244|#ifndef _WIN32
 1181|       |#ifdef __APPLE__
 1182|       |	cache_dir = getenv("Caches");
 1183|       |#else
 1184|    244|	cache_dir = getenv("XDG_CACHE_HOME");
 1185|    244|#endif
 1186|    244|	if (cache_dir != NULL && cache_dir[0] != '\0') {
  ------------------
  |  Branch (1186:6): [True: 0, False: 244]
  |  Branch (1186:27): [True: 0, False: 0]
  ------------------
 1187|      0|		snprintf(buf, bufsize, "%s/%s", cache_dir, "opensc");
 1188|      0|		return SC_SUCCESS;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
 1189|      0|	}
 1190|    244|	cache_dir = ".cache/opensc";
 1191|    244|	homedir = getenv("HOME");
 1192|       |#else
 1193|       |	cache_dir = "eid-cache";
 1194|       |	homedir = getenv("USERPROFILE");
 1195|       |	/* If USERPROFILE isn't defined, assume it's a single-user OS
 1196|       |	 * and put the cache dir in the Windows dir (usually C:\\WINDOWS) */
 1197|       |	if (homedir == NULL || homedir[0] == '\0') {
 1198|       |		GetWindowsDirectoryA(temp_path, sizeof(temp_path));
 1199|       |		homedir = temp_path;
 1200|       |	}
 1201|       |#endif
 1202|    244|	if (homedir == NULL || homedir[0] == '\0')
  ------------------
  |  Branch (1202:6): [True: 0, False: 244]
  |  Branch (1202:25): [True: 0, False: 244]
  ------------------
 1203|      0|		return SC_ERROR_INTERNAL;
  ------------------
  |  |   81|      0|#define SC_ERROR_INTERNAL			-1400
  ------------------
 1204|    244|	if (snprintf(buf, bufsize, "%s/%s", homedir, cache_dir) < 0)
  ------------------
  |  Branch (1204:6): [True: 0, False: 244]
  ------------------
 1205|      0|		return SC_ERROR_BUFFER_TOO_SMALL;
  ------------------
  |  |   76|      0|#define SC_ERROR_BUFFER_TOO_SMALL		-1303
  ------------------
 1206|    244|	return SC_SUCCESS;
  ------------------
  |  |   28|    244|#define SC_SUCCESS				0
  ------------------
 1207|    244|}
ctx.c:load_card_atrs:
  629|    295|{
  630|    295|	struct sc_card_driver *driver;
  631|    295|	scconf_block **blocks;
  632|    295|	int i, j, k;
  633|       |
  634|    590|	for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
  ------------------
  |  Branch (634:14): [True: 295, False: 295]
  ------------------
  635|    295|		blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], "card_atr", NULL);
  636|    295|		if (!blocks)
  ------------------
  |  Branch (636:7): [True: 0, False: 295]
  ------------------
  637|      0|			continue;
  638|    295|		for (j = 0; blocks[j] != NULL; j++) {
  ------------------
  |  Branch (638:15): [True: 0, False: 295]
  ------------------
  639|      0|			scconf_block *b = blocks[j];
  640|      0|			char *atr = b->name->data;
  641|      0|			const scconf_list *list;
  642|      0|			struct sc_atr_table t;
  643|      0|			const char *dname;
  644|       |
  645|      0|			driver = NULL;
  646|       |
  647|      0|			if (strlen(atr) < 4)
  ------------------
  |  Branch (647:8): [True: 0, False: 0]
  ------------------
  648|      0|				continue;
  649|       |
  650|       |			/* The interesting part. If there's no card
  651|       |			 * driver assigned for the ATR, add it to
  652|       |			 * the default driver. This will reduce the
  653|       |			 * amount of code required to process things
  654|       |			 * related to card_atr blocks in situations,
  655|       |			 * where the code is not exactly related to
  656|       |			 * card driver settings, but for example
  657|       |			 * forcing a protocol at the reader driver.
  658|       |			 */
  659|      0|			dname = scconf_get_str(b, "driver", "default");
  660|       |
  661|       |			/* Find the card driver structure according to dname */
  662|      0|			for (k = 0; ctx->card_drivers[k] != NULL; k++) {
  ------------------
  |  Branch (662:16): [True: 0, False: 0]
  ------------------
  663|      0|				driver = ctx->card_drivers[k];
  664|      0|				if (!strcmp(dname, driver->short_name))
  ------------------
  |  Branch (664:9): [True: 0, False: 0]
  ------------------
  665|      0|					break;
  666|      0|				driver = NULL;
  667|      0|			}
  668|       |
  669|      0|			if (!driver)
  ------------------
  |  Branch (669:8): [True: 0, False: 0]
  ------------------
  670|      0|				continue;
  671|       |
  672|      0|			memset(&t, 0, sizeof(struct sc_atr_table));
  673|      0|			t.atr = atr;
  674|      0|			t.atrmask = (char *) scconf_get_str(b, "atrmask", NULL);
  675|      0|			t.name = (char *) scconf_get_str(b, "name", NULL);
  676|      0|			t.type = scconf_get_int(b, "type", SC_CARD_TYPE_UNKNOWN);
  677|      0|			list = scconf_find_list(b, "flags");
  678|      0|			while (list != NULL) {
  ------------------
  |  Branch (678:11): [True: 0, False: 0]
  ------------------
  679|      0|				unsigned int flags = 0;
  680|       |
  681|      0|				if (!list->data) {
  ------------------
  |  Branch (681:9): [True: 0, False: 0]
  ------------------
  682|      0|					list = list->next;
  683|      0|					continue;
  684|      0|				}
  685|       |
  686|      0|				if (!strcmp(list->data, "rng"))
  ------------------
  |  Branch (686:9): [True: 0, False: 0]
  ------------------
  687|      0|					flags = SC_CARD_FLAG_RNG;
  ------------------
  |  |  543|      0|#define SC_CARD_FLAG_RNG		0x00000002
  ------------------
  688|      0|				else if (!strcmp(list->data, "keep_alive"))
  ------------------
  |  Branch (688:14): [True: 0, False: 0]
  ------------------
  689|      0|					flags = SC_CARD_FLAG_KEEP_ALIVE;
  ------------------
  |  |  544|      0|#define SC_CARD_FLAG_KEEP_ALIVE	0x00000004
  ------------------
  690|      0|				else if (sscanf(list->data, "%x", &flags) != 1)
  ------------------
  |  Branch (690:14): [True: 0, False: 0]
  ------------------
  691|      0|					flags = 0;
  692|       |
  693|      0|				t.flags |= flags;
  694|      0|				list = list->next;
  695|      0|			}
  696|      0|			t.card_atr = b;
  697|      0|			_sc_add_atr(ctx, driver, &t);
  698|      0|		}
  699|    295|		free(blocks);
  700|    295|	}
  701|    295|	return SC_SUCCESS;
  ------------------
  |  |   28|    295|#define SC_SUCCESS				0
  ------------------
  702|    295|}
ctx.c:get_exe_path:
  910|    295|{
  911|       |	/* Find the executable's path which runs this code.
  912|       |	 * See https://github.com/gpakosz/whereami/ for
  913|       |	 * potentially more platforms */
  914|    295|	char exe_path[PATH_MAX] = "unknown executable path";
  915|    295|	int path_found = 0;
  916|       |
  917|       |#if   defined(_WIN32)
  918|       |	if (0 < GetModuleFileNameA(NULL, exe_path, sizeof exe_path))
  919|       |		path_found = 1;
  920|       |#elif defined(__APPLE__)
  921|       |	if (0 < proc_pidpath(getpid(), exe_path, sizeof exe_path))
  922|       |		path_found = 1;
  923|       |#elif defined(__linux__) || defined(__CYGWIN__)
  924|    295|	if (NULL != realpath("/proc/self/exe", exe_path))
  ------------------
  |  Branch (924:6): [True: 295, False: 0]
  ------------------
  925|    295|		path_found = 1;
  926|    295|#endif
  927|       |
  928|       |#if defined(HAVE_GETPROGNAME)
  929|       |	if (!path_found) {
  930|       |		/* getprogname is unreliable and typically only returns the basename.
  931|       |		 * However, this should be enough for our purposes */
  932|       |		const char *prog = getprogname();
  933|       |		if (prog)
  934|       |			strlcpy(exe_path, prog, sizeof exe_path);
  935|       |	}
  936|       |#else
  937|       |	/* avoid warning "set but not used" */
  938|    295|	(void) path_found;
  939|    295|#endif
  940|       |
  941|    295|	return strdup(exe_path);
  942|    295|}
ctx.c:set_defaults:
  321|    295|{
  322|    295|	ctx->debug = 0;
  323|    295|	if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout))
  ------------------
  |  Branch (323:6): [True: 0, False: 295]
  |  Branch (323:26): [True: 0, False: 0]
  |  Branch (323:55): [True: 0, False: 0]
  ------------------
  324|      0|		fclose(ctx->debug_file);
  325|    295|	ctx->debug_file = stderr;
  326|    295|	ctx->flags = 0;
  327|       |	ctx->forced_driver = NULL;
  328|    295|	add_internal_drvs(opts);
  329|    295|}
ctx.c:add_internal_drvs:
  295|    590|{
  296|    590|	const struct _sc_driver_entry *lst;
  297|    590|	int i;
  298|       |
  299|    590|	lst = internal_card_drivers;
  300|    590|	i = 0;
  301|  23.6k|	while (lst[i].name != NULL) {
  ------------------
  |  Branch (301:9): [True: 23.0k, False: 590]
  ------------------
  302|  23.0k|		add_drv(opts, lst[i].name);
  303|  23.0k|		i++;
  304|  23.0k|	}
  305|    590|}
ctx.c:add_drv:
  277|  24.4k|{
  278|  24.4k|	struct _sc_driver_entry *lst;
  279|  24.4k|	int *cp, max, i;
  280|       |
  281|  24.4k|	lst = opts->cdrv;
  282|  24.4k|	cp = &opts->ccount;
  283|  24.4k|	max = SC_MAX_CARD_DRIVERS;
  ------------------
  |  |   31|  24.4k|#define SC_MAX_CARD_DRIVERS		48
  ------------------
  284|  24.4k|	if (*cp == max) /* No space for more drivers... */
  ------------------
  |  Branch (284:6): [True: 0, False: 24.4k]
  ------------------
  285|      0|		return;
  286|   522k|	for (i = 0; i < *cp; i++)
  ------------------
  |  Branch (286:14): [True: 497k, False: 24.4k]
  ------------------
  287|   497k|		if (strcmp(name, lst[i].name) == 0)
  ------------------
  |  Branch (287:7): [True: 0, False: 497k]
  ------------------
  288|      0|			return;
  289|  24.4k|	lst[*cp].name = strdup(name);
  290|       |
  291|  24.4k|	*cp = *cp + 1;
  292|  24.4k|}
ctx.c:del_drvs:
  263|    590|{
  264|    590|	struct _sc_driver_entry *lst;
  265|    590|	int *cp, i;
  266|       |
  267|    590|	lst = opts->cdrv;
  268|    590|	cp = &opts->ccount;
  269|       |
  270|  25.0k|	for (i = 0; i < *cp; i++) {
  ------------------
  |  Branch (270:14): [True: 24.4k, False: 590]
  ------------------
  271|  24.4k|		free((void *)lst[i].name);
  272|  24.4k|	}
  273|    590|	*cp = 0;
  274|    590|}
ctx.c:process_config_file:
  705|    295|{
  706|    295|	int i, r, count = 0;
  707|    295|	scconf_block **blocks;
  708|    295|	const char *conf_path = NULL;
  709|    295|	const char *debug = NULL;
  710|       |#ifdef _WIN32
  711|       |	char temp_path[PATH_MAX];
  712|       |	size_t temp_len;
  713|       |#endif
  714|       |
  715|       |	/* Takes effect even when no config around */
  716|    295|	debug = getenv("OPENSC_DEBUG");
  717|    295|	if (debug)
  ------------------
  |  Branch (717:6): [True: 0, False: 295]
  ------------------
  718|      0|		ctx->debug = atoi(debug);
  719|       |
  720|    295|	memset(ctx->conf_blocks, 0, sizeof(ctx->conf_blocks));
  721|       |#ifdef _WIN32
  722|       |	temp_len = PATH_MAX-1;
  723|       |	r = sc_ctx_win32_get_config_value("OPENSC_CONF", "ConfigFile", "Software\\" OPENSC_VS_FF_COMPANY_NAME "\\OpenSC" OPENSC_ARCH_SUFFIX,
  724|       |			temp_path, &temp_len);
  725|       |	if (r)   {
  726|       |		sc_log(ctx, "process_config_file doesn't find opensc config file. Please set the registry key.");
  727|       |		return;
  728|       |	}
  729|       |	temp_path[temp_len] = '\0';
  730|       |	conf_path = temp_path;
  731|       |#else
  732|    295|	conf_path = getenv("OPENSC_CONF");
  733|    295|	if (!conf_path)
  ------------------
  |  Branch (733:6): [True: 295, False: 0]
  ------------------
  734|    295|		conf_path = OPENSC_CONF_PATH;
  735|    295|#endif
  736|    295|	ctx->conf = scconf_new(conf_path);
  737|    295|	if (ctx->conf == NULL)
  ------------------
  |  Branch (737:6): [True: 0, False: 295]
  ------------------
  738|      0|		return;
  739|    295|	r = scconf_parse(ctx->conf);
  740|    295|#define OPENSC_CONFIG_STRING "app default { card_drivers = old, internal; }"
  741|    295|#ifdef OPENSC_CONFIG_STRING
  742|       |	/* Parse the string if config file didn't exist */
  743|    295|	if (r < 0)
  ------------------
  |  Branch (743:6): [True: 295, False: 0]
  ------------------
  744|    295|		r = scconf_parse_string(ctx->conf, OPENSC_CONFIG_STRING);
  ------------------
  |  |  740|    295|#define OPENSC_CONFIG_STRING "app default { card_drivers = old, internal; }"
  ------------------
  745|    295|#endif
  746|    295|	if (r < 1) {
  ------------------
  |  Branch (746:6): [True: 0, False: 295]
  ------------------
  747|       |		/* A negative return value means the config file isn't
  748|       |		 * there, which is not an error. Nevertheless log this
  749|       |		 * fact. */
  750|      0|		if (r < 0)
  ------------------
  |  Branch (750:7): [True: 0, False: 0]
  ------------------
  751|      0|			sc_log(ctx, "scconf_parse failed: %s", ctx->conf->errmsg);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  752|      0|		else
  753|      0|			sc_log(ctx, "scconf_parse failed: %s", ctx->conf->errmsg);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  754|      0|		scconf_free(ctx->conf);
  755|      0|		ctx->conf = NULL;
  756|      0|		return;
  757|      0|	}
  758|       |	/* needs to be after the log file is known */
  759|    295|	sc_log(ctx, "Used configuration file '%s'", conf_path);
  ------------------
  |  |   71|    295|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  760|    295|	blocks = scconf_find_blocks(ctx->conf, NULL, "app", ctx->exe_path);
  761|    295|	if (blocks && blocks[0])
  ------------------
  |  Branch (761:6): [True: 295, False: 0]
  |  Branch (761:16): [True: 0, False: 295]
  ------------------
  762|      0|		ctx->conf_blocks[count++] = blocks[0];
  763|    295|	free(blocks);
  764|    295|	blocks = scconf_find_blocks(ctx->conf, NULL, "app", ctx->app_name);
  765|    295|	if (blocks && blocks[0])
  ------------------
  |  Branch (765:6): [True: 295, False: 0]
  |  Branch (765:16): [True: 0, False: 295]
  ------------------
  766|      0|		ctx->conf_blocks[count++] = blocks[0];
  767|    295|	free(blocks);
  768|    295|	if (strcmp(ctx->app_name, "default") != 0) {
  ------------------
  |  Branch (768:6): [True: 295, False: 0]
  ------------------
  769|    295|		blocks = scconf_find_blocks(ctx->conf, NULL, "app", "default");
  770|    295|		if (blocks && blocks[0])
  ------------------
  |  Branch (770:7): [True: 295, False: 0]
  |  Branch (770:17): [True: 295, False: 0]
  ------------------
  771|    295|			ctx->conf_blocks[count] = blocks[0];
  772|    295|		free(blocks);
  773|    295|	}
  774|       |	/* Above we add 3 blocks at most, but conf_blocks has 4 elements,
  775|       |	 * so at least one is NULL */
  776|    590|	for (i = 0; ctx->conf_blocks[i]; i++)
  ------------------
  |  Branch (776:14): [True: 295, False: 295]
  ------------------
  777|    295|		load_parameters(ctx, ctx->conf_blocks[i], opts);
  778|    295|}
ctx.c:load_parameters:
  384|    295|{
  385|    295|	int err = 0;
  386|    295|	const scconf_list *list;
  387|    295|	const char *val;
  388|    295|	int debug;
  389|    295|	const char *disable_hw_pkcs1_padding;
  390|       |#ifdef _WIN32
  391|       |	char expanded_val[PATH_MAX];
  392|       |	DWORD expanded_len;
  393|       |#endif
  394|       |
  395|    295|	debug = scconf_get_int(block, "debug", ctx->debug);
  396|    295|	if (debug > ctx->debug)
  ------------------
  |  Branch (396:6): [True: 0, False: 295]
  ------------------
  397|      0|		ctx->debug = debug;
  398|       |
  399|    295|	val = scconf_get_str(block, "debug_file", NULL);
  400|    295|	if (val)   {
  ------------------
  |  Branch (400:6): [True: 0, False: 295]
  ------------------
  401|       |#ifdef _WIN32
  402|       |		expanded_len = PATH_MAX;
  403|       |		expanded_len = ExpandEnvironmentStringsA(val, expanded_val, expanded_len);
  404|       |		if (0 < expanded_len && expanded_len < sizeof expanded_val)
  405|       |			val = expanded_val;
  406|       |#endif
  407|      0|		sc_ctx_log_to_file(ctx, val);
  408|      0|	}
  409|    295|	else if (ctx->debug)   {
  ------------------
  |  Branch (409:11): [True: 0, False: 295]
  ------------------
  410|      0|		sc_ctx_log_to_file(ctx, NULL);
  411|      0|	}
  412|       |
  413|    295|	if (scconf_get_bool (block, "disable_popups",
  ------------------
  |  Branch (413:6): [True: 0, False: 295]
  ------------------
  414|    295|				ctx->flags & SC_CTX_FLAG_DISABLE_POPUPS))
  ------------------
  |  |  868|    295|#define SC_CTX_FLAG_DISABLE_POPUPS			0x00000010
  ------------------
  415|      0|		ctx->flags |= SC_CTX_FLAG_DISABLE_POPUPS;
  ------------------
  |  |  868|      0|#define SC_CTX_FLAG_DISABLE_POPUPS			0x00000010
  ------------------
  416|       |
  417|    295|	if (scconf_get_bool (block, "disable_colors",
  ------------------
  |  Branch (417:6): [True: 0, False: 295]
  ------------------
  418|    295|				ctx->flags & SC_CTX_FLAG_DISABLE_COLORS))
  ------------------
  |  |  869|    295|#define SC_CTX_FLAG_DISABLE_COLORS			0x00000020
  ------------------
  419|      0|		ctx->flags |= SC_CTX_FLAG_DISABLE_COLORS;
  ------------------
  |  |  869|      0|#define SC_CTX_FLAG_DISABLE_COLORS			0x00000020
  ------------------
  420|       |
  421|    295|	if (scconf_get_bool (block, "enable_default_driver",
  ------------------
  |  Branch (421:6): [True: 0, False: 295]
  ------------------
  422|    295|				ctx->flags & SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER))
  ------------------
  |  |  867|    295|#define SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER	0x00000008
  ------------------
  423|      0|		ctx->flags |= SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER;
  ------------------
  |  |  867|      0|#define SC_CTX_FLAG_ENABLE_DEFAULT_DRIVER	0x00000008
  ------------------
  424|       |
  425|    295|	list = scconf_find_list(block, "card_drivers");
  426|    295|	set_drivers(opts, list);
  427|       |
  428|       |	/* Disable PKCS#1 v1.5 type 2 (for decryption) depadding on card by default */
  429|    295|	disable_hw_pkcs1_padding = "decipher";
  430|    295|	ctx->disable_hw_pkcs1_padding = SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_02;
  ------------------
  |  |  119|    295|#define SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_02	0x00000080 /* PKCS#1 v1.5 padding type 2 */
  ------------------
  431|    295|	disable_hw_pkcs1_padding = scconf_get_str(block, "disable_hw_pkcs1_padding", disable_hw_pkcs1_padding);
  432|    295|	if (0 == strcmp(disable_hw_pkcs1_padding, "no")) {
  ------------------
  |  Branch (432:6): [True: 0, False: 295]
  ------------------
  433|      0|		ctx->disable_hw_pkcs1_padding = 0;
  434|    295|	} else if (0 == strcmp(disable_hw_pkcs1_padding, "sign")) {
  ------------------
  |  Branch (434:13): [True: 0, False: 295]
  ------------------
  435|      0|		ctx->disable_hw_pkcs1_padding = SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01;
  ------------------
  |  |  118|      0|#define SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01	0x00000040 /* PKCS#1 v1.5 padding type 1 */
  ------------------
  436|    295|	} else if (0 == strcmp(disable_hw_pkcs1_padding, "decipher")) {
  ------------------
  |  Branch (436:13): [True: 295, False: 0]
  ------------------
  437|    295|		ctx->disable_hw_pkcs1_padding = SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_02;
  ------------------
  |  |  119|    295|#define SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_02	0x00000080 /* PKCS#1 v1.5 padding type 2 */
  ------------------
  438|    295|	} else if (0 == strcmp(disable_hw_pkcs1_padding, "both")) {
  ------------------
  |  Branch (438:13): [True: 0, False: 0]
  ------------------
  439|      0|		ctx->disable_hw_pkcs1_padding = SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01 | SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_02;
  ------------------
  |  |  118|      0|#define SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01	0x00000040 /* PKCS#1 v1.5 padding type 1 */
  ------------------
              		ctx->disable_hw_pkcs1_padding = SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_01 | SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_02;
  ------------------
  |  |  119|      0|#define SC_ALGORITHM_RSA_PAD_PKCS1_TYPE_02	0x00000080 /* PKCS#1 v1.5 padding type 2 */
  ------------------
  440|      0|	}
  441|       |
  442|       |#ifdef USE_OPENSSL3_LIBCTX
  443|       |	val = scconf_get_str(block, "openssl_config", NULL);
  444|       |	if (val != NULL) {
  445|       |		ctx->openssl_config = strdup(val);
  446|       |	}
  447|       |#endif
  448|       |
  449|    295|	return err;
  450|    295|}
ctx.c:set_drivers:
  367|    295|{
  368|    295|	const char *s_internal = "internal", *s_old = "old";
  369|    295|	if (list != NULL)
  ------------------
  |  Branch (369:6): [True: 295, False: 0]
  ------------------
  370|    295|		del_drvs(opts);
  371|    885|	while (list != NULL) {
  ------------------
  |  Branch (371:9): [True: 590, False: 295]
  ------------------
  372|    590|		if (strcmp(list->data, s_internal) == 0)
  ------------------
  |  Branch (372:7): [True: 295, False: 295]
  ------------------
  373|    295|			add_internal_drvs(opts);
  374|    295|		else if (strcmp(list->data, s_old) == 0)
  ------------------
  |  Branch (374:12): [True: 295, False: 0]
  ------------------
  375|    295|			add_old_drvs(opts);
  376|      0|		else
  377|      0|			add_drv(opts, list->data);
  378|    590|		list = list->next;
  379|    590|	}
  380|    295|}
ctx.c:add_old_drvs:
  308|    295|{
  309|    295|	const struct _sc_driver_entry *lst;
  310|    295|	int i;
  311|       |
  312|    295|	lst = old_card_drivers;
  313|    295|	i = 0;
  314|  1.77k|	while (lst[i].name != NULL) {
  ------------------
  |  Branch (314:9): [True: 1.47k, False: 295]
  ------------------
  315|  1.47k|		add_drv(opts, lst[i].name);
  316|  1.47k|		i++;
  317|  1.47k|	}
  318|    295|}
ctx.c:load_card_drivers:
  563|    295|{
  564|    295|	const struct _sc_driver_entry *ent;
  565|    295|	int drv_count;
  566|    295|	int i;
  567|       |
  568|    295|	for (drv_count = 0; ctx->card_drivers[drv_count] != NULL; drv_count++)
  ------------------
  |  Branch (568:22): [True: 0, False: 295]
  ------------------
  569|      0|		;
  570|       |
  571|  13.2k|	for (i = 0; i < opts->ccount; i++) {
  ------------------
  |  Branch (571:14): [True: 12.9k, False: 295]
  ------------------
  572|  12.9k|		struct sc_card_driver *(*func)(void) = NULL;
  573|  12.9k|		struct sc_card_driver *(**tfunc)(void) = &func;
  574|  12.9k|		void *dll = NULL;
  575|  12.9k|		int  j;
  576|       |
  577|  12.9k|		if (drv_count >= SC_MAX_CARD_DRIVERS - 1)   {
  ------------------
  |  |   31|  12.9k|#define SC_MAX_CARD_DRIVERS		48
  ------------------
  |  Branch (577:7): [True: 0, False: 12.9k]
  ------------------
  578|      0|			sc_log(ctx, "Not more then %i card drivers allowed.", SC_MAX_CARD_DRIVERS);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |               #define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |  578|      0|			sc_log(ctx, "Not more then %i card drivers allowed.", SC_MAX_CARD_DRIVERS);
  |  |  |  |  ------------------
  |  |  |  |  |  |   31|      0|#define SC_MAX_CARD_DRIVERS		48
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  579|      0|			break;
  580|      0|		}
  581|       |
  582|  12.9k|		ent = &opts->cdrv[i];
  583|   289k|		for (j = 0; internal_card_drivers[j].name != NULL; j++) {
  ------------------
  |  Branch (583:15): [True: 287k, False: 1.47k]
  ------------------
  584|   287k|			if (strcmp(ent->name, internal_card_drivers[j].name) == 0) {
  ------------------
  |  Branch (584:8): [True: 11.5k, False: 276k]
  ------------------
  585|  11.5k|				func = (struct sc_card_driver *(*)(void)) internal_card_drivers[j].func;
  586|  11.5k|				break;
  587|  11.5k|			}
  588|   287k|		}
  589|  12.9k|		if (func == NULL) {
  ------------------
  |  Branch (589:7): [True: 1.47k, False: 11.5k]
  ------------------
  590|  4.42k|			for (j = 0; old_card_drivers[j].name != NULL; j++) {
  ------------------
  |  Branch (590:16): [True: 4.42k, False: 0]
  ------------------
  591|  4.42k|				if (strcmp(ent->name, old_card_drivers[j].name) == 0) {
  ------------------
  |  Branch (591:9): [True: 1.47k, False: 2.95k]
  ------------------
  592|  1.47k|					func = (struct sc_card_driver *(*)(void)) old_card_drivers[j].func;
  593|  1.47k|					break;
  594|  1.47k|				}
  595|  4.42k|			}
  596|  1.47k|		}
  597|       |		/* if not initialized assume external module */
  598|  12.9k|		if (func == NULL)
  ------------------
  |  Branch (598:7): [True: 0, False: 12.9k]
  ------------------
  599|      0|			*(void **)(tfunc) = load_dynamic_driver(ctx, &dll, ent->name);
  600|       |		/* if still null, assume driver not found */
  601|  12.9k|		if (func == NULL) {
  ------------------
  |  Branch (601:7): [True: 0, False: 12.9k]
  ------------------
  602|      0|			sc_log(ctx, "Unable to load '%s'.", ent->name);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  603|      0|			if (dll)
  ------------------
  |  Branch (603:8): [True: 0, False: 0]
  ------------------
  604|      0|				sc_dlclose(dll);
  605|      0|			continue;
  606|      0|		}
  607|       |
  608|  12.9k|		ctx->card_drivers[drv_count] = func();
  609|  12.9k|		if (ctx->card_drivers[drv_count] == NULL) {
  ------------------
  |  Branch (609:7): [True: 0, False: 12.9k]
  ------------------
  610|      0|			sc_log(ctx, "Driver '%s' not available.", ent->name);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  611|      0|			continue;
  612|      0|		}
  613|       |
  614|  12.9k|		ctx->card_drivers[drv_count]->dll = dll;
  615|  12.9k|		ctx->card_drivers[drv_count]->atr_map = NULL;
  616|  12.9k|		ctx->card_drivers[drv_count]->natrs = 0;
  617|       |
  618|  12.9k|		load_card_driver_options(ctx, ctx->card_drivers[drv_count]);
  619|       |
  620|       |		/* Ensure that the list is always terminated by NULL */
  621|  12.9k|		ctx->card_drivers[drv_count + 1] = NULL;
  622|       |
  623|  12.9k|		drv_count++;
  624|  12.9k|	}
  625|    295|	return SC_SUCCESS;
  ------------------
  |  |   28|    295|#define SC_SUCCESS				0
  ------------------
  626|    295|}
ctx.c:load_card_driver_options:
  542|  12.9k|{
  543|  12.9k|	scconf_block **blocks, *blk;
  544|  12.9k|	int i;
  545|       |
  546|  25.9k|	for (i = 0; ctx->conf_blocks[i]; i++) {
  ------------------
  |  Branch (546:14): [True: 12.9k, False: 12.9k]
  ------------------
  547|  12.9k|		blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
  548|  12.9k|				"card_driver", driver->short_name);
  549|  12.9k|		if (!blocks)
  ------------------
  |  Branch (549:7): [True: 0, False: 12.9k]
  ------------------
  550|      0|			continue;
  551|  12.9k|		blk = blocks[0];
  552|  12.9k|		free(blocks);
  553|       |
  554|  12.9k|		if (blk == NULL)
  ------------------
  |  Branch (554:7): [True: 12.9k, False: 0]
  ------------------
  555|  12.9k|			continue;
  556|       |
  557|       |		/* no options at the moment */
  558|  12.9k|	}
  559|  12.9k|	return SC_SUCCESS;
  ------------------
  |  |   28|  12.9k|#define SC_SUCCESS				0
  ------------------
  560|  12.9k|}

sc_free_apps:
  269|     51|{
  270|     51|	int	i;
  271|       |
  272|     51|	for (i = 0; i < card->app_count; i++) {
  ------------------
  |  Branch (272:14): [True: 0, False: 51]
  ------------------
  273|      0|		free(card->app[i]->label);
  274|      0|		free(card->app[i]->ddo.value);
  275|      0|		free(card->app[i]);
  276|      0|	}
  277|     51|	card->app_count = -1;
  278|     51|}

sc_free_ef_atr:
  187|     51|{
  188|     51|	if (card->ef_atr)
  ------------------
  |  Branch (188:6): [True: 0, False: 51]
  ------------------
  189|      0|		free(card->ef_atr);
  190|       |	card->ef_atr = NULL;
  191|     51|}

sc_strerror:
   32|  10.0k|{
   33|  10.0k|	unsigned int error_index = 0;
   34|  10.0k|	const char *rdr_errors[] = {
   35|  10.0k|		"Generic reader error",
   36|  10.0k|		"No readers found",
   37|  10.0k|		"UNUSED",
   38|  10.0k|		"UNUSED",
   39|  10.0k|		"Card not present",
   40|  10.0k|		"Card removed",
   41|  10.0k|		"Card reset",
   42|  10.0k|		"Transmit failed",
   43|  10.0k|		"Timed out while waiting for user input",
   44|  10.0k|		"Input operation cancelled by user",
   45|  10.0k|		"The two PINs did not match",
   46|  10.0k|		"Message too long (keypad)",
   47|  10.0k|		"Timeout while waiting for event from card reader",
   48|  10.0k|		"Unresponsive card (correctly inserted?)",
   49|  10.0k|		"Reader detached",
   50|  10.0k|		"Reader reattached",
   51|  10.0k|		"Reader in use by another application"
   52|  10.0k|	};
   53|  10.0k|	const unsigned int rdr_base = -SC_ERROR_READER;
  ------------------
  |  |   31|  10.0k|#define SC_ERROR_READER				-1100
  ------------------
   54|       |
   55|  10.0k|	const char *card_errors[] = {
   56|  10.0k|		"Card command failed",
   57|  10.0k|		"File not found",
   58|  10.0k|		"Record not found",
   59|  10.0k|		"Unsupported CLA byte in APDU",
   60|  10.0k|		"Unsupported INS byte in APDU",
   61|  10.0k|		"Incorrect parameters in APDU",
   62|  10.0k|		"Wrong length",
   63|  10.0k|		"Card memory failure",
   64|  10.0k|		"Card does not support the requested operation",
   65|  10.0k|		"Not allowed",
   66|  10.0k|		"Card is invalid or cannot be handled",
   67|  10.0k|		"Security status not satisfied",
   68|  10.0k|		"Authentication method blocked",
   69|  10.0k|		"Unknown data received from card",
   70|  10.0k|		"PIN code or key incorrect",
   71|  10.0k|		"File already exists",
   72|  10.0k|		"Data object not found",
   73|  10.0k|		"Not enough memory on card",
   74|  10.0k|		"Part of returned data may be corrupted",
   75|  10.0k|		"End of file/record reached before reading Le bytes",
   76|  10.0k|		"Reference data not usable"
   77|  10.0k|	};
   78|  10.0k|	const unsigned int card_base = -SC_ERROR_CARD_CMD_FAILED;
  ------------------
  |  |   50|  10.0k|#define SC_ERROR_CARD_CMD_FAILED		-1200
  ------------------
   79|       |
   80|  10.0k|	const char *arg_errors[] = {
   81|  10.0k|		"Invalid arguments",
   82|  10.0k|		"UNUSED",
   83|  10.0k|		"UNUSED",
   84|  10.0k|		"Buffer too small",
   85|  10.0k|		"Invalid PIN length",
   86|  10.0k|		"Invalid data",
   87|  10.0k|	};
   88|  10.0k|	const unsigned int arg_base = -SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|  10.0k|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
   89|       |
   90|  10.0k|	const char *int_errors[] = {
   91|  10.0k|		"Internal error",
   92|  10.0k|		"Invalid ASN.1 object",
   93|  10.0k|		"Required ASN.1 object not found",
   94|  10.0k|		"Premature end of ASN.1 stream",
   95|  10.0k|		"Out of memory",
   96|  10.0k|		"Too many objects",
   97|  10.0k|		"Object not valid",
   98|  10.0k|		"Requested object not found",
   99|  10.0k|		"Not supported",
  100|  10.0k|		"Passphrase required",
  101|  10.0k|		"Inconsistent configuration",
  102|  10.0k|		"Decryption failed",
  103|  10.0k|		"Wrong padding",
  104|  10.0k|		"Unsupported card",
  105|  10.0k|		"Unable to load external module",
  106|  10.0k|		"EF offset too large",
  107|  10.0k|		"Not implemented",
  108|  10.0k|		"Invalid Simple TLV object",
  109|  10.0k|		"Premature end of Simple TLV stream",
  110|  10.0k|	};
  111|  10.0k|	const unsigned int int_base = -SC_ERROR_INTERNAL;
  ------------------
  |  |   81|  10.0k|#define SC_ERROR_INTERNAL			-1400
  ------------------
  112|       |
  113|  10.0k|	const char *p15i_errors[] = {
  114|  10.0k|		"Generic PKCS#15 initialization error",
  115|  10.0k|		"Syntax error",
  116|  10.0k|		"Inconsistent or incomplete PKCS#15 profile",
  117|  10.0k|		"Key length/algorithm not supported by card",
  118|  10.0k|		"No default (transport) key available",
  119|  10.0k|		"Non unique object ID",
  120|  10.0k|		"Unable to load key and certificate(s) from file",
  121|  10.0k|		"UNUSED",
  122|  10.0k|		"File template not found",
  123|  10.0k|		"Invalid PIN reference",
  124|  10.0k|		"File too small",
  125|  10.0k|	};
  126|  10.0k|	const unsigned int p15i_base = -SC_ERROR_PKCS15INIT;
  ------------------
  |  |  102|  10.0k|#define SC_ERROR_PKCS15INIT			-1500
  ------------------
  127|       |
  128|  10.0k|	const char *sm_errors[] = {
  129|  10.0k|		"Generic Secure Messaging error",
  130|  10.0k|		"Data enciphering error",
  131|  10.0k|		"Invalid secure messaging level",
  132|  10.0k|		"No session keys",
  133|  10.0k|		"Invalid session keys",
  134|  10.0k|		"Secure Messaging not initialized",
  135|  10.0k|		"Cannot authenticate card",
  136|  10.0k|		"Random generation error",
  137|  10.0k|		"Secure messaging keyset not found",
  138|  10.0k|		"IFD data missing",
  139|  10.0k|		"SM not applied",
  140|  10.0k|		"SM session already active",
  141|  10.0k|		"Invalid checksum"
  142|  10.0k|	};
  143|  10.0k|	const unsigned int sm_base = -SC_ERROR_SM;
  ------------------
  |  |  115|  10.0k|#define SC_ERROR_SM				-1600
  ------------------
  144|       |
  145|  10.0k|	const char *misc_errors[] = {
  146|  10.0k|		"Unknown error",
  147|  10.0k|		"PKCS#15 compatible smart card not found",
  148|  10.0k|	};
  149|  10.0k|	const unsigned int misc_base = -SC_ERROR_UNKNOWN;
  ------------------
  |  |  130|  10.0k|#define SC_ERROR_UNKNOWN			-1900
  ------------------
  150|       |
  151|  10.0k|	const char *no_errors = "Success";
  152|  10.0k|	const char **errors = NULL;
  153|  10.0k|	unsigned int count = 0, err_base = 0;
  154|       |
  155|  10.0k|	if (!error)
  ------------------
  |  Branch (155:6): [True: 7.44k, False: 2.65k]
  ------------------
  156|  7.44k|		return no_errors;
  157|  2.65k|	error_index = error < 0 ? (unsigned)(-(long long int)error) : (unsigned)error;
  ------------------
  |  Branch (157:16): [True: 2.65k, False: 0]
  ------------------
  158|       |
  159|  2.65k|	if (error_index >= misc_base) {
  ------------------
  |  Branch (159:6): [True: 0, False: 2.65k]
  ------------------
  160|      0|		errors = misc_errors;
  161|      0|		count = DIM(misc_errors);
  ------------------
  |  |   29|      0|#define DIM(v)		(sizeof(v)/(sizeof((v)[0])))
  ------------------
  162|      0|		err_base = misc_base;
  163|  2.65k|	} else if (error_index >= sm_base) {
  ------------------
  |  Branch (163:13): [True: 0, False: 2.65k]
  ------------------
  164|      0|		errors = sm_errors;
  165|      0|		count = DIM(sm_errors);
  ------------------
  |  |   29|      0|#define DIM(v)		(sizeof(v)/(sizeof((v)[0])))
  ------------------
  166|      0|		err_base = sm_base;
  167|  2.65k|	} else if (error_index >= p15i_base) {
  ------------------
  |  Branch (167:13): [True: 0, False: 2.65k]
  ------------------
  168|      0|		errors = p15i_errors;
  169|      0|		count = DIM(p15i_errors);
  ------------------
  |  |   29|      0|#define DIM(v)		(sizeof(v)/(sizeof((v)[0])))
  ------------------
  170|      0|		err_base = p15i_base;
  171|  2.65k|	} else if (error_index >= int_base) {
  ------------------
  |  Branch (171:13): [True: 0, False: 2.65k]
  ------------------
  172|      0|		errors = int_errors;
  173|      0|		count = DIM(int_errors);
  ------------------
  |  |   29|      0|#define DIM(v)		(sizeof(v)/(sizeof((v)[0])))
  ------------------
  174|      0|		err_base = int_base;
  175|  2.65k|	} else if (error_index >= arg_base) {
  ------------------
  |  Branch (175:13): [True: 0, False: 2.65k]
  ------------------
  176|      0|		errors = arg_errors;
  177|      0|		count = DIM(arg_errors);
  ------------------
  |  |   29|      0|#define DIM(v)		(sizeof(v)/(sizeof((v)[0])))
  ------------------
  178|      0|		err_base = arg_base;
  179|  2.65k|	} else if (error_index >= card_base) {
  ------------------
  |  Branch (179:13): [True: 2.65k, False: 0]
  ------------------
  180|  2.65k|		errors = card_errors;
  181|  2.65k|		count = DIM(card_errors);
  ------------------
  |  |   29|  2.65k|#define DIM(v)		(sizeof(v)/(sizeof((v)[0])))
  ------------------
  182|  2.65k|		err_base = card_base;
  183|  2.65k|	} else if (error_index >= rdr_base) {
  ------------------
  |  Branch (183:13): [True: 0, False: 0]
  ------------------
  184|      0|		errors = rdr_errors;
  185|      0|		count = DIM(rdr_errors);
  ------------------
  |  |   29|      0|#define DIM(v)		(sizeof(v)/(sizeof((v)[0])))
  ------------------
  186|      0|		err_base = rdr_base;
  187|      0|	}
  188|  2.65k|	error_index -= err_base;
  189|  2.65k|	if (error_index >= count)
  ------------------
  |  Branch (189:6): [True: 0, False: 2.65k]
  ------------------
  190|      0|		return misc_errors[0];
  191|  2.65k|	return errors[error_index];
  192|  2.65k|}

iso7816_select_aid:
 1401|    102|{
 1402|    102|	struct sc_context *ctx = card->ctx;
 1403|    102|	struct sc_apdu apdu;
 1404|    102|	int rv;
 1405|       |
 1406|    102|	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_VERBOSE);
  ------------------
  |  |  148|    102|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  149|    102|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  150|    102|} while (0)
  |  |  ------------------
  |  |  |  Branch (150:10): [Folded, False: 102]
  |  |  ------------------
  ------------------
 1407|       |
 1408|    102|	sc_format_apdu(card, &apdu, resp == NULL ? SC_APDU_CASE_3_SHORT : SC_APDU_CASE_4_SHORT, 0xA4, 0x04, resp == NULL ? 0x0C : 0x00);
  ------------------
  |  |  293|     51|#define SC_APDU_CASE_3_SHORT		0x03
  ------------------
              	sc_format_apdu(card, &apdu, resp == NULL ? SC_APDU_CASE_3_SHORT : SC_APDU_CASE_4_SHORT, 0xA4, 0x04, resp == NULL ? 0x0C : 0x00);
  ------------------
  |  |  294|     51|#define SC_APDU_CASE_4_SHORT		0x04
  ------------------
  |  Branch (1408:30): [True: 51, False: 51]
  |  Branch (1408:102): [True: 51, False: 51]
  ------------------
 1409|    102|	apdu.lc = reqlen;
 1410|    102|	apdu.data = req;
 1411|    102|	apdu.datalen = reqlen;
 1412|    102|	apdu.resp = resp;
 1413|    102|	apdu.resplen = resp == NULL ? 0 : *resplen;
  ------------------
  |  Branch (1413:17): [True: 51, False: 51]
  ------------------
 1414|    102|	apdu.le = resp == NULL ? 0 : 256;
  ------------------
  |  Branch (1414:12): [True: 51, False: 51]
  ------------------
 1415|       |
 1416|    102|	rv = sc_transmit_apdu(card, &apdu);
 1417|    102|	if (resplen)
  ------------------
  |  Branch (1417:6): [True: 51, False: 51]
  ------------------
 1418|     51|		*resplen = apdu.resplen;
 1419|    102|	LOG_TEST_RET(card->ctx, rv, "APDU transmit failed");
  ------------------
  |  |  174|    102|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|    102|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|    102|	int _ret = (r); \
  |  |  |  |  168|    102|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 102]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|    102|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 102]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1420|       |
 1421|    102|	rv = sc_check_sw(card, apdu.sw1, apdu.sw2);
 1422|    102|	LOG_FUNC_RETURN(ctx, rv);
  ------------------
  |  |  164|    102|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|    102|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|    102|	int _ret = r; \
  |  |  |  |  155|    102|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 102, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|    102|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|    102|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 102, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|    102|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|    102|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|    102|	return _ret; \
  |  |  |  |  163|    102|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1423|    102|}
sc_get_iso7816_driver:
 1491|  8.96k|{
 1492|  8.96k|	return &iso_driver;
 1493|  8.96k|}
iso7816.c:no_match:
 1437|     51|{
 1438|     51|	return 0;
 1439|     51|}
iso7816.c:iso7816_select_file:
  631|    153|{
  632|    153|	struct sc_context *ctx;
  633|    153|	struct sc_apdu apdu;
  634|    153|	unsigned char buf[SC_MAX_APDU_BUFFER_SIZE];
  635|    153|	unsigned char pathbuf[SC_MAX_PATH_SIZE], *path = pathbuf;
  636|    153|	int r, pathtype;
  637|    153|	size_t pathlen;
  638|    153|	int select_mf = 0;
  639|    153|	struct sc_file *file = NULL;
  640|    153|	const u8 *buffer;
  641|    153|	size_t buffer_len;
  642|    153|	unsigned int cla, tag;
  643|       |
  644|    153|	if (card == NULL || in_path == NULL) {
  ------------------
  |  Branch (644:6): [True: 0, False: 153]
  |  Branch (644:22): [True: 0, False: 153]
  ------------------
  645|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  646|      0|	}
  647|    153|	ctx = card->ctx;
  648|    153|	memcpy(path, in_path->value, in_path->len);
  649|    153|	pathlen = in_path->len;
  650|    153|	pathtype = in_path->type;
  651|       |
  652|    153|	if (in_path->aid.len) {
  ------------------
  |  Branch (652:6): [True: 0, False: 153]
  ------------------
  653|      0|		if (!pathlen) {
  ------------------
  |  Branch (653:7): [True: 0, False: 0]
  ------------------
  654|      0|			memcpy(path, in_path->aid.value, in_path->aid.len);
  655|      0|			pathlen = in_path->aid.len;
  656|      0|			pathtype = SC_PATH_TYPE_DF_NAME;
  ------------------
  |  |  118|      0|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
  657|      0|		} else {
  658|       |			/* First, select the application */
  659|      0|			sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 4, 0);
  ------------------
  |  |  293|      0|#define SC_APDU_CASE_3_SHORT		0x03
  ------------------
  660|      0|			apdu.data = in_path->aid.value;
  661|      0|			apdu.datalen = in_path->aid.len;
  662|      0|			apdu.lc = in_path->aid.len;
  663|       |
  664|      0|			r = sc_transmit_apdu(card, &apdu);
  665|      0|			LOG_TEST_RET(ctx, r, "APDU transmit failed");
  ------------------
  |  |  174|      0|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|      0|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|      0|	int _ret = (r); \
  |  |  |  |  168|      0|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  666|      0|			r = sc_check_sw(card, apdu.sw1, apdu.sw2);
  667|      0|			if (r)
  ------------------
  |  Branch (667:8): [True: 0, False: 0]
  ------------------
  668|      0|				LOG_FUNC_RETURN(ctx, r);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  669|       |
  670|      0|			if (pathtype == SC_PATH_TYPE_PATH
  ------------------
  |  |  119|      0|#define SC_PATH_TYPE_PATH		2
  ------------------
  |  Branch (670:8): [True: 0, False: 0]
  ------------------
  671|      0|					|| pathtype == SC_PATH_TYPE_DF_NAME)
  ------------------
  |  |  118|      0|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
  |  Branch (671:9): [True: 0, False: 0]
  ------------------
  672|      0|				pathtype = SC_PATH_TYPE_FROM_CURRENT;
  ------------------
  |  |  122|      0|#define SC_PATH_TYPE_FROM_CURRENT	4
  ------------------
  673|      0|		}
  674|      0|	}
  675|       |
  676|    153|	sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xA4, 0, 0);
  ------------------
  |  |  294|    153|#define SC_APDU_CASE_4_SHORT		0x04
  ------------------
  677|       |
  678|    153|	switch (pathtype) {
  679|      0|	case SC_PATH_TYPE_FILE_ID:
  ------------------
  |  |  117|      0|#define SC_PATH_TYPE_FILE_ID		0
  ------------------
  |  Branch (679:2): [True: 0, False: 153]
  ------------------
  680|      0|		apdu.p1 = 0;
  681|      0|		if (pathlen != 2)
  ------------------
  |  Branch (681:7): [True: 0, False: 0]
  ------------------
  682|      0|			return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  683|      0|		break;
  684|    102|	case SC_PATH_TYPE_DF_NAME:
  ------------------
  |  |  118|    102|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
  |  Branch (684:2): [True: 102, False: 51]
  ------------------
  685|    102|		apdu.p1 = 4;
  686|    102|		break;
  687|     51|	case SC_PATH_TYPE_PATH:
  ------------------
  |  |  119|     51|#define SC_PATH_TYPE_PATH		2
  ------------------
  |  Branch (687:2): [True: 51, False: 102]
  ------------------
  688|     51|		apdu.p1 = 8;
  689|     51|		if (pathlen >= 2 && memcmp(path, "\x3F\x00", 2) == 0) {
  ------------------
  |  Branch (689:7): [True: 51, False: 0]
  |  Branch (689:23): [True: 51, False: 0]
  ------------------
  690|     51|			if (pathlen == 2) {	/* only 3F00 supplied */
  ------------------
  |  Branch (690:8): [True: 51, False: 0]
  ------------------
  691|     51|				select_mf = 1;
  692|     51|				apdu.p1 = 0;
  693|     51|				break;
  694|     51|			}
  695|      0|			path += 2;
  696|      0|			pathlen -= 2;
  697|      0|		}
  698|      0|		break;
  699|      0|	case SC_PATH_TYPE_FROM_CURRENT:
  ------------------
  |  |  122|      0|#define SC_PATH_TYPE_FROM_CURRENT	4
  ------------------
  |  Branch (699:2): [True: 0, False: 153]
  ------------------
  700|      0|		apdu.p1 = 9;
  701|      0|		break;
  702|      0|	case SC_PATH_TYPE_PARENT:
  ------------------
  |  |  123|      0|#define SC_PATH_TYPE_PARENT		5
  ------------------
  |  Branch (702:2): [True: 0, False: 153]
  ------------------
  703|      0|		apdu.p1 = 3;
  704|      0|		pathlen = 0;
  705|      0|		apdu.cse = SC_APDU_CASE_2_SHORT;
  ------------------
  |  |  292|      0|#define SC_APDU_CASE_2_SHORT		0x02
  ------------------
  706|      0|		break;
  707|      0|	default:
  ------------------
  |  Branch (707:2): [True: 0, False: 153]
  ------------------
  708|      0|		LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  709|    153|	}
  710|    153|	apdu.lc = pathlen;
  711|    153|	apdu.data = path;
  712|    153|	apdu.datalen = pathlen;
  713|       |
  714|    153|	if (file_out != NULL) {
  ------------------
  |  Branch (714:6): [True: 102, False: 51]
  ------------------
  715|    102|		apdu.p2 = 0;		/* first record, return FCI */
  716|    102|		apdu.resp = buf;
  717|    102|		apdu.resplen = sizeof(buf);
  718|    102|		apdu.le = sc_get_max_recv_size(card) < 256 ? sc_get_max_recv_size(card) : 256;
  ------------------
  |  Branch (718:13): [True: 0, False: 102]
  ------------------
  719|    102|	}
  720|     51|	else {
  721|     51|		apdu.p2 = 0x0C;		/* first record, return nothing */
  722|     51|		apdu.cse = (apdu.lc == 0) ? SC_APDU_CASE_1 : SC_APDU_CASE_3_SHORT;
  ------------------
  |  |  291|      0|#define SC_APDU_CASE_1			0x01
  ------------------
              		apdu.cse = (apdu.lc == 0) ? SC_APDU_CASE_1 : SC_APDU_CASE_3_SHORT;
  ------------------
  |  |  293|    102|#define SC_APDU_CASE_3_SHORT		0x03
  ------------------
  |  Branch (722:14): [True: 0, False: 51]
  ------------------
  723|     51|	}
  724|       |
  725|    153|	r = sc_transmit_apdu(card, &apdu);
  726|    153|	LOG_TEST_RET(ctx, r, "APDU transmit failed");
  ------------------
  |  |  174|    153|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|    153|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|    153|	int _ret = (r); \
  |  |  |  |  168|    153|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 153]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|    153|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 153]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  727|    153|	if (file_out == NULL) {
  ------------------
  |  Branch (727:6): [True: 51, False: 102]
  ------------------
  728|       |		/* For some cards 'SELECT' can be only with request to return FCI/FCP. */
  729|     51|		r = sc_check_sw(card, apdu.sw1, apdu.sw2);
  730|     51|		if (apdu.sw1 == 0x6A && apdu.sw2 == 0x86)   {
  ------------------
  |  Branch (730:7): [True: 0, False: 51]
  |  Branch (730:27): [True: 0, False: 0]
  ------------------
  731|      0|			apdu.p2 = 0x00;
  732|      0|			if (sc_transmit_apdu(card, &apdu) == SC_SUCCESS)
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (732:8): [True: 0, False: 0]
  ------------------
  733|      0|				r = sc_check_sw(card, apdu.sw1, apdu.sw2);
  734|      0|		}
  735|     51|		if (apdu.sw1 == 0x61)
  ------------------
  |  Branch (735:7): [True: 0, False: 51]
  ------------------
  736|     51|			LOG_FUNC_RETURN(ctx, SC_SUCCESS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  737|     51|		LOG_FUNC_RETURN(ctx, r);
  ------------------
  |  |  164|     51|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|     51|	int _ret = r; \
  |  |  |  |  155|     51|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|     51|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 51, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|     51|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|     51|	return _ret; \
  |  |  |  |  163|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  738|     51|	}
  739|       |
  740|    102|	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
  741|    102|	if (r)
  ------------------
  |  Branch (741:6): [True: 102, False: 0]
  ------------------
  742|    102|		LOG_FUNC_RETURN(ctx, r);
  ------------------
  |  |  164|    102|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|    102|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|    102|	int _ret = r; \
  |  |  |  |  155|    102|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 102, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|    102|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|    102|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 102, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|    102|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|    102|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|    102|	return _ret; \
  |  |  |  |  163|    102|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  743|       |
  744|      0|	if (file_out && (apdu.resplen == 0))   {
  ------------------
  |  Branch (744:6): [True: 0, False: 0]
  |  Branch (744:18): [True: 0, False: 0]
  ------------------
  745|       |		/* For some cards 'SELECT' MF or DF_NAME do not return FCI. */
  746|      0|		if (select_mf || pathtype == SC_PATH_TYPE_DF_NAME)   {
  ------------------
  |  |  118|      0|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
  |  Branch (746:7): [True: 0, False: 0]
  |  Branch (746:20): [True: 0, False: 0]
  ------------------
  747|      0|			file = sc_file_new();
  748|      0|			if (file == NULL)
  ------------------
  |  Branch (748:8): [True: 0, False: 0]
  ------------------
  749|      0|				LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  750|      0|			file->path = *in_path;
  751|       |
  752|      0|			*file_out = file;
  753|      0|			LOG_FUNC_RETURN(ctx, SC_SUCCESS);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  754|      0|		}
  755|      0|	}
  756|       |
  757|      0|	if (apdu.resplen < 2)
  ------------------
  |  Branch (757:6): [True: 0, False: 0]
  ------------------
  758|      0|		LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  759|      0|	switch (apdu.resp[0]) {
  760|      0|	case ISO7816_TAG_FCI:
  ------------------
  |  |   15|      0|#define ISO7816_TAG_FCI			0x6F
  ------------------
  |  Branch (760:2): [True: 0, False: 0]
  ------------------
  761|      0|	case ISO7816_TAG_FCP:
  ------------------
  |  |   17|      0|#define ISO7816_TAG_FCP			0x62
  ------------------
  |  Branch (761:2): [True: 0, False: 0]
  ------------------
  762|      0|		file = sc_file_new();
  763|      0|		if (file == NULL)
  ------------------
  |  Branch (763:7): [True: 0, False: 0]
  ------------------
  764|      0|			LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  765|      0|		file->path = *in_path;
  766|      0|		if (card->ops->process_fci == NULL) {
  ------------------
  |  Branch (766:7): [True: 0, False: 0]
  ------------------
  767|      0|			sc_file_free(file);
  768|      0|			LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  769|      0|		}
  770|      0|		buffer = apdu.resp;
  771|      0|		r = sc_asn1_read_tag(&buffer, apdu.resplen, &cla, &tag, &buffer_len);
  772|      0|		if (r == SC_SUCCESS)
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  |  Branch (772:7): [True: 0, False: 0]
  ------------------
  773|      0|			card->ops->process_fci(card, file, buffer, buffer_len);
  774|      0|		*file_out = file;
  775|      0|		break;
  776|      0|	case 0x00: /* proprietary coding */
  ------------------
  |  Branch (776:2): [True: 0, False: 0]
  ------------------
  777|      0|		LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  778|      0|	default:
  ------------------
  |  Branch (778:2): [True: 0, False: 0]
  ------------------
  779|      0|		LOG_FUNC_RETURN(ctx, SC_ERROR_UNKNOWN_DATA_RECEIVED);
  ------------------
  |  |  164|      0|#define LOG_FUNC_RETURN(ctx, r) SC_FUNC_RETURN((ctx), SC_LOG_DEBUG_NORMAL, (r))
  |  |  ------------------
  |  |  |  |  153|      0|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  |  |  154|      0|	int _ret = r; \
  |  |  |  |  155|      0|	if (_ret <= 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (155:6): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  156|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (156:65): [True: 0, False: 0]
  |  |  |  |  ------------------
  |  |  |  |  157|      0|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  |  |  158|      0|	} else { \
  |  |  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  |  |  161|      0|	} \
  |  |  |  |  162|      0|	return _ret; \
  |  |  |  |  163|      0|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  780|      0|	}
  781|       |
  782|      0|	return SC_SUCCESS;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  783|      0|}
iso7816.c:iso7816_check_sw:
  111|  2.14k|{
  112|  2.14k|	const int err_count = sizeof(iso7816_errors)/sizeof(iso7816_errors[0]);
  113|  2.14k|	int i;
  114|       |
  115|       |	/* Handle special cases here */
  116|  2.14k|	if (sw1 == 0x6C) {
  ------------------
  |  Branch (116:6): [True: 0, False: 2.14k]
  ------------------
  117|      0|		sc_log(card->ctx, "Wrong length; correct length is %d", sw2);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  118|      0|		return SC_ERROR_WRONG_LENGTH;
  ------------------
  |  |   56|      0|#define SC_ERROR_WRONG_LENGTH			-1206
  ------------------
  119|      0|	}
  120|  2.14k|	if (sw1 == 0x90 && sw2 == 0x00)
  ------------------
  |  Branch (120:6): [True: 0, False: 2.14k]
  |  Branch (120:21): [True: 0, False: 0]
  ------------------
  121|      0|		return SC_SUCCESS;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  122|  2.14k|	if (sw1 == 0x63U && (sw2 & ~0x0fU) == 0xc0U) {
  ------------------
  |  Branch (122:6): [True: 0, False: 2.14k]
  |  Branch (122:22): [True: 0, False: 0]
  ------------------
  123|      0|		sc_log(card->ctx, "PIN not verified (remaining tries: %d)", (sw2 & 0x0f));
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  124|      0|		return SC_ERROR_PIN_CODE_INCORRECT;
  ------------------
  |  |   64|      0|#define SC_ERROR_PIN_CODE_INCORRECT		-1214
  ------------------
  125|      0|	}
  126|  87.8k|	for (i = 0; i < err_count; i++)   {
  ------------------
  |  Branch (126:14): [True: 87.8k, False: 0]
  ------------------
  127|  87.8k|		if (iso7816_errors[i].SWs == ((sw1 << 8) | sw2)) {
  ------------------
  |  Branch (127:7): [True: 2.14k, False: 85.6k]
  ------------------
  128|  2.14k|			sc_log(card->ctx, "%s", iso7816_errors[i].errorstr);
  ------------------
  |  |   71|  2.14k|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  129|  2.14k|			return iso7816_errors[i].errorno;
  130|  2.14k|		}
  131|  87.8k|	}
  132|       |
  133|      0|	sc_log(card->ctx, "Unknown SWs; SW1=%02X, SW2=%02X", sw1, sw2);
  ------------------
  |  |   71|      0|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  134|      0|	return SC_ERROR_CARD_CMD_FAILED;
  ------------------
  |  |   50|      0|#define SC_ERROR_CARD_CMD_FAILED		-1200
  ------------------
  135|  2.14k|}

sc_do_log:
   58|  56.5k|{
   59|  56.5k|	va_list ap;
   60|       |
   61|  56.5k|	va_start(ap, format);
   62|  56.5k|	sc_do_log_va(ctx, level, file, line, func, 0, format, ap);
   63|       |	va_end(ap);
   64|  56.5k|}
sc_do_log_color:
   67|  10.0k|{
   68|  10.0k|	va_list ap;
   69|       |
   70|  10.0k|	va_start(ap, format);
   71|  10.0k|	sc_do_log_va(ctx, level, file, line, func, color, format, ap);
   72|       |	va_end(ap);
   73|  10.0k|}
sc_color_fprintf:
  254|   316k|{
  255|   316k|	int r;
  256|   316k|	va_list ap;
  257|       |
  258|   316k|	va_start(ap, format);
  259|   316k|	r = sc_color_fprintf_va(colors, ctx, stream, format, ap);
  260|   316k|	va_end(ap);
  261|       |
  262|   316k|	return r;
  263|   316k|}
_sc_debug_hex:
  343|     77|{
  344|     77|	size_t blen = len * 5 + 128;
  345|     77|	char *buf = malloc(blen);
  346|     77|	if (buf == NULL)
  ------------------
  |  Branch (346:6): [True: 0, False: 77]
  ------------------
  347|      0|		return;
  348|       |
  349|     77|	sc_hex_dump(data, len, buf, blen);
  350|       |
  351|     77|	if (label)
  ------------------
  |  Branch (351:6): [True: 77, False: 0]
  ------------------
  352|     77|		sc_do_log(ctx, type, file, line, func,
  353|     77|			"\n%s (%"SC_FORMAT_LEN_SIZE_T"u byte%s):\n%s",
  354|     77|			label, len, len==1?"":"s", buf);
  ------------------
  |  Branch (354:16): [True: 10, False: 67]
  ------------------
  355|      0|	else
  356|      0|		sc_do_log(ctx, type, file, line, func,
  357|      0|			"%"SC_FORMAT_LEN_SIZE_T"u byte%s:\n%s",
  358|      0|			len, len==1?"":"s", buf);
  ------------------
  |  Branch (358:9): [True: 0, False: 0]
  ------------------
  359|       |
  360|     77|	free(buf);
  361|     77|}
sc_hex_dump:
  364|     77|{
  365|     77|	char *p = buf;
  366|     77|	size_t p_len = len;
  367|     77|	int lines = 0;
  368|       |
  369|     77|	if (buf == NULL || (in == NULL && count != 0)) {
  ------------------
  |  Branch (369:6): [True: 0, False: 77]
  |  Branch (369:22): [True: 0, False: 77]
  |  Branch (369:36): [True: 0, False: 0]
  ------------------
  370|      0|		return;
  371|      0|	}
  372|     77|	buf[0] = 0;
  373|     77|	if ((count * 5) > len)
  ------------------
  |  Branch (373:6): [True: 0, False: 77]
  ------------------
  374|      0|		return;
  375|    117|	while (count) {
  ------------------
  |  Branch (375:9): [True: 40, False: 77]
  ------------------
  376|     40|		char ascbuf[17];
  377|     40|		size_t i;
  378|       |
  379|    142|		for (i = 0; i < count && i < 16; i++) {
  ------------------
  |  Branch (379:15): [True: 102, False: 40]
  |  Branch (379:28): [True: 102, False: 0]
  ------------------
  380|    102|			sprintf(p, "%02X ", *in);
  381|    102|			if (isprint(*in))
  ------------------
  |  Branch (381:8): [True: 46, False: 56]
  ------------------
  382|     46|				ascbuf[i] = *in;
  383|     56|			else
  384|     56|				ascbuf[i] = '.';
  385|    102|			p += 3;
  386|    102|			p_len -= 3;
  387|    102|			in++;
  388|    102|		}
  389|     40|		count -= i;
  390|     40|		ascbuf[i] = 0;
  391|     40|		for (; i < 16 && lines; i++) {
  ------------------
  |  Branch (391:10): [True: 40, False: 0]
  |  Branch (391:20): [True: 0, False: 40]
  ------------------
  392|      0|			strlcat(p, "   ", p_len);
  393|      0|			p += 3;
  394|      0|			p_len -= 3;
  395|      0|		}
  396|     40|		snprintf(p, p_len, "%s\n", ascbuf);
  397|     40|		p += strlen(ascbuf) + 1;
  398|     40|		p_len -= strlen(ascbuf) - 1;
  399|     40|		lines++;
  400|     40|	}
  401|     77|}
sc_dump_hex:
  405|  1.73k|{
  406|  1.73k|	static char dump_buf[0x1000];
  407|  1.73k|	size_t ii, size = sizeof(dump_buf) - 0x10;
  408|  1.73k|	size_t offs = 0;
  409|       |
  410|  1.73k|	memset(dump_buf, 0, sizeof(dump_buf));
  411|  1.73k|	if (in == NULL)
  ------------------
  |  Branch (411:6): [True: 0, False: 1.73k]
  ------------------
  412|      0|		return dump_buf;
  413|       |
  414|  1.73k|	for (ii=0; ii<count; ii++) {
  ------------------
  |  Branch (414:13): [True: 0, False: 1.73k]
  ------------------
  415|      0|		if (ii && !(ii%16))   {
  ------------------
  |  Branch (415:7): [True: 0, False: 0]
  |  Branch (415:13): [True: 0, False: 0]
  ------------------
  416|      0|			if (!(ii%48))
  ------------------
  |  Branch (416:8): [True: 0, False: 0]
  ------------------
  417|      0|				snprintf(dump_buf + offs, size - offs, "\n");
  418|      0|			else
  419|      0|				snprintf(dump_buf + offs, size - offs, " ");
  420|      0|			offs = strlen(dump_buf);
  421|      0|		}
  422|       |
  423|      0|		snprintf(dump_buf + offs, size - offs, "%02X", *(in + ii));
  424|      0|		offs += 2;
  425|       |
  426|      0|		if (offs > size)
  ------------------
  |  Branch (426:7): [True: 0, False: 0]
  ------------------
  427|      0|			break;
  428|      0|	}
  429|       |
  430|  1.73k|	if (ii<count)
  ------------------
  |  Branch (430:6): [True: 0, False: 1.73k]
  ------------------
  431|      0|		snprintf(dump_buf + offs, sizeof(dump_buf) - offs, "....\n");
  432|       |
  433|  1.73k|	return dump_buf;
  434|  1.73k|}
log.c:sc_do_log_va:
  124|  66.6k|{
  125|       |#ifdef _WIN32
  126|       |	SYSTEMTIME st;
  127|       |#else
  128|  66.6k|	struct tm *tm;
  129|  66.6k|	struct timeval tv;
  130|  66.6k|	char time_string[40];
  131|  66.6k|#endif
  132|       |
  133|  66.6k|	if (!ctx || ctx->debug < level)
  ------------------
  |  Branch (133:6): [True: 0, False: 66.6k]
  |  Branch (133:14): [True: 18.4k, False: 48.2k]
  ------------------
  134|  18.4k|		return;
  135|       |
  136|       |#ifdef _WIN32
  137|       |	/* In Windows, file handles can not be shared between DLL-s, each DLL has a
  138|       |	 * separate file handle table. Make sure we always have a valid file
  139|       |	 * descriptor. */
  140|       |	if (sc_ctx_log_to_file(ctx, ctx->debug_filename) < 0)
  141|       |		return;
  142|       |#endif
  143|  48.2k|	if (ctx->debug_file == NULL)
  ------------------
  |  Branch (143:6): [True: 0, False: 48.2k]
  ------------------
  144|      0|		return;
  145|       |
  146|       |#ifdef _WIN32
  147|       |	GetLocalTime(&st);
  148|       |	sc_color_fprintf(SC_COLOR_FG_GREEN|SC_COLOR_BOLD,
  149|       |			ctx, ctx->debug_file,
  150|       |			"P:%lu; T:%lu",
  151|       |			(unsigned long)GetCurrentProcessId(),
  152|       |			(unsigned long)GetCurrentThreadId());
  153|       |	sc_color_fprintf(SC_COLOR_FG_GREEN,
  154|       |			ctx, ctx->debug_file,
  155|       |			" %i-%02i-%02i %02i:%02i:%02i.%03i",
  156|       |			st.wYear, st.wMonth, st.wDay,
  157|       |			st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
  158|       |#else
  159|  48.2k|	sc_color_fprintf(SC_COLOR_FG_GREEN|SC_COLOR_BOLD,
  ------------------
  |  |   45|  48.2k|#define SC_COLOR_FG_GREEN		0x0002
  ------------------
              	sc_color_fprintf(SC_COLOR_FG_GREEN|SC_COLOR_BOLD,
  ------------------
  |  |   56|  48.2k|#define SC_COLOR_BOLD			0x8080
  ------------------
  160|  48.2k|			ctx, ctx->debug_file,
  161|  48.2k|			"P:%lu; T:0x%lu",
  162|  48.2k|			(unsigned long)getpid(),
  163|  48.2k|			(unsigned long)pthread_self());
  164|  48.2k|	gettimeofday (&tv, NULL);
  165|  48.2k|	tm = localtime (&tv.tv_sec);
  166|  48.2k|	strftime (time_string, sizeof(time_string), "%H:%M:%S", tm);
  167|  48.2k|	sc_color_fprintf(SC_COLOR_FG_GREEN,
  ------------------
  |  |   45|  48.2k|#define SC_COLOR_FG_GREEN		0x0002
  ------------------
  168|  48.2k|			ctx, ctx->debug_file,
  169|  48.2k|			" %s.%03ld",
  170|  48.2k|			time_string,
  171|  48.2k|			(long)tv.tv_usec / 1000);
  172|  48.2k|#endif
  173|       |
  174|  48.2k|	sc_color_fprintf(SC_COLOR_FG_YELLOW,
  ------------------
  |  |   46|  48.2k|#define SC_COLOR_FG_YELLOW		0x0004
  ------------------
  175|  48.2k|			ctx, ctx->debug_file,
  176|  48.2k|			" [");
  177|  48.2k|	sc_color_fprintf(SC_COLOR_FG_YELLOW|SC_COLOR_BOLD,
  ------------------
  |  |   46|  48.2k|#define SC_COLOR_FG_YELLOW		0x0004
  ------------------
              	sc_color_fprintf(SC_COLOR_FG_YELLOW|SC_COLOR_BOLD,
  ------------------
  |  |   56|  48.2k|#define SC_COLOR_BOLD			0x8080
  ------------------
  178|  48.2k|			ctx, ctx->debug_file,
  179|  48.2k|			"%s",
  180|  48.2k|			ctx->app_name);
  181|  48.2k|	sc_color_fprintf(SC_COLOR_FG_YELLOW,
  ------------------
  |  |   46|  48.2k|#define SC_COLOR_FG_YELLOW		0x0004
  ------------------
  182|  48.2k|			ctx, ctx->debug_file,
  183|  48.2k|			"] ");
  184|       |
  185|  48.2k|	if (file != NULL) {
  ------------------
  |  Branch (185:6): [True: 48.2k, False: 0]
  ------------------
  186|  48.2k|		sc_color_fprintf(SC_COLOR_FG_YELLOW,
  ------------------
  |  |   46|  48.2k|#define SC_COLOR_FG_YELLOW		0x0004
  ------------------
  187|  48.2k|				ctx, ctx->debug_file,
  188|  48.2k|				"%s:%d:%s: ",
  189|  48.2k|				file, line, func ? func : "");
  ------------------
  |  Branch (189:17): [True: 48.2k, False: 0]
  ------------------
  190|  48.2k|	}
  191|       |
  192|  48.2k|	sc_color_fprintf_va(color, ctx, ctx->debug_file, format, args);
  193|  48.2k|	if (strlen(format) == 0 || format[strlen(format) - 1] != '\n')
  ------------------
  |  Branch (193:6): [True: 0, False: 48.2k]
  |  Branch (193:29): [True: 26.7k, False: 21.5k]
  ------------------
  194|  26.7k|		sc_color_fprintf(color, ctx, ctx->debug_file, "\n");
  195|  48.2k|	fflush(ctx->debug_file);
  196|       |
  197|       |#ifdef _WIN32
  198|       |	if (ctx->debug_file && (ctx->debug_file != stderr && ctx->debug_file != stdout))
  199|       |		fclose(ctx->debug_file);
  200|       |	ctx->debug_file = NULL;
  201|       |#endif
  202|  48.2k|}
log.c:sc_color_fprintf_va:
  266|   364k|{
  267|   364k|	int r;
  268|       |#ifdef _WIN32
  269|       |	WORD old_attr = 0;
  270|       |	int fd = stream ? fileno(stream) : -1;
  271|       |	HANDLE handle = fd >= 0 ? (HANDLE) _get_osfhandle(fd) : INVALID_HANDLE_VALUE;
  272|       |#endif
  273|       |
  274|   364k|	if (!is_a_tty(stream))
  ------------------
  |  Branch (274:6): [True: 364k, False: 0]
  ------------------
  275|   364k|		colors = 0;
  276|       |
  277|   364k|	if (colors && (!ctx || (!(ctx->flags & SC_CTX_FLAG_DISABLE_COLORS)))) {
  ------------------
  |  |  869|      0|#define SC_CTX_FLAG_DISABLE_COLORS			0x00000020
  ------------------
  |  Branch (277:6): [True: 0, False: 364k]
  |  Branch (277:17): [True: 0, False: 0]
  |  Branch (277:25): [True: 0, False: 0]
  ------------------
  278|       |#ifdef _WIN32
  279|       |		WORD attr = 0;
  280|       |		CONSOLE_SCREEN_BUFFER_INFO csbi;
  281|       |		GetConsoleScreenBufferInfo(handle, &csbi);
  282|       |		old_attr = csbi.wAttributes;
  283|       |#endif
  284|      0|		set_color(SC_COLOR_FG_RED,
  ------------------
  |  |  250|      0|	do { if (colors & sc_color) { fprintf(stream, vt100_color); } } while (0)
  |  |  ------------------
  |  |  |  Branch (250:11): [True: 0, False: 0]
  |  |  |  Branch (250:73): [Folded, False: 0]
  |  |  ------------------
  ------------------
  285|      0|				FOREGROUND_RED,
  286|      0|				"\x1b[31m");
  287|      0|		set_color(SC_COLOR_FG_GREEN,
  ------------------
  |  |  250|      0|	do { if (colors & sc_color) { fprintf(stream, vt100_color); } } while (0)
  |  |  ------------------
  |  |  |  Branch (250:11): [True: 0, False: 0]
  |  |  |  Branch (250:73): [Folded, False: 0]
  |  |  ------------------
  ------------------
  288|      0|				FOREGROUND_GREEN,
  289|      0|				"\x1b[32m");
  290|      0|		set_color(SC_COLOR_FG_YELLOW,
  ------------------
  |  |  250|      0|	do { if (colors & sc_color) { fprintf(stream, vt100_color); } } while (0)
  |  |  ------------------
  |  |  |  Branch (250:11): [True: 0, False: 0]
  |  |  |  Branch (250:73): [Folded, False: 0]
  |  |  ------------------
  ------------------
  291|      0|				FOREGROUND_GREEN|FOREGROUND_RED,
  292|      0|				"\x1b[33m");
  293|      0|		set_color(SC_COLOR_FG_BLUE,
  ------------------
  |  |  250|      0|	do { if (colors & sc_color) { fprintf(stream, vt100_color); } } while (0)
  |  |  ------------------
  |  |  |  Branch (250:11): [True: 0, False: 0]
  |  |  |  Branch (250:73): [Folded, False: 0]
  |  |  ------------------
  ------------------
  294|      0|				FOREGROUND_BLUE,
  295|      0|				"\x1b[34m");
  296|      0|		set_color(SC_COLOR_FG_MAGENTA,
  ------------------
  |  |  250|      0|	do { if (colors & sc_color) { fprintf(stream, vt100_color); } } while (0)
  |  |  ------------------
  |  |  |  Branch (250:11): [True: 0, False: 0]
  |  |  |  Branch (250:73): [Folded, False: 0]
  |  |  ------------------
  ------------------
  297|      0|				FOREGROUND_BLUE|FOREGROUND_RED,
  298|      0|				"\x1b[35m");
  299|      0|		set_color(SC_COLOR_FG_CYAN,
  ------------------
  |  |  250|      0|	do { if (colors & sc_color) { fprintf(stream, vt100_color); } } while (0)
  |  |  ------------------
  |  |  |  Branch (250:11): [True: 0, False: 0]
  |  |  |  Branch (250:73): [Folded, False: 0]
  |  |  ------------------
  ------------------
  300|      0|				FOREGROUND_BLUE|FOREGROUND_GREEN,
  301|      0|				"\x1b[36m");
  302|      0|		set_color(SC_COLOR_BG_RED,
  ------------------
  |  |  250|      0|	do { if (colors & sc_color) { fprintf(stream, vt100_color); } } while (0)
  |  |  ------------------
  |  |  |  Branch (250:11): [True: 0, False: 0]
  |  |  |  Branch (250:73): [Folded, False: 0]
  |  |  ------------------
  ------------------
  303|      0|				FOREGROUND_RED,
  304|      0|				"\x1b[41m");
  305|      0|		set_color(SC_COLOR_BG_GREEN,
  ------------------
  |  |  250|      0|	do { if (colors & sc_color) { fprintf(stream, vt100_color); } } while (0)
  |  |  ------------------
  |  |  |  Branch (250:11): [True: 0, False: 0]
  |  |  |  Branch (250:73): [Folded, False: 0]
  |  |  ------------------
  ------------------
  306|      0|				BACKGROUND_GREEN,
  307|      0|				"\x1b[42m");
  308|      0|		set_color(SC_COLOR_BG_YELLOW,
  ------------------
  |  |  250|      0|	do { if (colors & sc_color) { fprintf(stream, vt100_color); } } while (0)
  |  |  ------------------
  |  |  |  Branch (250:11): [True: 0, False: 0]
  |  |  |  Branch (250:73): [Folded, False: 0]
  |  |  ------------------
  ------------------
  309|      0|				BACKGROUND_GREEN|BACKGROUND_RED,
  310|      0|				"\x1b[43m");
  311|      0|		set_color(SC_COLOR_BG_BLUE,
  ------------------
  |  |  250|      0|	do { if (colors & sc_color) { fprintf(stream, vt100_color); } } while (0)
  |  |  ------------------
  |  |  |  Branch (250:11): [True: 0, False: 0]
  |  |  |  Branch (250:73): [Folded, False: 0]
  |  |  ------------------
  ------------------
  312|      0|				BACKGROUND_BLUE,
  313|      0|				"\x1b[44m");
  314|      0|		set_color(SC_COLOR_BG_MAGENTA,
  ------------------
  |  |  250|      0|	do { if (colors & sc_color) { fprintf(stream, vt100_color); } } while (0)
  |  |  ------------------
  |  |  |  Branch (250:11): [True: 0, False: 0]
  |  |  |  Branch (250:73): [Folded, False: 0]
  |  |  ------------------
  ------------------
  315|      0|				BACKGROUND_BLUE|BACKGROUND_RED,
  316|      0|				"\x1b[45m");
  317|      0|		set_color(SC_COLOR_BG_CYAN,
  ------------------
  |  |  250|      0|	do { if (colors & sc_color) { fprintf(stream, vt100_color); } } while (0)
  |  |  ------------------
  |  |  |  Branch (250:11): [True: 0, False: 0]
  |  |  |  Branch (250:73): [Folded, False: 0]
  |  |  ------------------
  ------------------
  318|      0|				BACKGROUND_BLUE|BACKGROUND_GREEN,
  319|      0|				"\x1b[46m");
  320|      0|		set_color(SC_COLOR_BOLD,
  ------------------
  |  |  250|      0|	do { if (colors & sc_color) { fprintf(stream, vt100_color); } } while (0)
  |  |  ------------------
  |  |  |  Branch (250:11): [True: 0, False: 0]
  |  |  |  Branch (250:73): [Folded, False: 0]
  |  |  ------------------
  ------------------
  321|      0|				FOREGROUND_INTENSITY,
  322|      0|				"\x1b[1m");
  323|       |#ifdef _WIN32
  324|       |		SetConsoleTextAttribute(handle, attr);
  325|       |#endif
  326|      0|	}
  327|       |
  328|   364k|	r = vfprintf(stream, format, args);
  329|       |
  330|   364k|	if (colors && (!ctx || (!(ctx->flags & SC_CTX_FLAG_DISABLE_COLORS)))) {
  ------------------
  |  |  869|      0|#define SC_CTX_FLAG_DISABLE_COLORS			0x00000020
  ------------------
  |  Branch (330:6): [True: 0, False: 364k]
  |  Branch (330:17): [True: 0, False: 0]
  |  Branch (330:25): [True: 0, False: 0]
  ------------------
  331|       |#ifdef _WIN32
  332|       |		SetConsoleTextAttribute(handle, old_attr);
  333|       |#else
  334|      0|		fprintf(stream, "\x1b[0m");
  335|      0|#endif
  336|      0|	}
  337|       |
  338|   364k|	return r;
  339|   364k|}
log.c:is_a_tty:
  228|   364k|{
  229|   364k|	if (fp != NULL) {
  ------------------
  |  Branch (229:6): [True: 364k, False: 0]
  ------------------
  230|   364k|		int fd = fileno(fp);
  231|   364k|		if (fd >= 0) {
  ------------------
  |  Branch (231:7): [True: 0, False: 364k]
  ------------------
  232|       |#ifdef _WIN32
  233|       |			HANDLE h = (HANDLE)_get_osfhandle(fd);
  234|       |			if (h != INVALID_HANDLE_VALUE) {
  235|       |				return GetFileType(h) == FILE_TYPE_CHAR;
  236|       |			}
  237|       |#else
  238|      0|			return isatty(fd);
  239|      0|#endif
  240|      0|		}
  241|   364k|	}
  242|   364k|	return 0;
  243|   364k|}

msc_select_applet:
  262|     51|{
  263|     51|	sc_apdu_t apdu;
  264|     51|	int r;
  265|       |
  266|     51|	sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0xA4, 4, 0);
  ------------------
  |  |  293|     51|#define SC_APDU_CASE_3_SHORT		0x03
  ------------------
  267|     51|	apdu.lc = appletIdLength;
  268|     51|	apdu.data = appletId;
  269|     51|	apdu.datalen = appletIdLength;
  270|     51|	apdu.resplen = 0;
  271|     51|	apdu.le = 0;
  272|       |
  273|     51|	r = sc_transmit_apdu(card, &apdu);
  274|     51|	LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
  ------------------
  |  |  174|     51|#define LOG_TEST_RET(ctx, r, text) SC_TEST_RET((ctx), SC_LOG_DEBUG_NORMAL, (r), (text))
  |  |  ------------------
  |  |  |  |  166|     51|#define SC_TEST_RET(ctx, level, r, text) do { \
  |  |  |  |  167|     51|	int _ret = (r); \
  |  |  |  |  168|     51|	if (_ret < 0) { \
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (168:6): [True: 0, False: 51]
  |  |  |  |  ------------------
  |  |  |  |  169|      0|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, SC_COLOR_FG_RED, \
  |  |  |  |  ------------------
  |  |  |  |  |  |   44|      0|#define SC_COLOR_FG_RED			0x0001
  |  |  |  |  ------------------
  |  |  |  |  170|      0|			"%s: %d (%s)\n", (text), _ret, sc_strerror(_ret)); \
  |  |  |  |  171|      0|		return _ret; \
  |  |  |  |  172|      0|	} \
  |  |  |  |  173|     51|} while(0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (173:9): [Folded, False: 51]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  275|     51|	if(apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
  ------------------
  |  Branch (275:5): [True: 0, False: 51]
  |  Branch (275:25): [True: 0, False: 0]
  ------------------
  276|      0|		return 1;
  277|       |
  278|     51|	SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE,  SC_ERROR_CARD_CMD_FAILED);
  ------------------
  |  |  153|     51|#define SC_FUNC_RETURN(ctx, level, r) do { \
  |  |  154|     51|	int _ret = r; \
  |  |  155|     51|	if (_ret <= 0) { \
  |  |  ------------------
  |  |  |  Branch (155:6): [True: 51, False: 0]
  |  |  ------------------
  |  |  156|     51|		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |               		sc_do_log_color(ctx, level, FILENAME, __LINE__, __FUNCTION__, _ret ? SC_COLOR_FG_RED : 0, \
  |  |  ------------------
  |  |  |  |   44|     51|#define SC_COLOR_FG_RED			0x0001
  |  |  ------------------
  |  |  |  Branch (156:65): [True: 51, False: 0]
  |  |  ------------------
  |  |  157|     51|			"returning with: %d (%s)\n", _ret, sc_strerror(_ret)); \
  |  |  158|     51|	} else { \
  |  |  159|      0|		sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, \
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  |  |  160|      0|			"returning with: %d\n", _ret); \
  |  |  161|      0|	} \
  |  |  162|     51|	return _ret; \
  |  |  163|     51|} while(0)
  |  |  ------------------
  |  |  |  Branch (163:9): [Folded, False: 0]
  |  |  ------------------
  ------------------
  279|     51|}

sc_pkcs15_unbind:
 1384|    295|{
 1385|    295|	if (p15card == NULL || p15card->magic != SC_PKCS15_CARD_MAGIC) {
  ------------------
  |  |  519|      0|#define SC_PKCS15_CARD_MAGIC		0x10203040
  ------------------
  |  Branch (1385:6): [True: 295, False: 0]
  |  Branch (1385:25): [True: 0, False: 0]
  ------------------
 1386|    295|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|    295|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
 1387|    295|	}
 1388|       |
 1389|      0|	LOG_FUNC_CALLED(p15card->card->ctx);
  ------------------
  |  |  151|      0|#define LOG_FUNC_CALLED(ctx) SC_FUNC_CALLED((ctx), SC_LOG_DEBUG_NORMAL)
  |  |  ------------------
  |  |  |  |  148|      0|#define SC_FUNC_CALLED(ctx, level) do { \
  |  |  |  |  149|      0|	 sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, "called\n"); \
  |  |  |  |  ------------------
  |  |  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  |  |  ------------------
  |  |  |  |  150|      0|} while (0)
  |  |  |  |  ------------------
  |  |  |  |  |  Branch (150:10): [Folded, False: 0]
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
 1390|      0|	if (p15card->dll_handle)
  ------------------
  |  Branch (1390:6): [True: 0, False: 0]
  ------------------
 1391|      0|		sc_dlclose(p15card->dll_handle);
 1392|      0|	sc_pkcs15_pincache_clear(p15card);
 1393|      0|	sc_pkcs15_card_free(p15card);
 1394|      0|	return 0;
 1395|    295|}

sc_get_ctapi_driver:
  558|    295|{
  559|    295|	ctapi_ops.init = ctapi_init;
  560|    295|	ctapi_ops.finish = ctapi_finish;
  561|    295|	ctapi_ops.detect_readers = NULL;
  562|    295|	ctapi_ops.transmit = ctapi_transmit;
  563|    295|	ctapi_ops.detect_card_presence = ctapi_detect_card_presence;
  564|    295|	ctapi_ops.lock = ctapi_lock;
  565|    295|	ctapi_ops.unlock = ctapi_unlock;
  566|    295|	ctapi_ops.release = ctapi_release;
  567|    295|	ctapi_ops.connect = ctapi_connect;
  568|    295|	ctapi_ops.disconnect = ctapi_disconnect;
  569|    295|	ctapi_ops.perform_verify = ctbcs_pin_cmd;
  570|    295|	ctapi_ops.perform_pace = NULL;
  571|    295|	ctapi_ops.use_reader = NULL;
  572|       |
  573|    295|	return &ctapi_drv;
  574|    295|}
reader-ctapi.c:ctapi_init:
  515|    295|{
  516|    295|	int i;
  517|    295|	struct ctapi_global_private_data *gpriv;
  518|    295|	scconf_block **blocks = NULL, *conf_block = NULL;
  519|       |
  520|    295|	gpriv = calloc(1, sizeof(struct ctapi_global_private_data));
  521|    295|	if (gpriv == NULL)
  ------------------
  |  Branch (521:6): [True: 0, False: 295]
  ------------------
  522|      0|		return SC_ERROR_OUT_OF_MEMORY;
  ------------------
  |  |   85|      0|#define SC_ERROR_OUT_OF_MEMORY			-1404
  ------------------
  523|    295|	ctx->reader_drv_data = gpriv;
  524|       |
  525|    295|	conf_block = sc_get_conf_block(ctx, "reader_driver", "ctapi", 1);
  526|    295|	if (conf_block)   {
  ------------------
  |  Branch (526:6): [True: 0, False: 295]
  ------------------
  527|      0|		blocks = scconf_find_blocks(ctx->conf, conf_block, "module", NULL);
  528|      0|		for (i = 0; blocks != NULL && blocks[i] != NULL; i++)
  ------------------
  |  Branch (528:15): [True: 0, False: 0]
  |  Branch (528:33): [True: 0, False: 0]
  ------------------
  529|      0|			ctapi_load_module(ctx, gpriv, blocks[i]);
  530|      0|		free(blocks);
  531|      0|	}
  532|       |
  533|    295|	return 0;
  534|    295|}
reader-ctapi.c:ctapi_finish:
  537|    295|{
  538|    295|	struct ctapi_global_private_data *priv = (struct ctapi_global_private_data *) ctx->reader_drv_data;
  539|       |
  540|    295|	if (priv) {
  ------------------
  |  Branch (540:6): [True: 295, False: 0]
  ------------------
  541|    295|		int i;
  542|       |
  543|    295|		for (i = 0; i < priv->module_count; i++) {
  ------------------
  |  Branch (543:15): [True: 0, False: 295]
  ------------------
  544|      0|			struct ctapi_module *mod = &priv->modules[i];
  545|       |
  546|      0|			free(mod->name);
  547|      0|			sc_dlclose(mod->dlhandle);
  548|      0|		}
  549|    295|		if (priv->module_count)
  ------------------
  |  Branch (549:7): [True: 0, False: 295]
  ------------------
  550|      0|			free(priv->modules);
  551|    295|		free(priv);
  552|    295|	}
  553|       |
  554|    295|	return 0;
  555|    295|}

sc_get_version:
   59|    295|{
   60|    295|    return sc_version;
   61|    295|}
sc_hex_to_bin:
   64|    306|{
   65|    306|	const char *sc_hex_to_bin_separators = " :";
   66|    306|	if (in == NULL || out == NULL || outlen == NULL) {
  ------------------
  |  Branch (66:6): [True: 0, False: 306]
  |  Branch (66:20): [True: 0, False: 306]
  |  Branch (66:35): [True: 0, False: 306]
  ------------------
   67|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
   68|      0|	}
   69|       |
   70|    306|	int byte_needs_nibble = 0;
   71|    306|	int r = SC_SUCCESS;
  ------------------
  |  |   28|    306|#define SC_SUCCESS				0
  ------------------
   72|    306|	size_t left = *outlen;
   73|    306|	u8 byte = 0;
   74|  8.56k|	while (*in != '\0' && 0 != left) {
  ------------------
  |  Branch (74:9): [True: 8.26k, False: 306]
  |  Branch (74:24): [True: 8.26k, False: 0]
  ------------------
   75|  8.26k|		char c = *in++;
   76|  8.26k|		u8 nibble;
   77|  8.26k|		if      ('0' <= c && c <= '9')
  ------------------
  |  Branch (77:12): [True: 8.26k, False: 0]
  |  Branch (77:24): [True: 4.84k, False: 3.41k]
  ------------------
   78|  4.84k|			nibble = c - '0';
   79|  3.41k|		else if ('a' <= c && c <= 'f')
  ------------------
  |  Branch (79:12): [True: 561, False: 2.85k]
  |  Branch (79:24): [True: 561, False: 0]
  ------------------
   80|    561|			nibble = c - 'a' + 10;
   81|  2.85k|		else if ('A' <= c && c <= 'F')
  ------------------
  |  Branch (81:12): [True: 714, False: 2.14k]
  |  Branch (81:24): [True: 714, False: 0]
  ------------------
   82|    714|			nibble = c - 'A' + 10;
   83|  2.14k|		else {
   84|  2.14k|			if (strchr(sc_hex_to_bin_separators, (int) c)) {
  ------------------
  |  Branch (84:8): [True: 2.14k, False: 0]
  ------------------
   85|  2.14k|				if (byte_needs_nibble) {
  ------------------
  |  Branch (85:9): [True: 0, False: 2.14k]
  ------------------
   86|      0|					r = SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
   87|      0|					goto err;
   88|      0|				}
   89|  2.14k|				continue;
   90|  2.14k|			}
   91|      0|			r = SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
   92|      0|			goto err;
   93|  2.14k|		}
   94|       |
   95|  6.12k|		if (byte_needs_nibble) {
  ------------------
  |  Branch (95:7): [True: 3.06k, False: 3.06k]
  ------------------
   96|  3.06k|			byte |= nibble;
   97|  3.06k|			*out++ = (u8) byte;
   98|  3.06k|			left--;
   99|  3.06k|			byte_needs_nibble = 0;
  100|  3.06k|		} else {
  101|  3.06k|			byte  = nibble << 4;
  102|  3.06k|			byte_needs_nibble = 1;
  103|  3.06k|		}
  104|  6.12k|	}
  105|       |
  106|    306|	if (left == *outlen && 1 == byte_needs_nibble && 0 != left) {
  ------------------
  |  Branch (106:6): [True: 0, False: 306]
  |  Branch (106:25): [True: 0, False: 0]
  |  Branch (106:51): [True: 0, False: 0]
  ------------------
  107|       |		/* no output written so far, but we have a valid nibble in the upper
  108|       |		 * bits. Allow this special case. */
  109|      0|		*out = (u8) byte>>4;
  110|      0|		left--;
  111|      0|		byte_needs_nibble = 0;
  112|      0|	}
  113|       |
  114|       |	/* for ease of implementation we only accept completely hexed bytes. */
  115|    306|	if (byte_needs_nibble) {
  ------------------
  |  Branch (115:6): [True: 0, False: 306]
  ------------------
  116|      0|		r = SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  117|      0|		goto err;
  118|      0|	}
  119|       |
  120|       |	/* skip all trailing separators to see if we missed something */
  121|    306|	while (*in != '\0') {
  ------------------
  |  Branch (121:9): [True: 0, False: 306]
  ------------------
  122|      0|		if (NULL == strchr(sc_hex_to_bin_separators, (int) *in))
  ------------------
  |  Branch (122:7): [True: 0, False: 0]
  ------------------
  123|      0|			break;
  124|      0|		in++;
  125|      0|	}
  126|    306|	if (*in != '\0') {
  ------------------
  |  Branch (126:6): [True: 0, False: 306]
  ------------------
  127|      0|		r = SC_ERROR_BUFFER_TOO_SMALL;
  ------------------
  |  |   76|      0|#define SC_ERROR_BUFFER_TOO_SMALL		-1303
  ------------------
  128|      0|		goto err;
  129|      0|	}
  130|       |
  131|    306|err:
  132|    306|	*outlen -= left;
  133|    306|	return r;
  134|    306|}
sc_bin_to_hex:
  138|  1.68k|{
  139|  1.68k|	if (in == NULL || out == NULL) {
  ------------------
  |  Branch (139:6): [True: 0, False: 1.68k]
  |  Branch (139:20): [True: 0, False: 1.68k]
  ------------------
  140|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  141|      0|	}
  142|       |
  143|  1.68k|	if (in_sep > 0) {
  ------------------
  |  Branch (143:6): [True: 1.68k, False: 0]
  ------------------
  144|  1.68k|		if (out_len < in_len*3 || out_len < 1)
  ------------------
  |  Branch (144:7): [True: 0, False: 1.68k]
  |  Branch (144:29): [True: 0, False: 1.68k]
  ------------------
  145|      0|			return SC_ERROR_BUFFER_TOO_SMALL;
  ------------------
  |  |   76|      0|#define SC_ERROR_BUFFER_TOO_SMALL		-1303
  ------------------
  146|  1.68k|	} else {
  147|      0|		if (out_len < in_len*2 + 1)
  ------------------
  |  Branch (147:7): [True: 0, False: 0]
  ------------------
  148|      0|			return SC_ERROR_BUFFER_TOO_SMALL;
  ------------------
  |  |   76|      0|#define SC_ERROR_BUFFER_TOO_SMALL		-1303
  ------------------
  149|      0|	}
  150|       |
  151|  1.68k|	const char hex[] = "0123456789abcdef";
  152|  3.36k|	while (in_len) {
  ------------------
  |  Branch (152:9): [True: 1.68k, False: 1.68k]
  ------------------
  153|  1.68k|		unsigned char value = *in++;
  154|  1.68k|		*out++ = hex[(value >> 4) & 0xF];
  155|  1.68k|		*out++ = hex[ value       & 0xF];
  156|  1.68k|		in_len--;
  157|  1.68k|		if (in_len && in_sep > 0)
  ------------------
  |  Branch (157:7): [True: 1.02k, False: 660]
  |  Branch (157:17): [True: 1.02k, False: 0]
  ------------------
  158|  1.02k|			*out++ = (char)in_sep;
  159|  1.68k|	}
  160|  1.68k|	*out = '\0';
  161|       |
  162|  1.68k|	return SC_SUCCESS;
  ------------------
  |  |   28|  1.68k|#define SC_SUCCESS				0
  ------------------
  163|  1.68k|}
sc_path_set:
  355|     51|{
  356|     51|	if (path == NULL || id == NULL || id_len == 0 || id_len > SC_MAX_PATH_SIZE)
  ------------------
  |  |   47|     51|#define SC_MAX_PATH_SIZE		16
  ------------------
  |  Branch (356:6): [True: 0, False: 51]
  |  Branch (356:22): [True: 0, False: 51]
  |  Branch (356:36): [True: 0, False: 51]
  |  Branch (356:51): [True: 0, False: 51]
  ------------------
  357|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  358|       |
  359|     51|	memset(path, 0, sizeof(*path));
  360|     51|	memcpy(path->value, id, id_len);
  361|     51|	path->len   = id_len;
  362|     51|	path->type  = type;
  363|     51|	path->index = idx;
  364|     51|	path->count = count;
  365|       |
  366|     51|	return SC_SUCCESS;
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  367|     51|}
sc_format_path:
  370|    102|{
  371|    102|	int type = SC_PATH_TYPE_PATH;
  ------------------
  |  |  119|    102|#define SC_PATH_TYPE_PATH		2
  ------------------
  372|       |
  373|    102|	if (path) {
  ------------------
  |  Branch (373:6): [True: 102, False: 0]
  ------------------
  374|    102|		memset(path, 0, sizeof(*path));
  375|    102|		if (*str == 'i' || *str == 'I') {
  ------------------
  |  Branch (375:7): [True: 0, False: 102]
  |  Branch (375:22): [True: 0, False: 102]
  ------------------
  376|      0|			type = SC_PATH_TYPE_FILE_ID;
  ------------------
  |  |  117|      0|#define SC_PATH_TYPE_FILE_ID		0
  ------------------
  377|      0|			str++;
  378|      0|		}
  379|    102|		path->len = sizeof(path->value);
  380|    102|		if (sc_hex_to_bin(str, path->value, &path->len) >= 0) {
  ------------------
  |  Branch (380:7): [True: 102, False: 0]
  ------------------
  381|    102|			path->type = type;
  382|    102|		}
  383|    102|		path->count = -1;
  384|    102|	}
  385|    102|}
sc_print_path:
  439|  1.78k|{
  440|  1.78k|	static char buffer[SC_MAX_PATH_STRING_SIZE + SC_MAX_AID_STRING_SIZE];
  441|       |
  442|  1.78k|	if (sc_path_print(buffer, sizeof(buffer), path) != SC_SUCCESS)
  ------------------
  |  |   28|  1.78k|#define SC_SUCCESS				0
  ------------------
  |  Branch (442:6): [True: 0, False: 1.78k]
  ------------------
  443|      0|		buffer[0] = '\0';
  444|       |
  445|  1.78k|	return buffer;
  446|  1.78k|}
sc_path_print:
  449|  1.88k|{
  450|  1.88k|	size_t i;
  451|       |
  452|  1.88k|	if (buf == NULL || path == NULL)
  ------------------
  |  Branch (452:6): [True: 0, False: 1.88k]
  |  Branch (452:21): [True: 0, False: 1.88k]
  ------------------
  453|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
  454|       |
  455|  1.88k|	if (buflen < path->len * 2 + path->aid.len * 2 + 3)
  ------------------
  |  Branch (455:6): [True: 0, False: 1.88k]
  ------------------
  456|      0|		return SC_ERROR_BUFFER_TOO_SMALL;
  ------------------
  |  |   76|      0|#define SC_ERROR_BUFFER_TOO_SMALL		-1303
  ------------------
  457|       |
  458|  1.88k|	buf[0] = '\0';
  459|  1.88k|	if (path->aid.len)   {
  ------------------
  |  Branch (459:6): [True: 1.73k, False: 153]
  ------------------
  460|  13.8k|		for (i = 0; i < path->aid.len; i++)
  ------------------
  |  Branch (460:15): [True: 12.1k, False: 1.73k]
  ------------------
  461|  12.1k|			snprintf(buf + strlen(buf), buflen - strlen(buf), "%02x", path->aid.value[i]);
  462|  1.73k|		snprintf(buf + strlen(buf), buflen - strlen(buf), "::");
  463|  1.73k|	}
  464|       |
  465|  3.00k|	for (i = 0; i < path->len; i++)
  ------------------
  |  Branch (465:14): [True: 1.12k, False: 1.88k]
  ------------------
  466|  1.12k|		snprintf(buf + strlen(buf), buflen - strlen(buf), "%02x", path->value[i]);
  467|  1.88k|	if (!path->aid.len && path->type == SC_PATH_TYPE_DF_NAME)
  ------------------
  |  |  118|    153|#define SC_PATH_TYPE_DF_NAME		1
  ------------------
  |  Branch (467:6): [True: 153, False: 1.73k]
  |  Branch (467:24): [True: 102, False: 51]
  ------------------
  468|    102|		snprintf(buf + strlen(buf), buflen - strlen(buf), "::");
  469|       |
  470|  1.88k|	return SC_SUCCESS;
  ------------------
  |  |   28|  1.88k|#define SC_SUCCESS				0
  ------------------
  471|  1.88k|}
sc_get_mf_path:
  493|     51|{
  494|     51|	static const sc_path_t mf_path = {
  495|     51|		{0x3f, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 2,
  496|     51|		0,
  497|     51|		0,
  498|     51|		SC_PATH_TYPE_PATH,
  ------------------
  |  |  119|     51|#define SC_PATH_TYPE_PATH		2
  ------------------
  499|     51|		{{0},0}
  500|     51|	};
  501|     51|	return &mf_path;
  502|     51|}
_sc_parse_atr:
  824|     51|{
  825|     51|	u8 *p = reader->atr.value;
  826|     51|	int atr_len = (int) reader->atr.len;
  827|     51|	int n_hist, x;
  828|     51|	int tx[4] = {-1, -1, -1, -1};
  829|     51|	int i, FI, DI;
  830|     51|	const int Fi_table[] = {
  831|     51|		372, 372, 558, 744, 1116, 1488, 1860, -1,
  832|     51|		-1, 512, 768, 1024, 1536, 2048, -1, -1 };
  833|     51|	const int f_table[] = {
  834|     51|		40, 50, 60, 80, 120, 160, 200, -1,
  835|     51|		-1, 50, 75, 100, 150, 200, -1, -1 };
  836|     51|	const int Di_table[] = {
  837|     51|		-1, 1, 2, 4, 8, 16, 32, -1,
  838|     51|		12, 20, -1, -1, -1, -1, -1, -1 };
  839|       |
  840|     51|	reader->atr_info.hist_bytes_len = 0;
  841|     51|	reader->atr_info.hist_bytes = NULL;
  842|       |
  843|     51|	if (atr_len == 0) {
  ------------------
  |  Branch (843:6): [True: 31, False: 20]
  ------------------
  844|     31|		sc_log(reader->ctx, "empty ATR - card not present?\n");
  ------------------
  |  |   71|     31|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  845|     31|		return SC_ERROR_INTERNAL;
  ------------------
  |  |   81|     31|#define SC_ERROR_INTERNAL			-1400
  ------------------
  846|     31|	}
  847|       |
  848|     20|	if (p[0] != 0x3B && p[0] != 0x3F) {
  ------------------
  |  Branch (848:6): [True: 17, False: 3]
  |  Branch (848:22): [True: 17, False: 0]
  ------------------
  849|     17|		sc_log(reader->ctx, "invalid sync byte in ATR: 0x%02X\n", p[0]);
  ------------------
  |  |   71|     17|#define sc_log(ctx, format, args...)   sc_do_log(ctx, SC_LOG_DEBUG_NORMAL, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
  850|     17|		return SC_ERROR_INTERNAL;
  ------------------
  |  |   81|     17|#define SC_ERROR_INTERNAL			-1400
  ------------------
  851|     17|	}
  852|      3|	n_hist = p[1] & 0x0F;
  853|      3|	x = p[1] >> 4;
  854|      3|	p += 2;
  855|      3|	atr_len -= 2;
  856|     10|	for (i = 0; i < 4 && atr_len > 0; i++) {
  ------------------
  |  Branch (856:14): [True: 9, False: 1]
  |  Branch (856:23): [True: 7, False: 2]
  ------------------
  857|      7|                if (x & (1 << i)) {
  ------------------
  |  Branch (857:21): [True: 2, False: 5]
  ------------------
  858|      2|                        tx[i] = *p;
  859|      2|                        p++;
  860|      2|                        atr_len--;
  861|      2|                } else
  862|      5|                        tx[i] = -1;
  863|      7|        }
  864|      3|	if (tx[0] >= 0) {
  ------------------
  |  Branch (864:6): [True: 0, False: 3]
  ------------------
  865|      0|		reader->atr_info.FI = FI = tx[0] >> 4;
  866|      0|		reader->atr_info.DI = DI = tx[0] & 0x0F;
  867|      0|		reader->atr_info.Fi = Fi_table[FI];
  868|      0|		reader->atr_info.f = f_table[FI];
  869|      0|		reader->atr_info.Di = Di_table[DI];
  870|      3|	} else {
  871|      3|		reader->atr_info.Fi = -1;
  872|      3|		reader->atr_info.f = -1;
  873|      3|		reader->atr_info.Di = -1;
  874|      3|	}
  875|      3|	if (tx[2] >= 0)
  ------------------
  |  Branch (875:6): [True: 1, False: 2]
  ------------------
  876|      1|		reader->atr_info.N = tx[3];
  877|      2|	else
  878|      2|		reader->atr_info.N = -1;
  879|      3|	while (tx[3] > 0 && tx[3] & 0xF0 && atr_len > 0) {
  ------------------
  |  Branch (879:9): [True: 0, False: 3]
  |  Branch (879:22): [True: 0, False: 0]
  |  Branch (879:38): [True: 0, False: 0]
  ------------------
  880|      0|		x = tx[3] >> 4;
  881|      0|		for (i = 0; i < 4 && atr_len > 0; i++) {
  ------------------
  |  Branch (881:15): [True: 0, False: 0]
  |  Branch (881:24): [True: 0, False: 0]
  ------------------
  882|      0|	                if (x & (1 << i)) {
  ------------------
  |  Branch (882:22): [True: 0, False: 0]
  ------------------
  883|      0|	                        tx[i] = *p;
  884|      0|	                        p++;
  885|      0|	                        atr_len--;
  886|      0|	                } else
  887|      0|	                        tx[i] = -1;
  888|      0|		}
  889|      0|	}
  890|      3|	if (atr_len <= 0)
  ------------------
  |  Branch (890:6): [True: 2, False: 1]
  ------------------
  891|      2|		return SC_SUCCESS;
  ------------------
  |  |   28|      2|#define SC_SUCCESS				0
  ------------------
  892|      1|	if (n_hist > atr_len)
  ------------------
  |  Branch (892:6): [True: 1, False: 0]
  ------------------
  893|      1|		n_hist = atr_len;
  894|      1|	reader->atr_info.hist_bytes_len = n_hist;
  895|      1|	reader->atr_info.hist_bytes = p;
  896|      1|	return SC_SUCCESS;
  ------------------
  |  |   28|      1|#define SC_SUCCESS				0
  ------------------
  897|      3|}
sc_mem_clear:
  930|    346|{
  931|    346|	if (len > 0)   {
  ------------------
  |  Branch (931:6): [True: 346, False: 0]
  ------------------
  932|       |#ifdef HAVE_MEMSET_S
  933|       |		memset_s(ptr, len, 0, len);
  934|       |#elif _WIN32
  935|       |		SecureZeroMemory(ptr, len);
  936|       |#elif HAVE_EXPLICIT_BZERO
  937|       |		explicit_bzero(ptr, len);
  938|       |#elif ENABLE_OPENSSL
  939|       |		OPENSSL_cleanse(ptr, len);
  940|       |#else
  941|       |		memset(ptr, 0, len);
  942|       |#endif
  943|    346|	}
  944|    346|}
sc_compacttlv_find_tag:
 1058|      2|{
 1059|      2|	if (buf != NULL) {
  ------------------
  |  Branch (1059:6): [True: 2, False: 0]
  ------------------
 1060|      2|		size_t idx;
 1061|      2|		u8 plain_tag = tag & 0xF0;
 1062|      2|		size_t expected_len = tag & 0x0F;
 1063|       |
 1064|      4|		for (idx = 0; idx < len; idx++) {
  ------------------
  |  Branch (1064:17): [True: 2, False: 2]
  ------------------
 1065|      2|			u8 ctag = buf[idx] & 0xF0;
 1066|      2|			size_t ctag_len = buf[idx] & 0x0F;
 1067|      2|			if (ctag == plain_tag && idx + ctag_len < len &&
  ------------------
  |  Branch (1067:8): [True: 0, False: 2]
  |  Branch (1067:29): [True: 0, False: 0]
  ------------------
 1068|      0|					(expected_len == 0 || expected_len == ctag_len)) {
  ------------------
  |  Branch (1068:7): [True: 0, False: 0]
  |  Branch (1068:28): [True: 0, False: 0]
  ------------------
 1069|      0|				if (outlen != NULL)
  ------------------
  |  Branch (1069:9): [True: 0, False: 0]
  ------------------
 1070|      0|					*outlen = ctag_len;
 1071|      0|				return buf + (idx + 1);
 1072|      0|			}
 1073|      2|			idx += ctag_len;
 1074|      2|		}
 1075|      2|	}
 1076|      2|	return NULL;
 1077|      2|}
sc_mutex_create:
 1082|    346|{
 1083|    346|	if (ctx == NULL)
  ------------------
  |  Branch (1083:6): [True: 0, False: 346]
  ------------------
 1084|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
 1085|    346|	if (ctx->thread_ctx != NULL && ctx->thread_ctx->create_mutex != NULL)
  ------------------
  |  Branch (1085:6): [True: 0, False: 346]
  |  Branch (1085:33): [True: 0, False: 0]
  ------------------
 1086|      0|		return ctx->thread_ctx->create_mutex(mutex);
 1087|    346|	else
 1088|    346|		return SC_SUCCESS;
  ------------------
  |  |   28|    346|#define SC_SUCCESS				0
  ------------------
 1089|    346|}
sc_mutex_lock:
 1092|  4.88k|{
 1093|  4.88k|	if (ctx == NULL)
  ------------------
  |  Branch (1093:6): [True: 0, False: 4.88k]
  ------------------
 1094|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
 1095|  4.88k|	if (ctx->thread_ctx != NULL && ctx->thread_ctx->lock_mutex != NULL)
  ------------------
  |  Branch (1095:6): [True: 0, False: 4.88k]
  |  Branch (1095:33): [True: 0, False: 0]
  ------------------
 1096|      0|		return ctx->thread_ctx->lock_mutex(mutex);
 1097|  4.88k|	else
 1098|  4.88k|		return SC_SUCCESS;
  ------------------
  |  |   28|  4.88k|#define SC_SUCCESS				0
  ------------------
 1099|  4.88k|}
sc_mutex_unlock:
 1102|  4.88k|{
 1103|  4.88k|	if (ctx == NULL)
  ------------------
  |  Branch (1103:6): [True: 0, False: 4.88k]
  ------------------
 1104|      0|		return SC_ERROR_INVALID_ARGUMENTS;
  ------------------
  |  |   73|      0|#define SC_ERROR_INVALID_ARGUMENTS		-1300
  ------------------
 1105|  4.88k|	if (ctx->thread_ctx != NULL && ctx->thread_ctx->unlock_mutex != NULL)
  ------------------
  |  Branch (1105:6): [True: 0, False: 4.88k]
  |  Branch (1105:33): [True: 0, False: 0]
  ------------------
 1106|      0|		return ctx->thread_ctx->unlock_mutex(mutex);
 1107|  4.88k|	else
 1108|  4.88k|		return SC_SUCCESS;
  ------------------
  |  |   28|  4.88k|#define SC_SUCCESS				0
  ------------------
 1109|  4.88k|}

scconf_parse_token:
  251|  2.95k|{
  252|  2.95k|	scconf_item *item;
  253|  2.95k|	size_t len;
  254|       |
  255|  2.95k|	if (parser->error) {
  ------------------
  |  Branch (255:6): [True: 0, False: 2.95k]
  ------------------
  256|       |		/* fatal error */
  257|      0|		return;
  258|      0|	}
  259|  2.95k|	switch (token_type) {
  ------------------
  |  Branch (259:10): [True: 2.95k, False: 0]
  ------------------
  260|      0|	case TOKEN_TYPE_NEWLINE:
  ------------------
  |  |   32|      0|#define TOKEN_TYPE_NEWLINE	1
  ------------------
  |  Branch (260:2): [True: 0, False: 2.95k]
  ------------------
  261|      0|		parser->line++;
  262|      0|		if (parser->last_token_type != TOKEN_TYPE_NEWLINE) {
  ------------------
  |  |   32|      0|#define TOKEN_TYPE_NEWLINE	1
  ------------------
  |  Branch (262:7): [True: 0, False: 0]
  ------------------
  263|      0|			break;
  264|      0|		}
  265|       |		/* fall through - treat empty lines as comments */
  266|      0|	case TOKEN_TYPE_COMMENT:
  ------------------
  |  |   31|      0|#define TOKEN_TYPE_COMMENT	0
  ------------------
  |  Branch (266:2): [True: 0, False: 2.95k]
  ------------------
  267|      0|		item = scconf_item_add_internal(parser, SCCONF_ITEM_TYPE_COMMENT);
  ------------------
  |  |   42|      0|#define SCCONF_ITEM_TYPE_COMMENT	0	/* key = NULL, comment */
  ------------------
  268|      0|		if (!item) {
  ------------------
  |  Branch (268:7): [True: 0, False: 0]
  ------------------
  269|      0|			return;
  270|      0|		}
  271|      0|		item->value.comment = token ? strdup(token) : NULL;
  ------------------
  |  Branch (271:25): [True: 0, False: 0]
  ------------------
  272|      0|		break;
  273|  1.47k|	case TOKEN_TYPE_STRING:
  ------------------
  |  |   33|  1.47k|#define TOKEN_TYPE_STRING	2
  ------------------
  |  Branch (273:2): [True: 1.47k, False: 1.47k]
  ------------------
  274|  1.47k|		{
  275|  1.47k|			char *stoken = NULL;
  276|       |
  277|  1.47k|			if ((parser->state & (STATE_VALUE | STATE_SET)) ==
  ------------------
  |  |   37|  1.47k|#define STATE_VALUE	0x02
  ------------------
              			if ((parser->state & (STATE_VALUE | STATE_SET)) ==
  ------------------
  |  |   38|  1.47k|#define STATE_SET	0x10
  ------------------
  |  Branch (277:8): [True: 0, False: 1.47k]
  ------------------
  278|  1.47k|			    (STATE_VALUE | STATE_SET)) {
  ------------------
  |  |   37|  1.47k|#define STATE_VALUE	0x02
  ------------------
              			    (STATE_VALUE | STATE_SET)) {
  ------------------
  |  |   38|  1.47k|#define STATE_SET	0x10
  ------------------
  279|      0|				scconf_parse_warning_expect(parser, ";");
  280|      0|				scconf_parse_reset_state(parser);
  281|      0|			}
  282|  1.47k|			if (token && *token == '"') {
  ------------------
  |  Branch (282:8): [True: 1.47k, False: 0]
  |  Branch (282:17): [True: 0, False: 1.47k]
  ------------------
  283|       |				/* quoted string, remove them */
  284|      0|				token++;
  285|      0|				len = strlen(token);
  286|      0|				if (len < 1 || token[len - 1] != '"') {
  ------------------
  |  Branch (286:9): [True: 0, False: 0]
  |  Branch (286:20): [True: 0, False: 0]
  ------------------
  287|      0|					scconf_parse_warning_expect(parser, "\"");
  288|      0|				} else {
  289|       |					/* stoken */
  290|      0|					stoken = strdup(token);
  291|      0|					if (stoken) {
  ------------------
  |  Branch (291:10): [True: 0, False: 0]
  ------------------
  292|      0|						stoken[len - 1] = '\0';
  293|      0|					}
  294|      0|				}
  295|      0|			}
  296|  1.47k|			if (!stoken) {
  ------------------
  |  Branch (296:8): [True: 1.47k, False: 0]
  ------------------
  297|  1.47k|				stoken = token ? strdup(token) : NULL;
  ------------------
  |  Branch (297:14): [True: 1.47k, False: 0]
  ------------------
  298|  1.47k|			}
  299|  1.47k|			if (parser->state == 0) {
  ------------------
  |  Branch (299:8): [True: 590, False: 885]
  ------------------
  300|       |				/* key */
  301|    590|				parser->key = stoken ? strdup(stoken) : NULL;
  ------------------
  |  Branch (301:19): [True: 590, False: 0]
  ------------------
  302|    590|				parser->state = STATE_NAME;
  ------------------
  |  |   36|    590|#define STATE_NAME	0x01
  ------------------
  303|    885|			} else if (parser->state == STATE_NAME) {
  ------------------
  |  |   36|    885|#define STATE_NAME	0x01
  ------------------
  |  Branch (303:15): [True: 295, False: 590]
  ------------------
  304|       |				/* name */
  305|    295|				parser->state |= STATE_SET;
  ------------------
  |  |   38|    295|#define STATE_SET	0x10
  ------------------
  306|    295|				scconf_list_add(&parser->name, stoken);
  307|    590|			} else if (parser->state == STATE_VALUE && parser->current_item->type == SCCONF_ITEM_TYPE_VALUE) {
  ------------------
  |  |   37|  1.18k|#define STATE_VALUE	0x02
  ------------------
              			} else if (parser->state == STATE_VALUE && parser->current_item->type == SCCONF_ITEM_TYPE_VALUE) {
  ------------------
  |  |   44|    590|#define SCCONF_ITEM_TYPE_VALUE		2	/* key = key, list */
  ------------------
  |  Branch (307:15): [True: 590, False: 0]
  |  Branch (307:47): [True: 590, False: 0]
  ------------------
  308|       |				/* value */
  309|    590|				parser->state |= STATE_SET;
  ------------------
  |  |   38|    590|#define STATE_SET	0x10
  ------------------
  310|    590|				scconf_list_add(&parser->current_item->value.list,
  311|    590|						      stoken);
  312|    590|			} else {
  313|       |				/* error */
  314|      0|				scconf_parse_error_not_expect(parser, stoken);
  315|      0|			}
  316|  1.47k|			if (stoken) {
  ------------------
  |  Branch (316:8): [True: 1.47k, False: 0]
  ------------------
  317|  1.47k|				free(stoken);
  318|  1.47k|			}
  319|  1.47k|			stoken = NULL;
  320|  1.47k|		}
  321|  1.47k|		break;
  322|  1.47k|	case TOKEN_TYPE_PUNCT:
  ------------------
  |  |   34|  1.47k|#define TOKEN_TYPE_PUNCT	3
  ------------------
  |  Branch (322:2): [True: 1.47k, False: 1.47k]
  ------------------
  323|  1.47k|		switch (*token) {
  324|    295|		case '{':
  ------------------
  |  Branch (324:3): [True: 295, False: 1.18k]
  ------------------
  325|    295|			if ((parser->state & STATE_NAME) == 0) {
  ------------------
  |  |   36|    295|#define STATE_NAME	0x01
  ------------------
  |  Branch (325:8): [True: 0, False: 295]
  ------------------
  326|      0|				scconf_parse_error_not_expect(parser, "{");
  327|      0|				break;
  328|      0|			}
  329|    295|			parser->nested_blocks++;
  330|    295|			scconf_block_add_internal(parser);
  331|    295|			scconf_parse_reset_state(parser);
  332|    295|			break;
  333|    295|		case '}':
  ------------------
  |  Branch (333:3): [True: 295, False: 1.18k]
  ------------------
  334|    295|			parser->nested_blocks--;
  335|    295|			if (parser->state != 0) {
  ------------------
  |  Branch (335:8): [True: 0, False: 295]
  ------------------
  336|      0|				if ((parser->state & STATE_VALUE) == 0 ||
  ------------------
  |  |   37|      0|#define STATE_VALUE	0x02
  ------------------
  |  Branch (336:9): [True: 0, False: 0]
  ------------------
  337|      0|				    (parser->state & STATE_SET) == 0) {
  ------------------
  |  |   38|      0|#define STATE_SET	0x10
  ------------------
  |  Branch (337:9): [True: 0, False: 0]
  ------------------
  338|      0|					scconf_parse_error_not_expect(parser,
  339|      0|								      "}");
  340|      0|					break;
  341|      0|				}
  342|       |				/* foo = bar } */
  343|      0|				scconf_parse_warning_expect(parser, ";");
  344|      0|				scconf_parse_reset_state(parser);
  345|      0|			}
  346|    295|			if (!parser->block->parent) {
  ------------------
  |  Branch (346:8): [True: 0, False: 295]
  ------------------
  347|       |				/* too many '}' */
  348|      0|				scconf_parse_error(parser,
  349|      0|						   "missing matching '{'");
  350|      0|				break;
  351|      0|			}
  352|    295|			scconf_parse_parent(parser);
  353|    295|			break;
  354|    295|		case ',':
  ------------------
  |  Branch (354:3): [True: 295, False: 1.18k]
  ------------------
  355|    295|			if ((parser->state & (STATE_NAME | STATE_VALUE)) == 0) {
  ------------------
  |  |   36|    295|#define STATE_NAME	0x01
  ------------------
              			if ((parser->state & (STATE_NAME | STATE_VALUE)) == 0) {
  ------------------
  |  |   37|    295|#define STATE_VALUE	0x02
  ------------------
  |  Branch (355:8): [True: 0, False: 295]
  ------------------
  356|      0|				scconf_parse_error_not_expect(parser, ",");
  357|      0|			}
  358|    295|			parser->state &= ~STATE_SET;
  ------------------
  |  |   38|    295|#define STATE_SET	0x10
  ------------------
  359|    295|			break;
  360|    295|		case '=':
  ------------------
  |  Branch (360:3): [True: 295, False: 1.18k]
  ------------------
  361|    295|			if ((parser->state & STATE_NAME) == 0) {
  ------------------
  |  |   36|    295|#define STATE_NAME	0x01
  ------------------
  |  Branch (361:8): [True: 0, False: 295]
  ------------------
  362|      0|				scconf_parse_error_not_expect(parser, "=");
  363|      0|				break;
  364|      0|			}
  365|    295|			scconf_item_add_internal(parser, SCCONF_ITEM_TYPE_VALUE);
  ------------------
  |  |   44|    295|#define SCCONF_ITEM_TYPE_VALUE		2	/* key = key, list */
  ------------------
  366|    295|			parser->state = STATE_VALUE;
  ------------------
  |  |   37|    295|#define STATE_VALUE	0x02
  ------------------
  367|    295|			break;
  368|    295|		case ';':
  ------------------
  |  Branch (368:3): [True: 295, False: 1.18k]
  ------------------
  369|    295|			scconf_parse_reset_state(parser);
  370|    295|			break;
  371|      0|		default:
  ------------------
  |  Branch (371:3): [True: 0, False: 1.47k]
  ------------------
  372|      0|			snprintf(parser->emesg, sizeof(parser->emesg),
  373|      0|				"Line %d: bad token ignoring\n",
  374|      0|				parser->line);
  375|  1.47k|		}
  376|  1.47k|		break;
  377|  2.95k|	}
  378|       |
  379|  2.95k|	parser->last_token_type = token_type;
  380|  2.95k|}
scconf_parse:
  383|    295|{
  384|    295|	static char buffer[256];
  385|    295|	scconf_parser p;
  386|    295|	int r = 1;
  387|       |
  388|    295|	memset(&p, 0, sizeof(p));
  389|    295|	p.config = config;
  390|    295|	p.block = config->root;
  391|    295|	p.line = 1;
  392|    295|	p.nested_blocks = 0;
  393|       |
  394|    295|	if (!scconf_lex_parse(&p, config->filename)) {
  ------------------
  |  Branch (394:6): [True: 295, False: 0]
  ------------------
  395|    295|		snprintf(buffer, sizeof(buffer),
  396|    295|				"Unable to open \"%s\": %s",
  397|    295|				config->filename, strerror(errno));
  398|    295|		r = -1;
  399|    295|	} else if (p.error) {
  ------------------
  |  Branch (399:13): [True: 0, False: 0]
  ------------------
  400|      0|		strlcpy(buffer, p.emesg, sizeof(buffer));
  ------------------
  |  |   43|      0|#define strlcpy _strlcpy
  ------------------
  401|      0|		r = 0;
  402|      0|	} else {
  403|      0|		r = 1;
  404|      0|	}
  405|       |
  406|    295|	if (r <= 0)
  ------------------
  |  Branch (406:6): [True: 295, False: 0]
  ------------------
  407|    295|		config->errmsg = buffer;
  408|    295|	return r;
  409|    295|}
scconf_parse_string:
  412|    295|{
  413|    295|	static char buffer[256];
  414|    295|	scconf_parser p;
  415|    295|	int r;
  416|       |
  417|    295|	memset(&p, 0, sizeof(p));
  418|    295|	p.config = config;
  419|    295|	p.block = config->root;
  420|    295|	p.line = 1;
  421|    295|	p.nested_blocks = 0;
  422|       |
  423|    295|	if (!scconf_lex_parse_string(&p, string)) {
  ------------------
  |  Branch (423:6): [True: 0, False: 295]
  ------------------
  424|      0|		snprintf(buffer, sizeof(buffer),
  425|      0|				"Failed to parse configuration string");
  426|      0|		r = -1;
  427|    295|	} else if (p.error) {
  ------------------
  |  Branch (427:13): [True: 0, False: 295]
  ------------------
  428|      0|		strlcpy(buffer, p.emesg, sizeof(buffer));
  ------------------
  |  |   43|      0|#define strlcpy _strlcpy
  ------------------
  429|      0|		r = 0;
  430|    295|	} else {
  431|    295|		r = 1;
  432|    295|	}
  433|       |
  434|    295|	scconf_parse_reset_state(&p);
  435|       |
  436|    295|	if (r <= 0)
  ------------------
  |  Branch (436:6): [True: 0, False: 295]
  ------------------
  437|      0|		config->errmsg = buffer;
  438|    295|	return r;
  439|    295|}
parse.c:scconf_item_add_internal:
   95|    590|{
   96|    590|	scconf_item *item;
   97|       |
   98|    590|	if (type == SCCONF_ITEM_TYPE_VALUE) {
  ------------------
  |  |   44|    590|#define SCCONF_ITEM_TYPE_VALUE		2	/* key = key, list */
  ------------------
  |  Branch (98:6): [True: 295, False: 295]
  ------------------
   99|       |		/* if item with same key already exists, use it */
  100|    295|		item = scconf_item_find(parser);
  101|    295|		if (item) {
  ------------------
  |  Branch (101:7): [True: 0, False: 295]
  ------------------
  102|      0|			free(parser->key);
  103|      0|			parser->key = NULL;
  104|      0|			parser->current_item = item;
  105|      0|			return item;
  106|      0|		}
  107|    295|	}
  108|    590|	item = calloc(1, sizeof(scconf_item));
  109|    590|	if (!item) {
  ------------------
  |  Branch (109:6): [True: 0, False: 590]
  ------------------
  110|      0|		return NULL;
  111|      0|	}
  112|    590|	item->type = type;
  113|       |
  114|    590|	item->key = parser->key;
  115|    590|	parser->key = NULL;
  116|       |
  117|    590|	if (parser->last_item) {
  ------------------
  |  Branch (117:6): [True: 0, False: 590]
  ------------------
  118|      0|		parser->last_item->next = item;
  119|    590|	} else {
  120|    590|		parser->block->items = item;
  121|    590|	}
  122|    590|	parser->current_item = parser->last_item = item;
  123|    590|	return item;
  124|    590|}
parse.c:scconf_item_find:
   81|    295|{
   82|    295|	scconf_item *item;
   83|       |
   84|    295|	for (item = parser->block->items; item; item = item->next) {
  ------------------
  |  Branch (84:36): [True: 0, False: 295]
  ------------------
   85|      0|		if (item && item->type == SCCONF_ITEM_TYPE_VALUE
  ------------------
  |  |   44|      0|#define SCCONF_ITEM_TYPE_VALUE		2	/* key = key, list */
  ------------------
  |  Branch (85:7): [True: 0, False: 0]
  |  Branch (85:15): [True: 0, False: 0]
  ------------------
   86|      0|			   	&& item->key && parser->key
  ------------------
  |  Branch (86:11): [True: 0, False: 0]
  |  Branch (86:24): [True: 0, False: 0]
  ------------------
   87|      0|			   	&& strcasecmp(item->key, parser->key) == 0) {
  ------------------
  |  Branch (87:11): [True: 0, False: 0]
  ------------------
   88|      0|			return item;
   89|      0|		}
   90|      0|	}
   91|    295|	return item;
   92|    295|}
parse.c:scconf_block_add_internal:
  173|    295|{
  174|    295|	scconf_block *block;
  175|    295|	scconf_item *item;
  176|       |
  177|    295|	item = scconf_item_add_internal(parser, SCCONF_ITEM_TYPE_BLOCK);
  ------------------
  |  |   43|    295|#define SCCONF_ITEM_TYPE_BLOCK		1	/* key = key, block */
  ------------------
  178|    295|	if (!item) {
  ------------------
  |  Branch (178:6): [True: 0, False: 295]
  ------------------
  179|      0|		return;
  180|      0|	}
  181|       |
  182|    295|	block = calloc(1, sizeof(scconf_block));
  183|    295|	if (!block) {
  ------------------
  |  Branch (183:6): [True: 0, False: 295]
  ------------------
  184|      0|		return;
  185|      0|	}
  186|    295|	block->parent = parser->block;
  187|    295|	item->value.block = block;
  188|       |
  189|    295|	if (!parser->name) {
  ------------------
  |  Branch (189:6): [True: 0, False: 295]
  ------------------
  190|      0|		scconf_list_add(&parser->name, "");
  191|      0|	}
  192|    295|	block->name = parser->name;
  193|    295|	parser->name = NULL;
  194|       |
  195|    295|	parser->block = block;
  196|       |	parser->last_item = NULL;
  197|    295|}
parse.c:scconf_parse_reset_state:
  231|    885|{
  232|    885|	if (parser) {
  ------------------
  |  Branch (232:6): [True: 885, False: 0]
  ------------------
  233|    885|		if (parser->key) {
  ------------------
  |  Branch (233:7): [True: 0, False: 885]
  ------------------
  234|      0|			free(parser->key);
  235|      0|		}
  236|    885|		scconf_list_destroy(parser->name);
  237|       |
  238|    885|		parser->key = NULL;
  239|       |		parser->name = NULL;
  240|    885|		parser->state = 0;
  241|    885|	}
  242|    885|}
parse.c:scconf_parse_parent:
  219|    295|{
  220|    295|	parser->block = parser->block->parent;
  221|       |
  222|    295|	parser->last_item = parser->block->items;
  223|    295|	if (parser->last_item) {
  ------------------
  |  Branch (223:6): [True: 295, False: 0]
  ------------------
  224|    295|		while (parser->last_item->next) {
  ------------------
  |  Branch (224:10): [True: 0, False: 295]
  ------------------
  225|      0|			parser->last_item = parser->last_item->next;
  226|      0|		}
  227|    295|	}
  228|    295|}

scconf_new:
   37|    295|{
   38|    295|	scconf_context *config;
   39|       |
   40|    295|	config = calloc(1, sizeof(scconf_context));
   41|    295|	if (!config) {
  ------------------
  |  Branch (41:6): [True: 0, False: 295]
  ------------------
   42|      0|		return NULL;
   43|      0|	}
   44|    295|	config->filename = filename ? strdup(filename) : NULL;
  ------------------
  |  Branch (44:21): [True: 295, False: 0]
  ------------------
   45|    295|	config->root = calloc(1, sizeof(scconf_block));
   46|    295|	if (!config->root) {
  ------------------
  |  Branch (46:6): [True: 0, False: 295]
  ------------------
   47|      0|		if (config->filename) {
  ------------------
  |  Branch (47:7): [True: 0, False: 0]
  ------------------
   48|      0|			free(config->filename);
   49|      0|		}
   50|      0|		free(config);
   51|      0|		return NULL;
   52|      0|	}
   53|    295|	return config;
   54|    295|}
scconf_free:
   57|    295|{
   58|    295|	if (config) {
  ------------------
  |  Branch (58:6): [True: 295, False: 0]
  ------------------
   59|    295|		scconf_block_destroy(config->root);
   60|    295|		if (config->filename) {
  ------------------
  |  Branch (60:7): [True: 295, False: 0]
  ------------------
   61|    295|			free(config->filename);
   62|    295|		}
   63|    295|		free(config);
   64|    295|	}
   65|    295|}
scconf_find_blocks:
   87|  14.6k|{
   88|  14.6k|	scconf_block **blocks = NULL, **tmp;
   89|  14.6k|	int alloc_size, size;
   90|  14.6k|	scconf_item *item;
   91|       |
   92|  14.6k|	if (!block) {
  ------------------
  |  Branch (92:6): [True: 885, False: 13.8k]
  ------------------
   93|    885|		block = config->root;
   94|    885|	}
   95|  14.6k|	if (!item_name) {
  ------------------
  |  Branch (95:6): [True: 0, False: 14.6k]
  ------------------
   96|      0|		return NULL;
   97|      0|	}
   98|  14.6k|	size = 0;
   99|  14.6k|	alloc_size = 10;
  100|  14.6k|	tmp = (scconf_block **) realloc(blocks, sizeof(scconf_block *) * alloc_size);
  101|  14.6k|	if (!tmp) {
  ------------------
  |  Branch (101:6): [True: 0, False: 14.6k]
  ------------------
  102|      0|		free(blocks);
  103|      0|		return NULL;
  104|      0|	}
  105|  14.6k|	blocks = tmp;
  106|       |
  107|  29.3k|	for (item = block->items; item; item = item->next) {
  ------------------
  |  Branch (107:28): [True: 14.6k, False: 14.6k]
  ------------------
  108|  14.6k|		if (item->type == SCCONF_ITEM_TYPE_BLOCK &&
  ------------------
  |  |   43|  29.3k|#define SCCONF_ITEM_TYPE_BLOCK		1	/* key = key, block */
  ------------------
  |  Branch (108:7): [True: 885, False: 13.8k]
  ------------------
  109|    885|		    strcasecmp(item_name, item->key) == 0) {
  ------------------
  |  Branch (109:7): [True: 885, False: 0]
  ------------------
  110|    885|			if (!item->value.block)
  ------------------
  |  Branch (110:8): [True: 0, False: 885]
  ------------------
  111|      0|				continue;
  112|    885|			if (key && strcasecmp(key, item->value.block->name->data)) {
  ------------------
  |  Branch (112:8): [True: 885, False: 0]
  |  Branch (112:15): [True: 590, False: 295]
  ------------------
  113|    590|				continue;
  114|    590|			}
  115|    295|			if (size + 1 >= alloc_size) {
  ------------------
  |  Branch (115:8): [True: 0, False: 295]
  ------------------
  116|      0|				alloc_size *= 2;
  117|      0|				tmp = (scconf_block **) realloc(blocks, sizeof(scconf_block *) * alloc_size);
  118|      0|				if (!tmp) {
  ------------------
  |  Branch (118:9): [True: 0, False: 0]
  ------------------
  119|      0|					free(blocks);
  120|      0|					return NULL;
  121|      0|				}
  122|      0|				blocks = tmp;
  123|      0|			}
  124|    295|			blocks[size++] = item->value.block;
  125|    295|		}
  126|  14.6k|	}
  127|  14.6k|	blocks[size] = NULL;
  128|  14.6k|	return blocks;
  129|  14.6k|}
scconf_find_list:
  132|  2.30k|{
  133|  2.30k|	scconf_item *item;
  134|       |
  135|  2.30k|	if (!block)
  ------------------
  |  Branch (135:6): [True: 244, False: 2.06k]
  ------------------
  136|    244|		return NULL;
  137|       |
  138|  3.83k|	for (item = block->items; item; item = item->next)
  ------------------
  |  Branch (138:28): [True: 2.06k, False: 1.77k]
  ------------------
  139|  2.06k|		if (item->type == SCCONF_ITEM_TYPE_VALUE && strcasecmp(option, item->key) == 0)
  ------------------
  |  |   44|  4.13k|#define SCCONF_ITEM_TYPE_VALUE		2	/* key = key, list */
  ------------------
  |  Branch (139:7): [True: 2.06k, False: 0]
  |  Branch (139:47): [True: 295, False: 1.77k]
  ------------------
  140|    295|			return item->value.list;
  141|  1.77k|	return NULL;
  142|  2.06k|}
scconf_get_str:
  145|    834|{
  146|    834|	const scconf_list *list;
  147|       |
  148|    834|	list = scconf_find_list(block, option);
  149|    834|	if (!list)
  ------------------
  |  Branch (149:6): [True: 834, False: 0]
  ------------------
  150|    834|		return def;
  151|       |
  152|       |	/* ignore non 'auto-configured' values */
  153|      0|	if (*list->data == '@' && *(list->data + strlen(list->data) - 1) == '@')
  ------------------
  |  Branch (153:6): [True: 0, False: 0]
  |  Branch (153:28): [True: 0, False: 0]
  ------------------
  154|      0|		return def;
  155|       |
  156|      0|	return list->data;
  157|      0|}
scconf_get_int:
  160|    295|{
  161|    295|	const scconf_list *list;
  162|    295|	long res;
  163|       |
  164|    295|	list = scconf_find_list(block, option);
  165|    295|	if (!list) {
  ------------------
  |  Branch (165:6): [True: 295, False: 0]
  ------------------
  166|    295|		return def;
  167|    295|	}
  168|      0|	res = strtol(list->data, NULL, 0);
  169|      0|	if (res <= INT_MAX) {
  ------------------
  |  Branch (169:6): [True: 0, False: 0]
  ------------------
  170|      0|		return (int)res;
  171|      0|	}
  172|      0|	return def;
  173|      0|}
scconf_get_bool:
  176|    885|{
  177|    885|	const scconf_list *list;
  178|       |
  179|    885|	list = scconf_find_list(block, option);
  180|    885|	if (!list) {
  ------------------
  |  Branch (180:6): [True: 885, False: 0]
  ------------------
  181|    885|		return def;
  182|    885|	}
  183|      0|	return toupper((int) *list->data) == 'T' || toupper((int) *list->data) == 'Y';
  ------------------
  |  Branch (183:9): [True: 0, False: 0]
  |  Branch (183:46): [True: 0, False: 0]
  ------------------
  184|    885|}
scconf_item_destroy:
  257|    590|{
  258|    590|	scconf_item *next;
  259|       |
  260|  1.18k|	while (item) {
  ------------------
  |  Branch (260:9): [True: 590, False: 590]
  ------------------
  261|    590|		next = item->next;
  262|       |
  263|    590|		switch (item->type) {
  ------------------
  |  Branch (263:11): [True: 590, False: 0]
  ------------------
  264|      0|		case SCCONF_ITEM_TYPE_COMMENT:
  ------------------
  |  |   42|      0|#define SCCONF_ITEM_TYPE_COMMENT	0	/* key = NULL, comment */
  ------------------
  |  Branch (264:3): [True: 0, False: 590]
  ------------------
  265|      0|			if (item->value.comment) {
  ------------------
  |  Branch (265:8): [True: 0, False: 0]
  ------------------
  266|      0|				free(item->value.comment);
  267|      0|			}
  268|      0|			item->value.comment = NULL;
  269|      0|			break;
  270|    295|		case SCCONF_ITEM_TYPE_BLOCK:
  ------------------
  |  |   43|    295|#define SCCONF_ITEM_TYPE_BLOCK		1	/* key = key, block */
  ------------------
  |  Branch (270:3): [True: 295, False: 295]
  ------------------
  271|    295|			scconf_block_destroy(item->value.block);
  272|    295|			break;
  273|    295|		case SCCONF_ITEM_TYPE_VALUE:
  ------------------
  |  |   44|    295|#define SCCONF_ITEM_TYPE_VALUE		2	/* key = key, list */
  ------------------
  |  Branch (273:3): [True: 295, False: 295]
  ------------------
  274|    295|			scconf_list_destroy(item->value.list);
  275|    295|			break;
  276|    590|		}
  277|       |
  278|    590|		if (item->key) {
  ------------------
  |  Branch (278:7): [True: 590, False: 0]
  ------------------
  279|    590|			free(item->key);
  280|    590|		}
  281|       |		item->key = NULL;
  282|    590|		free(item);
  283|    590|		item = next;
  284|    590|	}
  285|    590|}
scconf_block_destroy:
  310|    590|{
  311|    590|	if (block) {
  ------------------
  |  Branch (311:6): [True: 590, False: 0]
  ------------------
  312|    590|		scconf_list_destroy(block->name);
  313|    590|		scconf_item_destroy(block->items);
  314|    590|		free(block);
  315|    590|	}
  316|    590|}
scconf_list_add:
  319|    885|{
  320|    885|	scconf_list *rec, **tmp;
  321|       |
  322|    885|	rec = calloc(1, sizeof(scconf_list));
  323|    885|	if (!rec) {
  ------------------
  |  Branch (323:6): [True: 0, False: 885]
  ------------------
  324|      0|		return NULL;
  325|      0|	}
  326|    885|	rec->data = value ? strdup(value) : NULL;
  ------------------
  |  Branch (326:14): [True: 885, False: 0]
  ------------------
  327|       |
  328|    885|	if (!*list) {
  ------------------
  |  Branch (328:6): [True: 590, False: 295]
  ------------------
  329|    590|		*list = rec;
  330|    590|	} else {
  331|    590|		for (tmp = list; *tmp; tmp = &(*tmp)->next);
  ------------------
  |  Branch (331:20): [True: 295, False: 295]
  ------------------
  332|    295|		*tmp = rec;
  333|    295|	}
  334|    885|	return rec;
  335|    885|}
scconf_list_destroy:
  350|  1.77k|{
  351|  1.77k|	scconf_list *next;
  352|       |
  353|  2.65k|	while (list) {
  ------------------
  |  Branch (353:9): [True: 885, False: 1.77k]
  ------------------
  354|    885|		next = list->next;
  355|    885|		if (list->data) {
  ------------------
  |  Branch (355:7): [True: 885, False: 0]
  ------------------
  356|    885|			free(list->data);
  357|    885|		}
  358|    885|		free(list);
  359|    885|		list = next;
  360|    885|	}
  361|  1.77k|}

scconf_lex_parse:
  181|    295|{
  182|    295|	FILE *fp;
  183|    295|	BUFHAN bhan;
  184|    295|	int ret;
  185|       |
  186|    295|	fp = fopen(filename, "r");
  187|    295|	if (!fp) {
  ------------------
  |  Branch (187:6): [True: 295, False: 0]
  ------------------
  188|    295|		parser->error = 1;
  189|    295|		snprintf(parser->emesg, sizeof(parser->emesg),
  190|    295|			 "File %s can't be opened\n", filename);
  191|    295|		return 0;
  192|    295|	}
  193|      0|	buf_init(&bhan, fp, (char *) NULL);
  194|      0|	ret = scconf_lex_engine(parser, &bhan);
  195|      0|	fclose(fp);
  196|      0|	return ret;
  197|    295|}
scconf_lex_parse_string:
  200|    295|{
  201|    295|	BUFHAN bhan;
  202|    295|	int ret;
  203|       |
  204|       |	buf_init(&bhan, (FILE *) NULL, string);
  205|    295|	ret = scconf_lex_engine(parser, &bhan);
  206|    295|	return ret;
  207|    295|}
sclex.c:buf_init:
   44|    295|{
   45|    295|	bp->fp = fp;
   46|    295|	bp->saved_char = 0;
   47|    295|	bp->buf = malloc(256);
   48|    295|	if (bp->buf) {
  ------------------
  |  Branch (48:6): [True: 295, False: 0]
  ------------------
   49|    295|		bp->bufmax = 256;
   50|    295|		bp->buf[0] = '\0';
   51|    295|	} else
   52|      0|		bp->bufmax = 0;
   53|    295|	bp->bufcur = 0;
   54|    295|	bp->saved_string = saved_string;
   55|    295|}
sclex.c:scconf_lex_engine:
  126|    295|{
  127|    295|	int this_char;
  128|       |
  129|  5.31k|	while (1) {
  ------------------
  |  Branch (129:9): [True: 5.31k, Folded]
  ------------------
  130|  5.31k|		switch (this_char = buf_nextch(bp)) {
  131|      0|		case '#':
  ------------------
  |  Branch (131:3): [True: 0, False: 5.31k]
  ------------------
  132|       |			/* comment till end of line */
  133|      0|			buf_eat_till(bp, '#', "\r\n");
  134|      0|			scconf_parse_token(parser, TOKEN_TYPE_COMMENT, bp->buf);
  ------------------
  |  |   31|      0|#define TOKEN_TYPE_COMMENT	0
  ------------------
  135|      0|			buf_zero(bp);
  136|      0|			continue;
  137|      0|		case '\n':
  ------------------
  |  Branch (137:3): [True: 0, False: 5.31k]
  ------------------
  138|      0|			scconf_parse_token(parser, TOKEN_TYPE_NEWLINE, NULL);
  ------------------
  |  |   32|      0|#define TOKEN_TYPE_NEWLINE	1
  ------------------
  139|      0|			continue;
  140|  2.06k|		case ' ':
  ------------------
  |  Branch (140:3): [True: 2.06k, False: 3.24k]
  ------------------
  141|  2.06k|		case '\t':
  ------------------
  |  Branch (141:3): [True: 0, False: 5.31k]
  ------------------
  142|  2.06k|		case '\r':
  ------------------
  |  Branch (142:3): [True: 0, False: 5.31k]
  ------------------
  143|       |			/* eat up whitespace */
  144|  2.06k|			continue;
  145|    295|		case ',':
  ------------------
  |  Branch (145:3): [True: 295, False: 5.01k]
  ------------------
  146|    590|		case '{':
  ------------------
  |  Branch (146:3): [True: 295, False: 5.01k]
  ------------------
  147|    590|			if (parser->nested_blocks >= DEPTH_LIMIT) {
  ------------------
  |  |   36|    590|#define DEPTH_LIMIT 16
  ------------------
  |  Branch (147:8): [True: 0, False: 590]
  ------------------
  148|       |				/* reached the limit, this whole block */
  149|      0|				scconf_skip_block(parser);
  150|      0|				continue;
  151|      0|			}
  152|       |			/* fall through */
  153|    885|		case '}':
  ------------------
  |  Branch (153:3): [True: 295, False: 5.01k]
  ------------------
  154|  1.18k|		case '=':
  ------------------
  |  Branch (154:3): [True: 295, False: 5.01k]
  ------------------
  155|  1.47k|		case ';':
  ------------------
  |  Branch (155:3): [True: 295, False: 5.01k]
  ------------------
  156|  1.47k|			buf_addch(bp, (char) this_char);
  157|  1.47k|			scconf_parse_token(parser, TOKEN_TYPE_PUNCT, bp->buf);
  ------------------
  |  |   34|  1.47k|#define TOKEN_TYPE_PUNCT	3
  ------------------
  158|  1.47k|			buf_zero(bp);
  159|  1.47k|			continue;
  160|      0|		case '"':
  ------------------
  |  Branch (160:3): [True: 0, False: 5.31k]
  ------------------
  161|      0|			buf_eat_till(bp, (char) this_char, "\"\r\n");
  162|      0|			buf_addch(bp, (char) buf_nextch(bp));
  163|      0|			scconf_parse_token(parser, TOKEN_TYPE_STRING, bp->buf);
  ------------------
  |  |   33|      0|#define TOKEN_TYPE_STRING	2
  ------------------
  164|      0|			buf_zero(bp);
  165|      0|			continue;
  166|    295|		case EOF:
  ------------------
  |  Branch (166:3): [True: 295, False: 5.01k]
  ------------------
  167|    295|			break;
  168|  1.47k|		default:
  ------------------
  |  Branch (168:3): [True: 1.47k, False: 3.83k]
  ------------------
  169|  1.47k|			buf_eat_till(bp, (char) this_char, ";, \t\r\n");
  170|  1.47k|			scconf_parse_token(parser, TOKEN_TYPE_STRING, bp->buf);
  ------------------
  |  |   33|  1.47k|#define TOKEN_TYPE_STRING	2
  ------------------
  171|  1.47k|			buf_zero(bp);
  172|  1.47k|			continue;
  173|  5.31k|		}
  174|    295|		break;
  175|  5.31k|	}
  176|    295|	buf_finished(bp);
  177|    295|	return 1;
  178|    295|}
sclex.c:buf_nextch:
   73|  15.0k|{
   74|  15.0k|	int saved;
   75|       |
   76|  15.0k|	if (bp->saved_char) {
  ------------------
  |  Branch (76:6): [True: 1.47k, False: 13.5k]
  ------------------
   77|  1.47k|		saved = bp->saved_char;
   78|  1.47k|		bp->saved_char = 0;
   79|  1.47k|		return saved;
   80|  1.47k|	}
   81|  13.5k|	if (bp->saved_string) {
  ------------------
  |  Branch (81:6): [True: 13.5k, False: 0]
  ------------------
   82|  13.5k|		if (*(bp->saved_string) == '\0')
  ------------------
  |  Branch (82:7): [True: 295, False: 13.2k]
  ------------------
   83|    295|			return EOF;
   84|  13.2k|		saved = (unsigned char) (*(bp->saved_string++));
   85|  13.2k|		return saved;
   86|  13.5k|	} else {
   87|      0|		saved = fgetc(bp->fp);
   88|      0|		return saved;
   89|      0|	}
   90|  13.5k|}
sclex.c:buf_eat_till:
  101|  1.47k|{
  102|  1.47k|	int i;
  103|       |
  104|  1.47k|	if (start) {
  ------------------
  |  Branch (104:6): [True: 1.47k, False: 0]
  ------------------
  105|  1.47k|		buf_addch(bp, start);
  106|  1.47k|	}
  107|  9.73k|	while (1) {
  ------------------
  |  Branch (107:9): [True: 9.73k, Folded]
  ------------------
  108|  9.73k|		i = buf_nextch(bp);
  109|  9.73k|		if (i == EOF)
  ------------------
  |  Branch (109:7): [True: 0, False: 9.73k]
  ------------------
  110|      0|			return;
  111|  9.73k|		if (strchr(end, i)) {
  ------------------
  |  Branch (111:7): [True: 1.47k, False: 8.26k]
  ------------------
  112|  1.47k|			bp->saved_char = i;
  113|  1.47k|			return;
  114|  1.47k|		}
  115|  8.26k|		buf_addch(bp, (char) i);
  116|  8.26k|	}
  117|  1.47k|}
sclex.c:buf_zero:
  120|  2.95k|{
  121|  2.95k|	bp->bufcur = 0;
  122|  2.95k|	bp->buf[0] = '\0';
  123|  2.95k|}
sclex.c:buf_addch:
   58|  11.2k|{
   59|  11.2k|	if (bp->bufcur + 1 >= bp->bufmax) {
  ------------------
  |  Branch (59:6): [True: 0, False: 11.2k]
  ------------------
   60|      0|		char *p = (char *) realloc(bp->buf, bp->bufmax + 256);
   61|      0|		if (!p)
  ------------------
  |  Branch (61:7): [True: 0, False: 0]
  ------------------
   62|      0|			return;
   63|      0|		bp->bufmax += 256;
   64|      0|		bp->buf = p;
   65|      0|	}
   66|  11.2k|	if (bp->buf) {
  ------------------
  |  Branch (66:6): [True: 11.2k, False: 0]
  ------------------
   67|  11.2k|		bp->buf[bp->bufcur++] = ch;
   68|  11.2k|		bp->buf[bp->bufcur] = '\0';
   69|  11.2k|	}
   70|  11.2k|}
sclex.c:buf_finished:
   93|    295|{
   94|    295|	if (bp->buf) {
  ------------------
  |  Branch (94:6): [True: 295, False: 0]
  ------------------
   95|    295|		free(bp->buf);
   96|       |		bp->buf = NULL;
   97|    295|	}
   98|    295|}

fuzz_util_connect_card:
   52|     51|{
   53|       |	return fuzz_connect_card(ctx, card, NULL, reader_data, reader_data_size);
   54|     51|}
initialize_global:
   57|    617|{
   58|       |	/* Global variables need to be reser between runs,
   59|       |	   fuzz target is called repetitively in one execution */
   60|    617|	ctx = NULL;
   61|    617|	card = NULL;
   62|    617|	p15card = NULL;
   63|    617|	opt_auth_id = NULL;
   64|    617|	opt_reader = NULL;
   65|    617|	opt_cert = NULL;
   66|    617|	opt_data = NULL;
   67|    617|	opt_pubkey = NULL;
   68|    617|	opt_outfile = NULL;
   69|    617|	opt_bind_to_aid = NULL;
   70|    617|	opt_newpin = NULL;
   71|    617|	opt_pin = NULL;
   72|    617|	opt_puk = NULL;
   73|       |
   74|    617|	optind = 0;
   75|    617|	opterr = 0; /* do not print out error messages */
   76|    617|	optopt = 0;
   77|    617|}
LLVMFuzzerTestOneInput:
   80|    623|{
   81|    623|	char **argv = NULL;
   82|    623|	int argc = 0;
   83|       |
   84|    623|	if (size < 10)
  ------------------
  |  Branch (84:6): [True: 6, False: 617]
  ------------------
   85|      6|		return 0;
   86|       |
   87|    617|#ifdef FUZZING_ENABLED
   88|    617|	fclose(stdout);
   89|    617|#endif
   90|    617|	initialize_global();
   91|       |
   92|    617|	if (get_fuzzed_argv("./fuzz_pkcs15", data, size, &argv, &argc, &reader_data, &reader_data_size) != 0)
  ------------------
  |  Branch (92:6): [True: 8, False: 609]
  ------------------
   93|      8|		return 0;
   94|    609|	_main(argc, argv);
   95|    609|	free_arguments(argc, argv);
   96|       |
   97|    609|	return 0;
   98|    617|}

fuzz_get_chunk:
   36|  2.29k|{
   37|  2.29k|    struct driver_data *data;
   38|  2.29k|    uint16_t c_size;
   39|  2.29k|    const uint8_t *c;
   40|       |
   41|  2.29k|    if (chunk)
  ------------------
  |  Branch (41:9): [True: 2.29k, False: 0]
  ------------------
   42|  2.29k|        *chunk = NULL;
   43|  2.29k|    if (chunk_size)
  ------------------
  |  Branch (43:9): [True: 2.29k, False: 0]
  ------------------
   44|  2.29k|        *chunk_size = 0;
   45|       |
   46|  2.29k|    if (!chunk || !chunk_size || !reader) {
  ------------------
  |  Branch (46:9): [True: 0, False: 2.29k]
  |  Branch (46:19): [True: 0, False: 2.29k]
  |  Branch (46:34): [True: 0, False: 2.29k]
  ------------------
   47|      0|        if (reader)
  ------------------
  |  Branch (47:13): [True: 0, False: 0]
  ------------------
   48|      0|            sc_debug(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Invalid Arguments");
  ------------------
  |  |   70|      0|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
   49|      0|        return;
   50|      0|    }
   51|  2.29k|    data = reader->drv_data;
   52|  2.29k|    if (!data || !data->Data || data->Size < sizeof c_size) {
  ------------------
  |  Branch (52:9): [True: 0, False: 2.29k]
  |  Branch (52:18): [True: 0, False: 2.29k]
  |  Branch (52:33): [True: 2.26k, False: 26]
  ------------------
   53|  2.26k|        sc_debug(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL, "Invalid Arguments");
  ------------------
  |  |   70|  2.26k|#define sc_debug(ctx, level, format, args...)	sc_do_log(ctx, level, FILENAME, __LINE__, __FUNCTION__, format , ## args)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
   54|  2.26k|        return;
   55|  2.26k|    }
   56|       |    /* parse the length of the returned data on two bytes */
   57|     26|    c_size = *((uint16_t *) data->Data);
   58|       |    /* consume two bytes from the fuzzing data */
   59|     26|    data->Size -= sizeof c_size;
   60|     26|    data->Data += sizeof c_size;
   61|       |
   62|     26|    if (data->Size < c_size) {
  ------------------
  |  Branch (62:9): [True: 23, False: 3]
  ------------------
   63|     23|        c_size = data->Size;
   64|     23|    }
   65|       |
   66|       |    /* consume the bytes from the fuzzing data */
   67|     26|    c = data->Data;
   68|     26|    data->Size -= c_size;
   69|     26|    data->Data += c_size;
   70|       |
   71|     26|    sc_debug_hex(reader->ctx, SC_LOG_DEBUG_VERBOSE_TOOL,
  ------------------
  |  |  127|     26|    _sc_debug_hex(ctx, level, FILENAME, __LINE__, __FUNCTION__, label, data, len)
  |  |  ------------------
  |  |  |  |   64|       |#define FILENAME __FILE_NAME__
  |  |  ------------------
  ------------------
   72|     26|        "Returning fuzzing chunk", c, c_size);
   73|       |
   74|     26|    *chunk = c;
   75|     26|    *chunk_size = c_size;
   76|     26|}
sc_get_fuzz_driver:
  150|     51|{
  151|     51|    fuzz_ops.release = fuzz_reader_release;
  152|     51|    fuzz_ops.connect = fuzz_reader_connect;
  153|     51|    fuzz_ops.disconnect = fuzz_reader_disconnect;
  154|     51|    fuzz_ops.transmit = fuzz_reader_transmit;
  155|     51|    fuzz_ops.lock = fuzz_reader_lock;
  156|     51|    fuzz_ops.unlock = fuzz_reader_unlock;
  157|     51|    return &fuzz_drv;
  158|     51|}
fuzz_add_reader:
  161|     51|{
  162|     51|    sc_reader_t	*reader;
  163|     51|    struct driver_data *data;
  164|     51|    char name[64] = {0};
  165|       |
  166|     51|    if (!(reader = calloc(1, sizeof(*reader)))
  ------------------
  |  Branch (166:9): [True: 0, False: 51]
  ------------------
  167|     51|            || !(data = (calloc(1, sizeof(*data))))) {
  ------------------
  |  Branch (167:16): [True: 0, False: 51]
  ------------------
  168|      0|        free(reader);
  169|      0|        return;
  170|      0|    }
  171|       |
  172|     51|    data->Data = Data;
  173|     51|    data->Size = Size;
  174|       |
  175|     51|    reader->driver = &fuzz_drv;
  176|     51|    reader->ops = &fuzz_ops;
  177|     51|    reader->drv_data = data;
  178|     51|    snprintf(name, sizeof name - 1, "%zu random byte%s reader (%p)",
  179|     51|            Size, Size == 1 ? "" : "s", Data);
  ------------------
  |  Branch (179:19): [True: 11, False: 40]
  ------------------
  180|     51|    reader->name = strdup(name);
  181|       |
  182|     51|    reader->ctx = ctx;
  183|     51|    list_append(&ctx->readers, reader);
  184|     51|}
fuzz_connect_card:
  188|     51|{
  189|     51|    struct sc_reader *reader = NULL;
  190|       |
  191|       |    /* Erase possible readers from ctx */
  192|     51|    while (list_size(&ctx->readers)) {
  ------------------
  |  Branch (192:12): [True: 0, False: 51]
  ------------------
  193|      0|        sc_reader_t *rdr = (sc_reader_t *) list_get_at(&ctx->readers, 0);
  194|      0|        _sc_delete_reader(ctx, rdr);
  195|      0|    }
  196|     51|    if (ctx->reader_driver->ops->finish != NULL)
  ------------------
  |  Branch (196:9): [True: 51, False: 0]
  ------------------
  197|     51|        ctx->reader_driver->ops->finish(ctx);
  198|       |
  199|       |    /* Create virtual reader */
  200|     51|    ctx->reader_driver = sc_get_fuzz_driver();
  201|     51|    fuzz_add_reader(ctx, data, size);
  202|     51|    reader = sc_ctx_get_reader(ctx, 0);
  203|       |
  204|       |    /* Connect card */
  205|     51|    if (sc_connect_card(reader, card))
  ------------------
  |  Branch (205:9): [True: 51, False: 0]
  ------------------
  206|     51|        return SC_ERROR_INTERNAL;
  ------------------
  |  |   81|     51|#define SC_ERROR_INTERNAL			-1400
  ------------------
  207|       |
  208|      0|    if (reader_out)
  ------------------
  |  Branch (208:9): [True: 0, False: 0]
  ------------------
  209|      0|        *reader_out = reader;
  210|       |
  211|      0|    return SC_SUCCESS;
  ------------------
  |  |   28|      0|#define SC_SUCCESS				0
  ------------------
  212|     51|}
fuzzer_reader.c:fuzz_reader_release:
   79|     51|{
   80|     51|    if (reader) {
  ------------------
  |  Branch (80:9): [True: 51, False: 0]
  ------------------
   81|     51|        free(reader->drv_data);
   82|     51|        reader->drv_data = NULL;
   83|     51|    }
   84|       |
   85|     51|    return SC_SUCCESS;
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
   86|     51|}
fuzzer_reader.c:fuzz_reader_connect:
   89|     51|{
   90|     51|    uint16_t chunk_size;
   91|     51|    const uint8_t *chunk;
   92|       |
   93|     51|    fuzz_get_chunk(reader, &chunk, &chunk_size);
   94|       |
   95|     51|    if (chunk_size > SC_MAX_ATR_SIZE)
  ------------------
  |  |   41|     51|#define SC_MAX_ATR_SIZE			33
  ------------------
  |  Branch (95:9): [True: 0, False: 51]
  ------------------
   96|      0|        chunk_size = SC_MAX_ATR_SIZE;
  ------------------
  |  |   41|      0|#define SC_MAX_ATR_SIZE			33
  ------------------
   97|     51|    else
   98|     51|        reader->atr.len = chunk_size;
   99|       |
  100|     51|    if (chunk_size > 0)
  ------------------
  |  Branch (100:9): [True: 20, False: 31]
  ------------------
  101|     20|        memcpy(reader->atr.value, chunk, chunk_size);
  102|       |
  103|     51|    return SC_SUCCESS;
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  104|     51|}
fuzzer_reader.c:fuzz_reader_disconnect:
  107|     51|{
  108|     51|    return SC_SUCCESS;
  ------------------
  |  |   28|     51|#define SC_SUCCESS				0
  ------------------
  109|     51|}
fuzzer_reader.c:fuzz_reader_transmit:
  112|  2.24k|{
  113|  2.24k|    const uint8_t *chunk;
  114|  2.24k|    uint16_t chunk_size;
  115|       |
  116|  2.24k|    fuzz_get_chunk(reader, &chunk, &chunk_size);
  117|       |
  118|  2.24k|    if (chunk_size >= 2) {
  ------------------
  |  Branch (118:9): [True: 0, False: 2.24k]
  ------------------
  119|       |        /* set the SW1 and SW2 status bytes (the last two bytes of
  120|       |         * the response */
  121|      0|        apdu->sw1 = (unsigned int)chunk[chunk_size - 2];
  122|      0|        apdu->sw2 = (unsigned int)chunk[chunk_size - 1];
  123|      0|        chunk_size -= 2;
  124|       |        /* set output length and copy the returned data if necessary */
  125|      0|        if (chunk_size <= apdu->resplen)
  ------------------
  |  Branch (125:13): [True: 0, False: 0]
  ------------------
  126|      0|            apdu->resplen = chunk_size;
  127|       |
  128|      0|        if (apdu->resplen != 0)
  ------------------
  |  Branch (128:13): [True: 0, False: 0]
  ------------------
  129|      0|            memcpy(apdu->resp, chunk, apdu->resplen);
  130|  2.24k|    } else {
  131|  2.24k|        apdu->sw1 = 0x6D;
  132|  2.24k|        apdu->sw2 = 0x00;
  133|  2.24k|        apdu->resplen = 0;
  134|  2.24k|    }
  135|       |
  136|  2.24k|    return SC_SUCCESS;
  ------------------
  |  |   28|  2.24k|#define SC_SUCCESS				0
  ------------------
  137|  2.24k|}
fuzzer_reader.c:fuzz_reader_lock:
  140|  2.24k|{
  141|  2.24k|    return 0;
  142|  2.24k|}
fuzzer_reader.c:fuzz_reader_unlock:
  145|  2.24k|{
  146|  2.24k|    return 0;
  147|  2.24k|}

get_word:
   26|   500k|{
   27|       |	/* Words are separated by one zero byte,
   28|       |	   return pointer to the next word if there is one */
   29|   500k|	const uint8_t *ptr = data;
   30|   500k|	if (!data || size == 0 || *data == 0)
  ------------------
  |  Branch (30:6): [True: 0, False: 500k]
  |  Branch (30:15): [True: 0, False: 500k]
  |  Branch (30:28): [True: 0, False: 500k]
  ------------------
   31|      0|		return NULL;
   32|       |	
   33|   500k|	ptr = memchr(data, 0, size - 1);
   34|   500k|	return ptr ? ++ptr : NULL;
  ------------------
  |  Branch (34:9): [True: 500k, False: 4]
  ------------------
   35|   500k|}
extract_word:
   38|   145k|{
   39|       |	/* Find word and return its copy (needs to be freed) */
   40|   145k|	char *result = NULL;
   41|   145k|	const uint8_t *ptr = NULL;
   42|       |
   43|   145k|	if (*size < 2)
  ------------------
  |  Branch (43:6): [True: 0, False: 145k]
  ------------------
   44|      0|		return NULL;
   45|       |
   46|   145k|	ptr = get_word(*data, *size);
   47|   145k|	if (!ptr)
  ------------------
  |  Branch (47:6): [True: 0, False: 145k]
  ------------------
   48|      0|		return NULL;
   49|   145k|	result = strdup((const char *)*data);
   50|   145k|	*size -=(ptr - *data);
   51|   145k|	*data = ptr;
   52|       |
   53|   145k|	return result;
   54|   145k|}
get_fuzzed_argv:
   58|    617|{
   59|    617|	const uint8_t *ptr = data, *help_ptr = data;
   60|    617|	size_t ptr_size = size;
   61|    617|	char **argv = NULL;
   62|    617|	int argc = 1;
   63|       |
   64|       |	/* Count arguments until double zero bytes occurs*/
   65|   355k|	while(*ptr != 0) {
  ------------------
  |  Branch (65:8): [True: 354k, False: 613]
  ------------------
   66|   354k|		ptr = get_word(help_ptr, ptr_size);
   67|   354k|		if (!ptr)
  ------------------
  |  Branch (67:7): [True: 4, False: 354k]
  ------------------
   68|      4|			return -1;
   69|   354k|		argc++;
   70|   354k|		ptr_size -= (ptr - help_ptr);
   71|   354k|		help_ptr = ptr;
   72|   354k|	}
   73|       |
   74|    613|	if (argc > MAX_ARGC)
  ------------------
  |  |   23|    613|#define MAX_ARGC 10000
  ------------------
  |  Branch (74:6): [True: 4, False: 609]
  ------------------
   75|      4|		return -1;
   76|       |
   77|    609|	argv = malloc((argc + 1) * sizeof(char*));
   78|    609|	if (!argv)
  ------------------
  |  Branch (78:6): [True: 0, False: 609]
  ------------------
   79|      0|		return -1;
   80|       |
   81|       |	/* Copy arguments into argv */
   82|    609|	ptr = data;
   83|    609|	ptr_size = size;
   84|    609|	argv[0] = strdup(app_name);
   85|   146k|	for (int i = 1; i < argc; i++) {
  ------------------
  |  Branch (85:18): [True: 145k, False: 609]
  ------------------
   86|   145k|		argv[i] = extract_word(&ptr, &ptr_size);
   87|   145k|	}
   88|    609|	argv[argc] = NULL;
   89|       |
   90|    609|	*argc_out = argc;
   91|    609|	*argv_out = argv;
   92|    609|	*reader_data = ptr + 1; /* there are two zero bytes at the end of argv */
   93|    609|	*reader_data_size = ptr_size - 1;
   94|    609|	return 0;
   95|    609|}
free_arguments:
  166|    609|{
  167|   146k|	for (int i = 0; i < argc; i++) {
  ------------------
  |  Branch (167:18): [True: 146k, False: 609]
  ------------------
  168|   146k|		free(argv[i]);
  169|   146k|	}
  170|    609|	free(argv);
  171|    609|}

_main:
 2129|    609|{
 2130|    609|	int err = 0, r, c, long_optind = 0;
 2131|    609|	int do_read_cert = 0;
 2132|    609|	int do_list_certs = 0;
 2133|    609|	int do_read_data_object = 0;
 2134|    609|	int do_list_data_objects = 0;
 2135|    609|	int do_list_pins = 0;
 2136|    609|	int do_list_skeys = 0;
 2137|    609|	int do_list_apps = 0;
 2138|    609|	int do_dump = 0;
 2139|    609|	int do_list_prkeys = 0;
 2140|    609|	int do_list_pubkeys = 0;
 2141|    609|	int do_read_pubkey = 0;
 2142|    609|#if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
 2143|    609|	int do_read_sshkey = 0;
 2144|    609|#endif
 2145|    609|	int do_verify_pin = 0;
 2146|    609|	int do_change_pin = 0;
 2147|    609|	int do_unblock_pin = 0;
 2148|    609|	int do_test_update = 0;
 2149|    609|	int do_test_session_pin = 0;
 2150|    609|	int do_update = 0;
 2151|    609|	int do_print_version = 0;
 2152|    609|	int do_list_info = 0;
 2153|    609|	int action_count = 0;
 2154|    609|	sc_context_param_t ctx_param;
 2155|       |
 2156|    609|	static_assert(sizeof(option_help) / sizeof(char *) == sizeof(options) / sizeof(struct option),
 2157|    609|			"internal error");
 2158|       |
 2159|  1.13M|	while (1) {
  ------------------
  |  Branch (2159:9): [True: 1.13M, Folded]
  ------------------
 2160|  1.13M|		c = getopt_long(argc, argv, "r:cuko:sva:LR:CwDTU", options, &long_optind);
 2161|  1.13M|		if (c == -1)
  ------------------
  |  Branch (2161:7): [True: 588, False: 1.13M]
  ------------------
 2162|    588|			break;
 2163|  1.13M|		if (c == '?') {
  ------------------
  |  Branch (2163:7): [True: 21, False: 1.13M]
  ------------------
 2164|     21|			util_print_usage(app_name, options, option_help, NULL);
 2165|     21|			return 2;
 2166|     21|		}
 2167|  1.13M|		switch (c) {
  ------------------
  |  Branch (2167:11): [True: 1.13M, False: 542]
  ------------------
 2168|    361|		case 'r':
  ------------------
  |  Branch (2168:3): [True: 361, False: 1.13M]
  ------------------
 2169|       |
 2170|       |#if OPENSC_MAJOR == 0 &&  OPENSC_VERSION_MINOR == 19
 2171|       |			fprintf(stderr, "\nWarning, option -r is reserved to specify card reader in future versions\n");
 2172|       |			fprintf (stderr, "Using -r option for read-certificate operation\n\n");
 2173|       |			opt_cert = optarg;
 2174|       |			do_read_cert = 1;
 2175|       |			action_count++;
 2176|       |			break;
 2177|       |#elif OPENSC_MAJOR == 0 &&  OPENSC_VERSION_MINOR == 20
 2178|       |
 2179|       |			memset(&ctx_param, 0, sizeof(ctx_param));
 2180|       |			ctx_param.ver      = 0;
 2181|       |			ctx_param.app_name = app_name;
 2182|       |			if (verbose)
 2183|       |				ctx_param.debug_file = stderr;
 2184|       |
 2185|       |			if (SC_SUCCESS == sc_context_create(&ctx, &ctx_param)) {
 2186|       |				/* attempt to connect reader, on error, -r is used for read-certificate operation */
 2187|       |				struct sc_reader *reader = NULL;
 2188|       |
 2189|       |				err = util_connect_reader(ctx, &reader, optarg, 0, 0);
 2190|       |				sc_release_context(ctx);
 2191|       |				ctx = NULL;
 2192|       |
 2193|       |				if (err != SC_SUCCESS ) {
 2194|       |#if 1
 2195|       |					fprintf (stderr,
 2196|       |						"Error, option -r is reserved to specify card reader, no reader \"%s\" found\n", optarg);
 2197|       |					exit (1);
 2198|       |#else
 2199|       |					fprintf (stderr,
 2200|       |						"\nWarning, option -r is reserved to specify card reader, no reader \"%s\" found\n", optarg);
 2201|       |					fprintf (stderr, "Using -r option for read-certificate operation\n\n");
 2202|       |					opt_cert = optarg;
 2203|       |					do_read_cert = 1;
 2204|       |					action_count++;
 2205|       |					break;
 2206|       |#endif
 2207|       |				}
 2208|       |			}
 2209|       |			opt_reader = optarg;
 2210|       |			break;
 2211|       |#elif (OPENSC_MAJOR > 0) || (OPENSC_MAJOR == 0 && OPENSC_VERSION_MINOR > 20)
 2212|       |
 2213|    361|			opt_reader = optarg;
 2214|    361|			break;
 2215|      0|#endif
 2216|       |
 2217|    520|		case OPT_PRINT_VERSION:
  ------------------
  |  Branch (2217:3): [True: 520, False: 1.13M]
  ------------------
 2218|    520|			do_print_version = 1;
 2219|    520|			action_count++;
 2220|    520|			break;
 2221|    202|		case OPT_LIST_INFO:
  ------------------
  |  Branch (2221:3): [True: 202, False: 1.13M]
  ------------------
 2222|    202|			do_list_info = 1;
 2223|    202|			action_count++;
 2224|    202|			break;
 2225|    318|		case OPT_READ_CERT:
  ------------------
  |  Branch (2225:3): [True: 318, False: 1.13M]
  ------------------
 2226|    318|			opt_cert = optarg;
 2227|    318|			do_read_cert = 1;
 2228|    318|			action_count++;
 2229|    318|			break;
 2230|  7.19k|		case 'c':
  ------------------
  |  Branch (2230:3): [True: 7.19k, False: 1.13M]
  ------------------
 2231|  7.19k|			do_list_certs = 1;
 2232|  7.19k|			action_count++;
 2233|  7.19k|			break;
 2234|    485|		case 'R':
  ------------------
  |  Branch (2234:3): [True: 485, False: 1.13M]
  ------------------
 2235|    485|			opt_data = optarg;
 2236|    485|			do_read_data_object = 1;
 2237|    485|			action_count++;
 2238|    485|			break;
 2239|    194|		case OPT_RAW:
  ------------------
  |  Branch (2239:3): [True: 194, False: 1.13M]
  ------------------
 2240|    194|			opt_raw = 1;
 2241|    194|			break;
 2242|   319k|		case 'C':
  ------------------
  |  Branch (2242:3): [True: 319k, False: 818k]
  ------------------
 2243|   319k|			do_list_data_objects = 1;
 2244|   319k|			action_count++;
 2245|   319k|			break;
 2246|    510|		case OPT_VERIFY_PIN:
  ------------------
  |  Branch (2246:3): [True: 510, False: 1.13M]
  ------------------
 2247|    510|			do_verify_pin = 1;
 2248|    510|			action_count++;
 2249|    510|			break;
 2250|    210|		case OPT_CHANGE_PIN:
  ------------------
  |  Branch (2250:3): [True: 210, False: 1.13M]
  ------------------
 2251|    210|			do_change_pin = 1;
 2252|    210|			action_count++;
 2253|    210|			break;
 2254|   727k|		case 'u':
  ------------------
  |  Branch (2254:3): [True: 727k, False: 411k]
  ------------------
 2255|   727k|			do_unblock_pin = 1;
 2256|   727k|			action_count++;
 2257|   727k|			break;
 2258|    195|		case OPT_LIST_PINS:
  ------------------
  |  Branch (2258:3): [True: 195, False: 1.13M]
  ------------------
 2259|    195|			do_list_pins = 1;
 2260|    195|			action_count++;
 2261|    195|			break;
 2262|    194|		case OPT_LIST_SKEYS:
  ------------------
  |  Branch (2262:3): [True: 194, False: 1.13M]
  ------------------
 2263|    194|			do_list_skeys = 1;
 2264|    194|			action_count++;
 2265|    194|			break;
 2266|    313|		case 'D':
  ------------------
  |  Branch (2266:3): [True: 313, False: 1.13M]
  ------------------
 2267|    313|			do_dump = 1;
 2268|    313|			action_count++;
 2269|    313|			break;
 2270|  23.4k|		case 'k':
  ------------------
  |  Branch (2270:3): [True: 23.4k, False: 1.11M]
  ------------------
 2271|  23.4k|			do_list_prkeys = 1;
 2272|  23.4k|			action_count++;
 2273|  23.4k|			break;
 2274|    195|		case OPT_LIST_PUB:
  ------------------
  |  Branch (2274:3): [True: 195, False: 1.13M]
  ------------------
 2275|    195|			do_list_pubkeys = 1;
 2276|    195|			action_count++;
 2277|    195|			break;
 2278|    550|		case OPT_READ_PUB:
  ------------------
  |  Branch (2278:3): [True: 550, False: 1.13M]
  ------------------
 2279|    550|			opt_pubkey = optarg;
 2280|    550|			do_read_pubkey = 1;
 2281|    550|			action_count++;
 2282|    550|			break;
 2283|      0|#if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
 2284|    200|		case OPT_READ_SSH:
  ------------------
  |  Branch (2284:3): [True: 200, False: 1.13M]
  ------------------
 2285|    200|			opt_pubkey = optarg;
 2286|    200|			do_read_sshkey = 1;
 2287|    200|			action_count++;
 2288|    200|			break;
 2289|    194|		case OPT_RFC4716:
  ------------------
  |  Branch (2289:3): [True: 194, False: 1.13M]
  ------------------
 2290|    194|			opt_rfc4716 = 1;
 2291|    194|			break;
 2292|      0|#endif
 2293|    480|		case 'T':
  ------------------
  |  Branch (2293:3): [True: 480, False: 1.13M]
  ------------------
 2294|    480|			do_test_update = 1;
 2295|    480|			action_count++;
 2296|    480|			break;
 2297|    195|		case OPT_TEST_SESSION_PIN:
  ------------------
  |  Branch (2297:3): [True: 195, False: 1.13M]
  ------------------
 2298|    195|			do_test_session_pin = 1;
 2299|    195|			action_count++;
 2300|    195|			break;
 2301|  6.69k|		case 'U':
  ------------------
  |  Branch (2301:3): [True: 6.69k, False: 1.13M]
  ------------------
 2302|  6.69k|			do_update = 1;
 2303|  6.69k|			action_count++;
 2304|  6.69k|			break;
 2305|    201|		case OPT_READER:
  ------------------
  |  Branch (2305:3): [True: 201, False: 1.13M]
  ------------------
 2306|    201|			opt_reader = optarg;
 2307|    201|			break;
 2308|  3.06k|		case OPT_PIN:
  ------------------
  |  Branch (2308:3): [True: 3.06k, False: 1.13M]
  ------------------
 2309|  3.06k|			util_get_pin(optarg, &opt_pin);
 2310|  3.06k|			break;
 2311|    281|		case OPT_NEWPIN:
  ------------------
  |  Branch (2311:3): [True: 281, False: 1.13M]
  ------------------
 2312|    281|			util_get_pin(optarg, &opt_newpin);
 2313|    281|			break;
 2314|    264|		case OPT_PUK:
  ------------------
  |  Branch (2314:3): [True: 264, False: 1.13M]
  ------------------
 2315|    264|			util_get_pin(optarg, &opt_puk);
 2316|    264|			break;
 2317|    321|		case 'o':
  ------------------
  |  Branch (2317:3): [True: 321, False: 1.13M]
  ------------------
 2318|    321|			opt_outfile = optarg;
 2319|    321|			break;
 2320|  5.18k|		case 's':
  ------------------
  |  Branch (2320:3): [True: 5.18k, False: 1.13M]
  ------------------
 2321|  5.18k|			compact++;
 2322|  5.18k|			break;
 2323|  26.1k|		case 'v':
  ------------------
  |  Branch (2323:3): [True: 26.1k, False: 1.11M]
  ------------------
 2324|  26.1k|			verbose++;
 2325|  26.1k|			break;
 2326|  1.67k|		case 'a':
  ------------------
  |  Branch (2326:3): [True: 1.67k, False: 1.13M]
  ------------------
 2327|  1.67k|			opt_auth_id = optarg;
 2328|  1.67k|			break;
 2329|    465|		case OPT_BIND_TO_AID:
  ------------------
  |  Branch (2329:3): [True: 465, False: 1.13M]
  ------------------
 2330|    465|			opt_bind_to_aid = optarg;
 2331|    465|			break;
 2332|    194|		case OPT_LIST_APPLICATIONS:
  ------------------
  |  Branch (2332:3): [True: 194, False: 1.13M]
  ------------------
 2333|    194|			do_list_apps = 1;
 2334|    194|			action_count++;
 2335|    194|			break;
 2336|    506|		case OPT_NO_CACHE:
  ------------------
  |  Branch (2336:3): [True: 506, False: 1.13M]
  ------------------
 2337|    506|			opt_no_cache++;
 2338|    506|			break;
 2339|    272|		case OPT_CLEAR_CACHE:
  ------------------
  |  Branch (2339:3): [True: 272, False: 1.13M]
  ------------------
 2340|    272|			opt_clear_cache = 1;
 2341|    272|			action_count++;
 2342|    272|			break;
 2343|  8.23k|		case 'w':
  ------------------
  |  Branch (2343:3): [True: 8.23k, False: 1.12M]
  ------------------
 2344|  8.23k|			opt_wait = 1;
 2345|  8.23k|			break;
 2346|  1.03k|		case OPT_USE_PINPAD_DEPRECATED:
  ------------------
  |  Branch (2346:3): [True: 1.03k, False: 1.13M]
  ------------------
 2347|  1.03k|			fprintf(stderr, "'--no-prompt' is deprecated , use '--use-pinpad' instead.\n");
  ------------------
  |  |   39|  1.03k|#define stderr stdout
  ------------------
 2348|       |			/* fallthrough */
 2349|  1.23k|		case OPT_USE_PINPAD:
  ------------------
  |  Branch (2349:3): [True: 194, False: 1.13M]
  ------------------
 2350|  1.23k|			opt_use_pinpad = 1;
 2351|  1.23k|			break;
 2352|  1.13M|		}
 2353|  1.13M|	}
 2354|    588|	if (action_count == 0) {
  ------------------
  |  Branch (2354:6): [True: 293, False: 295]
  ------------------
 2355|    293|		util_print_usage(app_name, options, option_help, NULL);
 2356|    293|		return 2;
 2357|    293|	}
 2358|       |
 2359|    295|	if (do_print_version)   {
  ------------------
  |  Branch (2359:6): [True: 16, False: 279]
  ------------------
 2360|     16|		printf("%s\n", OPENSC_SCM_REVISION);
  ------------------
  |  |  226|     16|#define OPENSC_SCM_REVISION "OpenSC-<version not available>, rev: d0f842f, commit-time: 2026-07-23 13:01:12 +0200"
  ------------------
 2361|     16|		action_count--;
 2362|     16|	}
 2363|       |
 2364|    295|	memset(&ctx_param, 0, sizeof(ctx_param));
 2365|    295|	ctx_param.ver      = 0;
 2366|    295|	ctx_param.app_name = app_name;
 2367|    295|	ctx_param.debug    = verbose;
 2368|    295|	if (verbose)
  ------------------
  |  Branch (2368:6): [True: 295, False: 0]
  ------------------
 2369|    295|		ctx_param.debug_file = stderr;
  ------------------
  |  |   39|    295|#define stderr stdout
  ------------------
 2370|       |
 2371|    295|	r = sc_context_create(&ctx, &ctx_param);
 2372|    295|	if (r) {
  ------------------
  |  Branch (2372:6): [True: 0, False: 295]
  ------------------
 2373|      0|		fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r));
  ------------------
  |  |   39|      0|#define stderr stdout
  ------------------
 2374|      0|		return 1;
 2375|      0|	}
 2376|       |
 2377|    295|	if (opt_clear_cache) {
  ------------------
  |  Branch (2377:6): [True: 244, False: 51]
  ------------------
 2378|    244|		if ((err = clear_cache()))
  ------------------
  |  Branch (2378:7): [True: 244, False: 0]
  ------------------
 2379|    244|			goto end;
 2380|      0|		action_count--;
 2381|      0|	}
 2382|       |
 2383|     51|	err = util_connect_card_ex(ctx, &card, opt_reader, opt_wait, 0);
  ------------------
  |  |   43|     51|#define util_connect_card_ex(ctx, card, id, do_wait, do_lock) fuzz_util_connect_card(ctx, card)
  ------------------
 2384|     51|	if (err)
  ------------------
  |  Branch (2384:6): [True: 51, False: 0]
  ------------------
 2385|     51|		goto end;
 2386|       |
 2387|      0|	if (verbose)
  ------------------
  |  Branch (2387:6): [True: 0, False: 0]
  ------------------
 2388|      0|		fprintf(stderr, "Trying to find a PKCS#15 compatible card...\n");
  ------------------
  |  |   39|      0|#define stderr stdout
  ------------------
 2389|       |
 2390|      0|	if (opt_bind_to_aid)   {
  ------------------
  |  Branch (2390:6): [True: 0, False: 0]
  ------------------
 2391|      0|		struct sc_aid aid;
 2392|       |
 2393|      0|		aid.len = sizeof(aid.value);
 2394|      0|		if (sc_hex_to_bin(opt_bind_to_aid, aid.value, &aid.len))   {
  ------------------
  |  Branch (2394:7): [True: 0, False: 0]
  ------------------
 2395|      0|			fprintf(stderr, "Invalid AID value: '%s'\n", opt_bind_to_aid);
  ------------------
  |  |   39|      0|#define stderr stdout
  ------------------
 2396|      0|			err = 1;
 2397|      0|			goto end;
 2398|      0|		}
 2399|       |
 2400|      0|		r = sc_pkcs15_bind(card, &aid, &p15card);
 2401|      0|	}
 2402|      0|	else   {
 2403|      0|		r = sc_pkcs15_bind(card, NULL, &p15card);
 2404|      0|	}
 2405|       |
 2406|      0|	if (r) {
  ------------------
  |  Branch (2406:6): [True: 0, False: 0]
  ------------------
 2407|      0|		fprintf(stderr, "PKCS#15 binding failed: %s\n", sc_strerror(r));
  ------------------
  |  |   39|      0|#define stderr stdout
  ------------------
 2408|      0|		err = 1;
 2409|      0|		goto end;
 2410|      0|	}
 2411|      0|	if (opt_no_cache)
  ------------------
  |  Branch (2411:6): [True: 0, False: 0]
  ------------------
 2412|      0|		p15card->opts.use_file_cache = 0;
 2413|      0|	if (verbose)
  ------------------
  |  Branch (2413:6): [True: 0, False: 0]
  ------------------
 2414|      0|		fprintf(stderr, "Found %s!\n", p15card->tokeninfo->label);
  ------------------
  |  |   39|      0|#define stderr stdout
  ------------------
 2415|       |
 2416|      0|	if (do_list_info) {
  ------------------
  |  Branch (2416:6): [True: 0, False: 0]
  ------------------
 2417|      0|		if (!do_dump)
  ------------------
  |  Branch (2417:7): [True: 0, False: 0]
  ------------------
 2418|      0|			list_info();
 2419|      0|		action_count--;
 2420|      0|	}
 2421|       |
 2422|      0|	if (do_verify_pin)
  ------------------
  |  Branch (2422:6): [True: 0, False: 0]
  ------------------
 2423|      0|		if ((err = verify_pin()))
  ------------------
  |  Branch (2423:7): [True: 0, False: 0]
  ------------------
 2424|      0|			goto end;
 2425|       |
 2426|      0|	if (do_list_certs) {
  ------------------
  |  Branch (2426:6): [True: 0, False: 0]
  ------------------
 2427|      0|		if ((err = list_certificates()))
  ------------------
  |  Branch (2427:7): [True: 0, False: 0]
  ------------------
 2428|      0|			goto end;
 2429|      0|		action_count--;
 2430|      0|	}
 2431|      0|	if (do_read_cert) {
  ------------------
  |  Branch (2431:6): [True: 0, False: 0]
  ------------------
 2432|      0|		if ((err = read_certificate()))
  ------------------
  |  Branch (2432:7): [True: 0, False: 0]
  ------------------
 2433|      0|			goto end;
 2434|      0|		action_count--;
 2435|      0|	}
 2436|      0|	if (do_list_data_objects) {
  ------------------
  |  Branch (2436:6): [True: 0, False: 0]
  ------------------
 2437|      0|		if ((err = list_data_objects()))
  ------------------
  |  Branch (2437:7): [True: 0, False: 0]
  ------------------
 2438|      0|			goto end;
 2439|      0|		action_count--;
 2440|      0|	}
 2441|      0|	if (do_read_data_object) {
  ------------------
  |  Branch (2441:6): [True: 0, False: 0]
  ------------------
 2442|      0|		if ((err = read_data_object()))
  ------------------
  |  Branch (2442:7): [True: 0, False: 0]
  ------------------
 2443|      0|			goto end;
 2444|      0|		action_count--;
 2445|      0|	}
 2446|      0|	if (do_list_prkeys) {
  ------------------
  |  Branch (2446:6): [True: 0, False: 0]
  ------------------
 2447|      0|		if ((err = list_private_keys()))
  ------------------
  |  Branch (2447:7): [True: 0, False: 0]
  ------------------
 2448|      0|			goto end;
 2449|      0|		action_count--;
 2450|      0|	}
 2451|      0|	if (do_list_pubkeys) {
  ------------------
  |  Branch (2451:6): [True: 0, False: 0]
  ------------------
 2452|      0|		if ((err = list_public_keys()))
  ------------------
  |  Branch (2452:7): [True: 0, False: 0]
  ------------------
 2453|      0|			goto end;
 2454|      0|		action_count--;
 2455|      0|	}
 2456|      0|	if (do_read_pubkey) {
  ------------------
  |  Branch (2456:6): [True: 0, False: 0]
  ------------------
 2457|      0|		if ((err = read_public_key()))
  ------------------
  |  Branch (2457:7): [True: 0, False: 0]
  ------------------
 2458|      0|			goto end;
 2459|      0|		action_count--;
 2460|      0|	}
 2461|      0|#if defined(ENABLE_OPENSSL) && (defined(_WIN32) || defined(HAVE_INTTYPES_H))
 2462|      0|	if (do_read_sshkey) {
  ------------------
  |  Branch (2462:6): [True: 0, False: 0]
  ------------------
 2463|      0|		if ((err = read_ssh_key()))
  ------------------
  |  Branch (2463:7): [True: 0, False: 0]
  ------------------
 2464|      0|			goto end;
 2465|      0|		action_count--;
 2466|      0|	}
 2467|      0|#endif
 2468|      0|	if (do_list_pins) {
  ------------------
  |  Branch (2468:6): [True: 0, False: 0]
  ------------------
 2469|      0|		if ((err = list_pins()))
  ------------------
  |  Branch (2469:7): [True: 0, False: 0]
  ------------------
 2470|      0|			goto end;
 2471|      0|		action_count--;
 2472|      0|	}
 2473|      0|	if (do_list_skeys) {
  ------------------
  |  Branch (2473:6): [True: 0, False: 0]
  ------------------
 2474|      0|		if ((err = list_skeys()))
  ------------------
  |  Branch (2474:7): [True: 0, False: 0]
  ------------------
 2475|      0|			goto end;
 2476|      0|		action_count--;
 2477|      0|	}
 2478|      0|	if (do_list_apps) {
  ------------------
  |  Branch (2478:6): [True: 0, False: 0]
  ------------------
 2479|      0|		if ((err = list_apps(stdout)))
  ------------------
  |  Branch (2479:7): [True: 0, False: 0]
  ------------------
 2480|      0|			goto end;
 2481|      0|		action_count--;
 2482|      0|	}
 2483|      0|	if (do_dump) {
  ------------------
  |  Branch (2483:6): [True: 0, False: 0]
  ------------------
 2484|      0|		if ((err = dump()))
  ------------------
  |  Branch (2484:7): [True: 0, False: 0]
  ------------------
 2485|      0|			goto end;
 2486|      0|		action_count--;
 2487|      0|	}
 2488|      0|	if (do_change_pin) {
  ------------------
  |  Branch (2488:6): [True: 0, False: 0]
  ------------------
 2489|      0|		if ((err = change_pin()))
  ------------------
  |  Branch (2489:7): [True: 0, False: 0]
  ------------------
 2490|      0|			goto end;
 2491|      0|		action_count--;
 2492|      0|	}
 2493|      0|	if (do_unblock_pin) {
  ------------------
  |  Branch (2493:6): [True: 0, False: 0]
  ------------------
 2494|      0|		if ((err = unblock_pin()))
  ------------------
  |  Branch (2494:7): [True: 0, False: 0]
  ------------------
 2495|      0|			goto end;
 2496|      0|		action_count--;
 2497|      0|	}
 2498|      0|	if (do_test_update || do_update) {
  ------------------
  |  Branch (2498:6): [True: 0, False: 0]
  |  Branch (2498:24): [True: 0, False: 0]
  ------------------
 2499|      0|		err = test_update(card);
 2500|      0|		action_count--;
 2501|      0|		if (err == 2) { /* problem */
  ------------------
  |  Branch (2501:7): [True: 0, False: 0]
  ------------------
 2502|      0|			err = 1;
 2503|      0|			goto end;
 2504|      0|		}
 2505|      0|		if (do_update && err == 1) { /* card vulnerable */
  ------------------
  |  Branch (2505:7): [True: 0, False: 0]
  |  Branch (2505:20): [True: 0, False: 0]
  ------------------
 2506|      0|			if ((err = update(card)))
  ------------------
  |  Branch (2506:8): [True: 0, False: 0]
  ------------------
 2507|      0|				goto end;
 2508|      0|		}
 2509|      0|	}
 2510|      0|	if (do_test_session_pin) {
  ------------------
  |  Branch (2510:6): [True: 0, False: 0]
  ------------------
 2511|      0|		if ((err = test_session_pin()))
  ------------------
  |  Branch (2511:7): [True: 0, False: 0]
  ------------------
 2512|      0|			goto end;
 2513|      0|		action_count--;
 2514|      0|	}
 2515|    295|end:
 2516|    295|	sc_pkcs15_unbind(p15card);
 2517|    295|	sc_disconnect_card(card);
 2518|    295|	sc_release_context(ctx);
 2519|    295|	return err;
 2520|      0|}
fuzz_pkcs15_tool.c:clear_cache:
 1316|    244|{
 1317|    244|	char dirname[PATH_MAX];
 1318|    244|	int r = 0;
 1319|       |
 1320|       |	/* remove the user's cache directory */
 1321|    244|	if ((r = sc_get_cache_dir(ctx, dirname, sizeof(dirname))) < 0)
  ------------------
  |  Branch (1321:6): [True: 0, False: 244]
  ------------------
 1322|      0|		return r;
 1323|    244|	r = nftw(dirname, unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
 1324|    244|	return r;
 1325|    244|}

util_print_usage:
  260|    314|{
  261|    314|	int i;
  262|    314|	int header_shown = 0;
  263|       |
  264|    314|	if (args)
  ------------------
  |  Branch (264:6): [True: 0, False: 314]
  ------------------
  265|      0|		printf("Usage: %s [OPTIONS] %s\n", app_name, args);
  266|    314|	else
  267|    314|		printf("Usage: %s [OPTIONS]\n", app_name);
  268|       |
  269|  11.6k|	for (i = 0; options[i].name; i++) {
  ------------------
  |  Branch (269:14): [True: 11.3k, False: 314]
  ------------------
  270|  11.3k|		char buf[40];
  271|  11.3k|		const char *arg_str;
  272|       |
  273|       |		/* Skip "hidden" options */
  274|  11.3k|		if (option_help[i] == NULL)
  ------------------
  |  Branch (274:7): [True: 314, False: 10.9k]
  ------------------
  275|    314|			continue;
  276|       |
  277|  10.9k|		if (!header_shown++)
  ------------------
  |  Branch (277:7): [True: 314, False: 10.6k]
  ------------------
  278|    314|			printf("Options:\n");
  279|       |
  280|  10.9k|		switch (options[i].has_arg) {
  281|  3.45k|		case 1:
  ------------------
  |  Branch (281:3): [True: 3.45k, False: 7.53k]
  ------------------
  282|  3.45k|			arg_str = " <arg>";
  283|  3.45k|			break;
  284|      0|		case 2:
  ------------------
  |  Branch (284:3): [True: 0, False: 10.9k]
  ------------------
  285|      0|			arg_str = " [arg]";
  286|      0|			break;
  287|  7.53k|		default:
  ------------------
  |  Branch (287:3): [True: 7.53k, False: 3.45k]
  ------------------
  288|  7.53k|			arg_str = "";
  289|  7.53k|			break;
  290|  10.9k|		}
  291|  10.9k|		if (isascii(options[i].val) &&
  ------------------
  |  Branch (291:7): [True: 4.08k, False: 6.90k]
  ------------------
  292|  10.9k|		    isprint(options[i].val) && !isspace(options[i].val))
  ------------------
  |  Branch (292:7): [True: 4.08k, False: 0]
  |  Branch (292:34): [True: 4.08k, False: 0]
  ------------------
  293|  4.08k|			sprintf(buf, "-%c, --%s%s", options[i].val, options[i].name, arg_str);
  294|  6.90k|		else
  295|  6.90k|			sprintf(buf, "    --%s%s", options[i].name, arg_str);
  296|       |
  297|       |		/* print the line - wrap if necessary */
  298|  10.9k|		if (strlen(buf) > 28) {
  ------------------
  |  Branch (298:7): [True: 0, False: 10.9k]
  ------------------
  299|      0|			printf("  %s\n", buf);
  300|      0|			buf[0] = '\0';
  301|      0|		}
  302|  10.9k|		printf("  %-28s  %s\n", buf, option_help[i]);
  303|  10.9k|	}
  304|    314|}
util_get_pin:
  500|  3.60k|{
  501|  3.60k|	size_t inputlen;
  502|  3.60k|	size_t pinlen = 0;
  503|       |
  504|  3.60k|	if (!input || !pin) {
  ------------------
  |  Branch (504:6): [True: 0, False: 3.60k]
  |  Branch (504:16): [True: 0, False: 3.60k]
  ------------------
  505|      0|		return 0;
  506|      0|	}
  507|  3.60k|	inputlen = strlen(input);
  508|       |
  509|  3.60k|	if (inputlen > 4 && strncasecmp(input, "env:", 4) == 0) {
  ------------------
  |  Branch (509:6): [True: 2.77k, False: 836]
  |  Branch (509:22): [True: 1.35k, False: 1.41k]
  ------------------
  510|       |		// Get a PIN from a environment variable
  511|  1.35k|		*pin = getenv(input + 4);
  512|  1.35k|		pinlen = *pin ? strlen(*pin) : 0;
  ------------------
  |  Branch (512:12): [True: 378, False: 981]
  ------------------
  513|  2.24k|	} else if (inputlen > 5 && strncasecmp(input, "file:", 5) == 0) {
  ------------------
  |  Branch (513:13): [True: 1.10k, False: 1.14k]
  |  Branch (513:29): [True: 194, False: 911]
  ------------------
  514|    194|		fprintf(stderr, "Reading PIN from file not supported!\n");
  515|  2.05k|	} else {
  516|       |		//Just use the input
  517|  2.05k|		*pin = input;
  518|  2.05k|		pinlen = inputlen;
  519|  2.05k|	}
  520|  3.60k|	return pinlen;
  521|  3.60k|}

