"Fossies" - the Fresh Open Source Software Archive

Member "opensc-0.22.0/src/libopensc/card-mcrd.c" (10 Aug 2021, 34606 Bytes) of package /linux/privat/opensc-0.22.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "card-mcrd.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 0.21.0_vs_0.22.0.

    1 /*
    2  * card-mcrd.c: Support for MICARDO cards
    3  *
    4  * Copyright (C) 2004  Martin Paljak <martin@martinpaljak.net>
    5  * Copyright (C) 2004  Priit Randla <priit.randla@eyp.ee>
    6  * Copyright (C) 2003  Marie Fischer <marie@vtl.ee>
    7  * Copyright (C) 2001  Juha Yrjölä <juha.yrjola@iki.fi>
    8  * Copyright (C) 2002  g10 Code GmbH
    9  *
   10  * This library is free software; you can redistribute it and/or
   11  * modify it under the terms of the GNU Lesser General Public
   12  * License as published by the Free Software Foundation; either
   13  * version 2.1 of the License, or (at your option) any later version.
   14  *
   15  * This library is distributed in the hope that it will be useful,
   16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   18  * Lesser General Public License for more details.
   19  *
   20  * You should have received a copy of the GNU Lesser General Public
   21  * License along with this library; if not, write to the Free Software
   22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   23  */
   24 
   25 #if HAVE_CONFIG_H
   26 #include "config.h"
   27 #endif
   28 
   29 #include <stdlib.h>
   30 #include <string.h>
   31 #include <ctype.h>
   32 
   33 #include "internal.h"
   34 #include "asn1.h"
   35 #include "cardctl.h"
   36 #include "gp.h"
   37 
   38 static const struct sc_atr_table mcrd_atrs[] = {
   39     {"3B:FF:94:00:FF:80:B1:FE:45:1F:03:00:68:D2:76:00:00:28:FF:05:1E:31:80:00:90:00:23", NULL,
   40       "Micardo 2.1/German BMI/D-Trust", SC_CARD_TYPE_MCRD_GENERIC, 0, NULL},
   41     {"3b:6f:00:ff:00:68:d2:76:00:00:28:ff:05:1e:31:80:00:90:00", NULL,
   42       "D-Trust", SC_CARD_TYPE_MCRD_GENERIC, 0, NULL},
   43     {"3b:ff:11:00:ff:80:b1:fe:45:1f:03:00:68:d2:76:00:00:28:ff:05:1e:31:80:00:90:00:a6", NULL,
   44       "D-Trust", SC_CARD_TYPE_MCRD_GENERIC, 0, NULL},
   45     {"3b:fe:18:00:00:80:31:fe:45:80:31:80:66:40:90:a4:16:2a:00:83:0f:90:00:ef", NULL, "EstEID 3.5 warm", SC_CARD_TYPE_MCRD_ESTEID_V30, 0, NULL},
   46     {"3b:fa:18:00:00:80:31:fe:45:fe:65:49:44:20:2f:20:50:4b:49:03", NULL, "EstEID 3.5 cold", SC_CARD_TYPE_MCRD_ESTEID_V30, 0, NULL },
   47     {"3b:f8:18:00:00:80:31:fe:45:fe:41:5a:45:20:44:49:54:33", NULL, "AzeDIT 3.5 cold", SC_CARD_TYPE_MCRD_ESTEID_V30, 0, NULL },
   48     {NULL, NULL, NULL, 0, 0, NULL}
   49 };
   50 
   51 static const struct sc_aid EstEID_v35_AID = { {0xD2, 0x33, 0x00, 0x00, 0x00, 0x45, 0x73, 0x74, 0x45, 0x49, 0x44, 0x20, 0x76, 0x33, 0x35}, 15 };
   52 
   53 static struct sc_card_operations mcrd_ops;
   54 static struct sc_card_driver mcrd_drv = {
   55     "MICARDO 2.1 / EstEID 3.0 - 3.5",
   56     "mcrd",
   57     &mcrd_ops,
   58     NULL, 0, NULL
   59 };
   60 
   61 static const struct sc_card_operations *iso_ops = NULL;
   62 
   63 enum {
   64     MCRD_SEL_MF = 0x00,
   65     MCRD_SEL_DF = 0x01,
   66     MCRD_SEL_EF = 0x02,
   67     MCRD_SEL_PARENT = 0x03,
   68     MCRD_SEL_AID = 0x04
   69 };
   70 
   71 #define MFID 0x3F00
   72 #define EF_KeyD 0x0013      /* File with extra key information. */
   73 #define EF_Rule 0x0030      /* Default ACL file. */
   74 #define SC_ESTEID_KEYREF_FILE_RECLEN 21
   75 
   76 #define MAX_CURPATH 10
   77 
   78 struct rule_record_s {
   79     struct rule_record_s *next;
   80     unsigned int recno;
   81     size_t datalen;
   82     u8 data[1];
   83 };
   84 
   85 struct keyd_record_s {
   86     struct keyd_record_s *next;
   87     unsigned int recno;
   88     size_t datalen;
   89     u8 data[1];
   90 };
   91 
   92 struct df_info_s {
   93     struct df_info_s *next;
   94     unsigned short path[MAX_CURPATH];
   95     size_t pathlen;
   96     struct rule_record_s *rule_file;    /* keeps records of EF_Rule. */
   97     struct keyd_record_s *keyd_file;    /* keeps records of EF_KeyD. */
   98 };
   99 
  100 struct mcrd_priv_data {
  101     unsigned short curpath[MAX_CURPATH];    /* The currently selected path. */
  102     int is_ef;      /* True if the path points to an EF. */
  103     size_t curpathlen;  /* Length of this path or 0 if unknown. */
  104     struct df_info_s *df_infos;
  105     sc_security_env_t sec_env;  /* current security environment */
  106 };
  107 
  108 #define DRVDATA(card) ((struct mcrd_priv_data *) ((card)->drv_data))
  109 
  110 // Control Reference Template Tag for Key Agreement (ISO 7816-4:2013 Table 54)
  111 static const struct sc_asn1_entry c_asn1_control[] = {
  112     { "control", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_CTX | 0xA6, 0, NULL, NULL },
  113     { NULL, 0, 0, 0, NULL, NULL }
  114 };
  115 
  116 // Ephemeral public key Template Tag (ISO 7816-8:2016 Table 3)
  117 static const struct sc_asn1_entry c_asn1_ephermal[] = {
  118     { "ephemeral", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_APP | 0x7F49, 0, NULL, NULL },
  119     { NULL, 0, 0, 0, NULL, NULL }
  120 };
  121 
  122 // External Public Key
  123 static const struct sc_asn1_entry c_asn1_public[] = {
  124     { "publicKey", SC_ASN1_OCTET_STRING, SC_ASN1_CTX | 0x86, 0, NULL, NULL },
  125     { NULL, 0, 0, 0, NULL, NULL }
  126 };
  127 
  128 static int load_special_files(sc_card_t * card);
  129 static int select_part(sc_card_t * card, u8 kind, unsigned short int fid, sc_file_t ** file);
  130 
  131 /* Return the DF_info for the current path.  If does not yet exist,
  132    create it.  Returns NULL on error. */
  133 static struct df_info_s *get_df_info(sc_card_t * card)
  134 {
  135     sc_context_t *ctx = card->ctx;
  136     struct mcrd_priv_data *priv = DRVDATA(card);
  137     struct df_info_s *dfi;
  138 
  139     if(!(!priv->is_ef))
  140         return NULL;
  141 
  142     if (!priv->curpathlen) {
  143         sc_log(ctx, "no current path to find the df_info\n");
  144         return NULL;
  145     }
  146 
  147     for (dfi = priv->df_infos; dfi; dfi = dfi->next) {
  148         if (dfi->pathlen == priv->curpathlen
  149             && !memcmp(dfi->path, priv->curpath,
  150                     dfi->pathlen * sizeof *dfi->path))
  151             return dfi;
  152     }
  153     /* Not found, create it. */
  154     dfi = calloc(1, sizeof *dfi);
  155     if (!dfi) {
  156         sc_log(ctx, "out of memory while allocating df_info\n");
  157         return NULL;
  158     }
  159     dfi->pathlen = priv->curpathlen;
  160     memcpy(dfi->path, priv->curpath, dfi->pathlen * sizeof *dfi->path);
  161     dfi->next = priv->df_infos;
  162     priv->df_infos = dfi;
  163     return dfi;
  164 }
  165 
  166 static void clear_special_files(struct df_info_s *dfi)
  167 {
  168     if (dfi) {
  169         while (dfi->rule_file) {
  170             struct rule_record_s *tmp = dfi->rule_file->next;
  171             free(dfi->rule_file);
  172             dfi->rule_file = tmp;
  173         }
  174         while (dfi->keyd_file) {
  175             struct keyd_record_s *tmp = dfi->keyd_file->next;
  176             free(dfi->keyd_file);
  177             dfi->keyd_file = tmp;
  178         }
  179     }
  180 }
  181 
  182 /* Some functionality straight from the EstEID manual.
  183  * Official notice: Refer to the Micardo 2.1 Public manual.
  184  * Sad side: not available without a NDA.
  185  */
  186 
  187 static int mcrd_delete_ref_to_authkey(sc_card_t * card)
  188 {
  189     sc_apdu_t apdu;
  190     int r;
  191     u8 sbuf[2] = { 0x83, 0x00 };
  192     if(card == NULL)
  193         return SC_ERROR_INTERNAL;
  194     sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xA4, sbuf, 2, NULL, 0);
  195     r = sc_transmit_apdu(card, &apdu);
  196     LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
  197     SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
  198 }
  199 
  200 static int mcrd_delete_ref_to_signkey(sc_card_t * card)
  201 {
  202     sc_apdu_t apdu;
  203     int r;
  204     u8 sbuf[2] = { 0x83, 0x00 };
  205     if(card == NULL)
  206         return SC_ERROR_INTERNAL;
  207     sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB6, sbuf, 2, NULL, 0);
  208     r = sc_transmit_apdu(card, &apdu);
  209     LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
  210     SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, sc_check_sw(card, apdu.sw1, apdu.sw2));
  211 }
  212 
  213 static int is_esteid_card(sc_card_t *card)
  214 {
  215     return card->type == SC_CARD_TYPE_MCRD_ESTEID_V30 ? 1 : 0;
  216 }
  217 
  218 static int mcrd_match_card(sc_card_t * card)
  219 {
  220     int i = 0, r = 0;
  221 
  222     i = _sc_match_atr(card, mcrd_atrs, &card->type);
  223     if (i >= 0) {
  224         card->name = mcrd_atrs[i].name;
  225         return 1;
  226     }
  227 
  228     LOG_FUNC_CALLED(card->ctx);
  229     r = gp_select_aid(card, &EstEID_v35_AID);
  230     if (r >= 0) {
  231         sc_log(card->ctx, "AID found");
  232         card->type = SC_CARD_TYPE_MCRD_ESTEID_V30;
  233         return 1;
  234     }
  235     return 0;
  236 }
  237 
  238 static int mcrd_init(sc_card_t * card)
  239 {
  240     unsigned long flags;
  241     struct mcrd_priv_data *priv = calloc(1, sizeof *priv);
  242     if (!priv)
  243         return SC_ERROR_OUT_OF_MEMORY;
  244     priv->curpath[0] = MFID;
  245     priv->curpathlen = 1;
  246     card->drv_data = priv;
  247     card->cla = 0x00;
  248     card->caps = SC_CARD_CAP_RNG;
  249 
  250     if (is_esteid_card(card)) {
  251         unsigned long ext_flags = SC_ALGORITHM_EXT_EC_NAMEDCURVE | SC_ALGORITHM_EXT_EC_UNCOMPRESES;
  252         flags = SC_ALGORITHM_ECDSA_RAW | SC_ALGORITHM_ECDH_CDH_RAW | SC_ALGORITHM_ECDSA_HASH_NONE;
  253         _sc_card_add_ec_alg(card, 384, flags, ext_flags, NULL);
  254         // Force EstEID 3.5 card recv size 255 with T=0 to avoid recursive read binary
  255         // sc_read_binary cannot handle recursive 61 00 calls
  256         if (card->reader && card->reader->active_protocol == SC_PROTO_T0)
  257             card->max_recv_size = 255;
  258     } else {
  259         flags = SC_ALGORITHM_RSA_RAW | SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE;
  260         _sc_card_add_rsa_alg(card, 512, flags, 0);
  261         _sc_card_add_rsa_alg(card, 768, flags, 0);
  262         _sc_card_add_rsa_alg(card, 1024, flags, 0);
  263     }
  264 
  265     if (SC_SUCCESS != sc_select_file (card, sc_get_mf_path(), NULL))
  266         sc_log(card->ctx, "Warning: select MF failed");
  267 
  268     /* Not needed for the fixed EstEID profile */
  269     if (!is_esteid_card(card))
  270         load_special_files(card);
  271 
  272     return SC_SUCCESS;
  273 }
  274 
  275 static int mcrd_finish(sc_card_t * card)
  276 {
  277     struct mcrd_priv_data *priv;
  278 
  279     if (card == NULL)
  280         return 0;
  281     priv = DRVDATA(card);
  282     while (priv->df_infos) {
  283         struct df_info_s *tmp = priv->df_infos->next;
  284         clear_special_files(priv->df_infos);
  285         free(priv->df_infos);
  286         priv->df_infos = tmp;
  287     }
  288     free(priv);
  289     return 0;
  290 }
  291 
  292 /* Load the rule and keyd file into our private data.
  293    Return 0 on success */
  294 static int load_special_files(sc_card_t * card)
  295 {
  296     sc_context_t *ctx = card->ctx;
  297     int r;
  298     unsigned int recno;
  299     struct df_info_s *dfi;
  300     struct rule_record_s *rule;
  301     struct keyd_record_s *keyd;
  302 
  303     /* First check whether we already cached it. */
  304     dfi = get_df_info(card);
  305     if (dfi && dfi->rule_file)
  306         return 0;   /* yes. */
  307     clear_special_files(dfi);
  308     if (!dfi)
  309         LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
  310 
  311     /* Read rule file. Note that we bypass our cache here. */
  312     r = select_part(card, MCRD_SEL_EF, EF_Rule, NULL);
  313     LOG_TEST_RET(ctx, r, "selecting EF_Rule failed");
  314 
  315     for (recno = 1;; recno++) {
  316         u8 recbuf[256];
  317         r = sc_read_record(card, recno, recbuf, sizeof(recbuf),
  318                     SC_RECORD_BY_REC_NR);
  319 
  320         if (r == SC_ERROR_RECORD_NOT_FOUND)
  321             break;
  322         if (r < 0) {
  323             SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r);
  324         } else {
  325             rule = malloc(sizeof *rule + (size_t)r);
  326             if (!rule)
  327                 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
  328             rule->recno = recno;
  329             rule->datalen = (size_t)r;
  330             memcpy(rule->data, recbuf, r);
  331             rule->next = dfi->rule_file;
  332             dfi->rule_file = rule;
  333         }
  334     }
  335 
  336     sc_log(ctx, "new EF_Rule file loaded (%d records)\n", recno - 1);
  337 
  338     /* Read the KeyD file. Note that we bypass our cache here. */
  339     r = select_part(card, MCRD_SEL_EF, EF_KeyD, NULL);
  340     if (r == SC_ERROR_FILE_NOT_FOUND) {
  341         sc_log(ctx, "no EF_KeyD file available\n");
  342         return 0;   /* That is okay. */
  343     }
  344     LOG_TEST_RET(ctx, r, "selecting EF_KeyD failed");
  345 
  346     for (recno = 1;; recno++) {
  347         u8 recbuf[256];
  348         r = sc_read_record(card, recno, recbuf, sizeof(recbuf),
  349                     SC_RECORD_BY_REC_NR);
  350 
  351         if (r == SC_ERROR_RECORD_NOT_FOUND)
  352             break;
  353         if (r < 0) {
  354             SC_FUNC_RETURN(ctx, SC_LOG_DEBUG_VERBOSE, r);
  355         } else {
  356             keyd = malloc(sizeof *keyd + (size_t)r);
  357             if (!keyd)
  358                 LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
  359             keyd->recno = recno;
  360             keyd->datalen = (size_t) r;
  361             memcpy(keyd->data, recbuf, r);
  362             keyd->next = dfi->keyd_file;
  363             dfi->keyd_file = keyd;
  364         }
  365     }
  366 
  367     sc_log(ctx, "new EF_KeyD file loaded (%d records)\n", recno - 1);
  368     /* FIXME: Do we need to restore the current DF?  I guess it is
  369        not required, but we could try to do so by selecting 3fff?  */
  370     return 0;
  371 }
  372 
  373 /* Process an ARR (7816-9/8.5.4) and setup the ACL. */
  374 static void process_arr(sc_card_t * card, const u8 * buf, size_t buflen)
  375 {
  376     sc_context_t *ctx = card->ctx;
  377     struct df_info_s *dfi;
  378     struct rule_record_s *rule;
  379     size_t left, taglen;
  380     unsigned int cla, tag;
  381     const u8 *p;
  382     int skip;
  383     char dbgbuf[2048];
  384 
  385     /* Currently we support only the short for. */
  386     if (buflen != 1) {
  387         sc_log(ctx, "can't handle long ARRs\n");
  388         return;
  389     }
  390 
  391     dfi = get_df_info(card);
  392     for (rule = dfi ? dfi->rule_file : NULL; rule && rule->recno != *buf;
  393         rule = rule->next) ;
  394     if (!rule) {
  395         sc_log(ctx, "referenced EF_rule record %d not found\n", *buf);
  396         return;
  397     }
  398 
  399     sc_hex_dump(rule->data, rule->datalen, dbgbuf, sizeof dbgbuf);
  400     sc_log(ctx,
  401         "rule for record %d:\n%s", *buf, dbgbuf);
  402 
  403     p = rule->data;
  404     left = rule->datalen;
  405     skip = 1;       /* Skip over initial unknown SC DOs. */
  406     for (;;) {
  407         buf = p;
  408         if (sc_asn1_read_tag(&p, left, &cla, &tag, &taglen) != SC_SUCCESS
  409                 || p == NULL)
  410             break;
  411         left -= (size_t)(p - buf);
  412         tag |= cla;
  413 
  414         if (tag == 0x80 && taglen != 1) {
  415             skip = 1;
  416         } else if (tag == 0x80) {   /* AM byte. */
  417             sc_log(ctx, "  AM_DO: %02x\n", *p);
  418             skip = 0;
  419         } else if (tag >= 0x81 && tag <= 0x8f) {    /* Cmd description */
  420             sc_hex_dump(p, taglen, dbgbuf, sizeof dbgbuf);
  421             sc_log(ctx, "  AM_DO: cmd[%s%s%s%s] %s",
  422                  (tag & 8) ? "C" : "",
  423                  (tag & 4) ? "I" : "",
  424                  (tag & 2) ? "1" : "",
  425                  (tag & 1) ? "2" : "", dbgbuf);
  426             skip = 0;
  427         } else if (tag == 0x9C) {   /* Proprietary state machine descrip. */
  428             skip = 1;
  429         } else if (!skip) {
  430             switch (tag) {
  431             case 0x90:  /* Always */
  432                 sc_log(ctx, "     SC: always\n");
  433                 break;
  434             case 0x97:  /* Never */
  435                 sc_log(ctx, "     SC: never\n");
  436                 break;
  437             case 0xA4:  /* Authentication, value is a CRT. */
  438                 sc_log_hex(ctx, "     SC: auth", p, taglen);
  439                 break;
  440 
  441             case 0xB4:
  442             case 0xB6:
  443             case 0xB8:  /* Cmd or resp with SM, value is a CRT. */
  444                 sc_log_hex(ctx, "     SC: cmd/resp", p, taglen);
  445                 break;
  446 
  447             case 0x9E:  /* Security Condition byte. */
  448                 sc_log_hex(ctx, "     SC: condition", p, taglen);
  449                 break;
  450 
  451             case 0xA0:  /* OR template. */
  452                 sc_log(ctx, "     SC: OR\n");
  453                 break;
  454             case 0xAF:  /* AND template. */
  455                 sc_log(ctx, "     SC: AND\n");
  456                 break;
  457             }
  458         }
  459         left -= taglen;
  460         p += taglen;
  461     }
  462 
  463 }
  464 
  465 static void process_fcp(sc_card_t * card, sc_file_t * file,
  466             const u8 * buf, size_t buflen)
  467 {
  468     sc_context_t *ctx = card->ctx;
  469     size_t taglen, len = buflen;
  470     const u8 *tag = NULL, *p = buf;
  471     int bad_fde = 0;
  472 
  473     sc_log(ctx, "processing FCI bytes\n");
  474 
  475     /* File identifier. */
  476     tag = sc_asn1_find_tag(ctx, p, len, 0x83, &taglen);
  477     if (tag != NULL && taglen == 2) {
  478         file->id = (tag[0] << 8) | tag[1];
  479         sc_log(ctx,
  480             "  file identifier: 0x%02X%02X\n", tag[0], tag[1]);
  481     }
  482     /* Number of data bytes in the file including structural information. */
  483     tag = sc_asn1_find_tag(ctx, p, len, 0x81, &taglen);
  484     if (!tag) {
  485         /* My card does not encode the filelength in 0x81 but
  486            in 0x85 which is the file descriptor extension in TCOS.
  487            Assume that this is the case when the regular file
  488            size tag is not encoded. */
  489         tag = sc_asn1_find_tag(ctx, p, len, 0x85, &taglen);
  490         bad_fde = !!tag;
  491     }
  492     if (tag != NULL && taglen >= 2) {
  493         int bytes = (tag[0] << 8) + tag[1];
  494         sc_log(ctx,
  495             "  bytes in file: %d\n", bytes);
  496         file->size = (size_t)bytes;
  497     }
  498     if (tag == NULL) {
  499         tag = sc_asn1_find_tag(ctx, p, len, 0x80, &taglen);
  500         if (tag != NULL && taglen >= 2) {
  501             int bytes = (tag[0] << 8) + tag[1];
  502             sc_log(ctx,
  503                 "  bytes in file: %d\n", bytes);
  504             file->size = (size_t)bytes;
  505         }
  506     }
  507 
  508     /* File descriptor byte(s). */
  509     tag = sc_asn1_find_tag(ctx, p, len, 0x82, &taglen);
  510     if (tag != NULL) {
  511         /* Fixme, this might actual be up to 6 bytes. */
  512         if (taglen > 0) {
  513             unsigned char byte = tag[0];
  514             const char *type;
  515 
  516             file->shareable = byte & 0x40 ? 1 : 0;
  517             sc_log(ctx,
  518                 "  shareable: %s\n",
  519                  (byte & 0x40) ? "yes" : "no");
  520             file->ef_structure = byte & 0x07;
  521             switch ((byte >> 3) & 7) {
  522             case 0:
  523                 type = "working EF";
  524                 file->type = SC_FILE_TYPE_WORKING_EF;
  525                 break;
  526             case 1:
  527                 type = "internal EF";
  528                 file->type = SC_FILE_TYPE_INTERNAL_EF;
  529                 break;
  530             case 7:
  531                 type = "DF";
  532                 file->type = SC_FILE_TYPE_DF;
  533                 break;
  534             default:
  535                 type = "unknown";
  536                 break;
  537             }
  538             sc_log(ctx,
  539                 "  type: %s\n", type);
  540             sc_log(ctx,
  541                 "  EF structure: %d\n", byte & 0x07);
  542         }
  543     }
  544 
  545     /* DF name. */
  546     tag = sc_asn1_find_tag(ctx, p, len, 0x84, &taglen);
  547     if (tag != NULL && taglen > 0 && taglen <= 16) {
  548         char name[17];
  549         size_t i;
  550 
  551         memcpy(file->name, tag, taglen);
  552         file->namelen = taglen;
  553 
  554         for (i = 0; i < taglen; i++) {
  555             if (isalnum(tag[i]) || ispunct(tag[i]) || isspace(tag[i]))
  556                 name[i] = (const char)tag[i];
  557             else
  558                 name[i] = '?';
  559         }
  560         name[taglen] = 0;
  561         sc_log(ctx, "  file name: %s\n", name);
  562     }
  563 
  564     /* Proprietary information. */
  565     tag = bad_fde ? NULL : sc_asn1_find_tag(ctx, p, len, 0x85, &taglen);
  566     if (tag != NULL && taglen) {
  567         sc_file_set_prop_attr(file, tag, taglen);
  568     } else
  569         file->prop_attr_len = 0;
  570 
  571     /* Proprietary information, constructed. */
  572     tag = sc_asn1_find_tag(ctx, p, len, 0xA5, &taglen);
  573     if (tag != NULL && taglen) {
  574         sc_file_set_prop_attr(file, tag, taglen);
  575     }
  576 
  577     /* Security attributes, proprietary format. */
  578     tag = sc_asn1_find_tag(ctx, p, len, 0x86, &taglen);
  579     if (tag != NULL && taglen) {
  580         sc_file_set_sec_attr(file, tag, taglen);
  581     }
  582 
  583     /* Security attributes, reference to expanded format. */
  584     tag = sc_asn1_find_tag(ctx, p, len, 0x8B, &taglen);
  585     if (tag && taglen && !is_esteid_card(card)) {
  586         process_arr(card, tag, taglen);
  587     } else if ((tag = sc_asn1_find_tag(ctx, p, len, 0xA1, &taglen))
  588             && taglen) {
  589         /* Not found, but there is a Security Attribute
  590            Template for interface mode. */
  591         tag = sc_asn1_find_tag(ctx, tag, taglen, 0x8B, &taglen);
  592         if (tag && taglen)
  593             process_arr(card, tag, taglen);
  594     }
  595 
  596     file->magic = SC_FILE_MAGIC;
  597 }
  598 
  599 /* Send a select command and parse the response. */
  600 static int
  601 do_select(sc_card_t * card, u8 kind,
  602       const u8 * buf, size_t buflen, sc_file_t ** file)
  603 {
  604     sc_apdu_t apdu;
  605     u8 resbuf[SC_MAX_APDU_BUFFER_SIZE];
  606     int r;
  607 
  608     u8 p2 = 0x00;
  609     if (kind == MCRD_SEL_EF) p2 = 0x04;
  610     if (kind == MCRD_SEL_DF) p2 = 0x0C;
  611 
  612     sc_format_apdu_ex(&apdu, 0x00, 0xA4, kind, p2, buf, buflen, resbuf, 256);
  613     r = sc_transmit_apdu(card, &apdu);
  614     LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
  615     if (!file) {
  616         if (apdu.sw1 == 0x61)
  617             SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, 0);
  618         r = sc_check_sw(card, apdu.sw1, apdu.sw2);
  619         if (!r && kind == MCRD_SEL_AID)
  620             card->cache.current_path.len = 0;
  621         SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
  622     }
  623     r = sc_check_sw(card, apdu.sw1, apdu.sw2);
  624     if (r)
  625         SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, r);
  626 
  627     if (p2 == 0x0C) {
  628         if (file) {
  629             *file = sc_file_new();
  630             if (!*file)
  631                 LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
  632             (*file)->type = SC_FILE_TYPE_DF;
  633             return SC_SUCCESS;
  634         }
  635     }
  636 
  637     if (p2 == 0x04 && apdu.resp[0] == 0x62) {
  638         *file = sc_file_new();
  639         if (!*file)
  640             LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
  641         /* EstEID v3.0 cards are buggy and sometimes return a double 0x62 tag */
  642         if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V30 && apdu.resp[2] == 0x62)
  643             process_fcp(card, *file, apdu.resp + 4, apdu.resp[3]);
  644         else
  645             process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]);
  646         return SC_SUCCESS;
  647     }
  648 
  649     if (p2 != 0x0C && apdu.resp[0] == 0x6F) {
  650         *file = sc_file_new();
  651         if (!*file)
  652             LOG_FUNC_RETURN(card->ctx, SC_ERROR_OUT_OF_MEMORY);
  653         if (apdu.resp[1] <= apdu.resplen)
  654             process_fcp(card, *file, apdu.resp + 2, apdu.resp[1]);
  655         return SC_SUCCESS;
  656     }
  657     return SC_SUCCESS;
  658 }
  659 
  660 /* Wrapper around do_select to be used when multiple selects are
  661    required. */
  662 static int
  663 select_part(sc_card_t * card, u8 kind, unsigned short int fid,
  664         sc_file_t ** file)
  665 {
  666     u8 fbuf[2];
  667     unsigned int len;
  668     int r;
  669 
  670     sc_log(card->ctx,
  671         "select_part (0x%04X, kind=%u)\n", fid, kind);
  672 
  673     if (fid == MFID) {
  674         kind = MCRD_SEL_MF; /* force this kind. */
  675         len = 0;
  676     } else {
  677         fbuf[0] = fid >> 8;
  678         fbuf[1] = fid & 0xff;
  679         len = 2;
  680     }
  681     r = do_select(card, kind, fbuf, len, file);
  682 
  683     return r;
  684 }
  685 
  686 /* Select a file by iterating over the FID in the PATHPTR array while
  687    updating the curpath kept in the private data cache.  With DF_ONLY
  688    passed as true only DF are selected, otherwise the function tries
  689    to figure out whether the last path item is a DF or EF. */
  690 static int
  691 select_down(sc_card_t * card,
  692         unsigned short *pathptr, size_t pathlen,
  693         int df_only, sc_file_t ** file)
  694 {
  695     struct mcrd_priv_data *priv = DRVDATA(card);
  696     int r;
  697     int found_ef = 0;
  698 
  699     if (!pathlen)
  700         return SC_ERROR_INVALID_ARGUMENTS;
  701 
  702     for (; pathlen; pathlen--, pathptr++) {
  703         if (priv->curpathlen == MAX_CURPATH)
  704             LOG_TEST_RET(card->ctx, SC_ERROR_INTERNAL,
  705                     "path too long for cache");
  706         r = -1;     /* force DF select. */
  707         if (pathlen == 1 && !df_only) {
  708             /* first try to select an EF and retry an DF
  709                on error. */
  710             r = select_part(card, MCRD_SEL_EF, *pathptr, file);
  711             if (!r)
  712                 found_ef = 1;
  713         }
  714         if (r)
  715             r = select_part(card, MCRD_SEL_DF, *pathptr,
  716                     pathlen == 1 ? file : NULL);
  717         LOG_TEST_RET(card->ctx, r, "unable to select DF");
  718         priv->curpath[priv->curpathlen] = *pathptr;
  719         priv->curpathlen++;
  720     }
  721     priv->is_ef = found_ef;
  722     if (!found_ef && !is_esteid_card(card))
  723         load_special_files(card);
  724 
  725     return 0;
  726 }
  727 
  728 /* Handle the selection case when a PATH is requested.  Our card does
  729    not support this addressing so we have to emulate it.  To keep the
  730    security status we should not unnecessary change the directory;
  731    this is accomplished be keeping track of the currently selected
  732    file.  Note that PATH is an array of PATHLEN file ids and not the
  733    usual sc_path structure. */
  734 
  735 static int
  736 select_file_by_path(sc_card_t * card, unsigned short *pathptr,
  737             size_t pathlen, sc_file_t ** file)
  738 {
  739     struct mcrd_priv_data *priv = DRVDATA(card);
  740     int r;
  741     size_t i;
  742 
  743     SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  744 
  745     if (!(!priv->curpathlen || priv->curpath[0] == MFID))
  746         return SC_ERROR_INTERNAL;
  747 
  748     if (pathlen && *pathptr == 0x3FFF) {
  749         pathlen--;
  750         pathptr++;
  751     }
  752 
  753     if (!pathlen || pathlen >= MAX_CURPATH)
  754         r = SC_ERROR_INVALID_ARGUMENTS;
  755     else if (pathlen == 1 && pathptr[0] == MFID) {
  756         /* MF requested: clear the cache and select it. */
  757         priv->curpathlen = 0;
  758         r = select_part(card, MCRD_SEL_MF, pathptr[0], file);
  759         LOG_TEST_RET(card->ctx, r, "unable to select MF");
  760         priv->curpath[0] = pathptr[0];
  761         priv->curpathlen = 1;
  762         priv->is_ef = 0;
  763     } else if (pathlen > 1 && pathptr[0] == MFID) {
  764         /* Absolute addressing, check cache to avoid
  765            unnecessary selects. */
  766         for (i = 0; (i < pathlen && i < priv->curpathlen
  767                 && pathptr[i] == priv->curpath[i]); i++) ;
  768         if (!priv->curpathlen) {
  769             /* Need to do all selects starting at the root. */
  770             priv->curpathlen = 0;
  771             priv->is_ef = 0;
  772             r = select_down(card, pathptr, pathlen, 0, file);
  773         } else if (i == pathlen && i < priv->curpathlen) {
  774             /* Go upwards; we do it the easy way and start
  775                at the root.  However we know that the target is a DF. */
  776             priv->curpathlen = 0;
  777             priv->is_ef = 0;
  778             r = select_down(card, pathptr, pathlen, 1, file);
  779         } else if (i == pathlen && i == priv->curpathlen) {
  780             /* Already selected. */
  781             if (!file)
  782                 r = 0;  /* The caller did not request the fci. */
  783             else {
  784                 /* This EF or DF was already selected, but
  785                    we need to get the FCI, so we have
  786                    to select again. */
  787                 if (!(priv->curpathlen > 1))
  788                     return SC_ERROR_INTERNAL;
  789                 priv->curpathlen--;
  790                 priv->is_ef = 0;
  791                 r = select_down(card, pathptr + pathlen - 1, 1,
  792                         0, file);
  793             }
  794         } else {
  795             /* We have to append something.  For now we
  796                simply start at the root. (fixme) */
  797             priv->curpathlen = 0;
  798             priv->is_ef = 0;
  799             r = select_down(card, pathptr, pathlen, 0, file);
  800         }
  801     } else {
  802         /* Relative addressing. */
  803         if (!priv->curpathlen) {
  804             /* Relative addressing without a current path. So we
  805                select the MF first. */
  806             r = select_part(card, MCRD_SEL_MF, pathptr[0], file);
  807             LOG_TEST_RET(card->ctx, r, "unable to select MF");
  808             priv->curpath[0] = pathptr[0];
  809             priv->curpathlen = 1;
  810             priv->is_ef = 0;
  811         }
  812         if (priv->is_ef) {
  813             if(!(priv->curpathlen > 1))
  814                 return SC_ERROR_INTERNAL;
  815             priv->curpathlen--;
  816             priv->is_ef = 0;
  817         }
  818         /* Free the previously allocated file so we do not leak memory here */
  819         if (file) {
  820             sc_file_free(*file);
  821             *file = NULL;
  822         }
  823         r = select_down(card, pathptr, pathlen, 0, file);
  824     }
  825     return r;
  826 }
  827 
  828 static int
  829 select_file_by_fid(sc_card_t * card, unsigned short *pathptr,
  830             size_t pathlen, sc_file_t ** file)
  831 {
  832     struct mcrd_priv_data *priv = DRVDATA(card);
  833     int r;
  834 
  835     SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  836 
  837     if (!(!priv->curpathlen || priv->curpath[0] == MFID))
  838         return SC_ERROR_INTERNAL;
  839 
  840     if (pathlen > 1)
  841         return SC_ERROR_INVALID_ARGUMENTS;
  842 
  843     if (pathlen && *pathptr == 0x3FFF)
  844         return 0;
  845 
  846     if (!pathlen) {
  847         /* re-select the current one if needed. */
  848         if (!file)
  849             r = 0;  /* The caller did not request the fci. */
  850         else if (!priv->curpathlen) {
  851             /* There is no current file. */
  852             r = SC_ERROR_INTERNAL;
  853         } else {
  854             if (!(priv->curpathlen > 1))
  855                 return SC_ERROR_INTERNAL;
  856             priv->curpathlen--;
  857             priv->is_ef = 0;
  858             r = select_down(card, pathptr, 1, 0, file);
  859         }
  860     } else if (pathptr[0] == MFID) {
  861         /* MF requested: clear the cache and select it. */
  862         priv->curpathlen = 0;
  863         r = select_part(card, MCRD_SEL_MF, MFID, file);
  864         LOG_TEST_RET(card->ctx, r, "unable to select MF");
  865         priv->curpath[0] = MFID;
  866         priv->curpathlen = 1;
  867         priv->is_ef = 0;
  868     } else {
  869         /* Relative addressing. */
  870         if (!priv->curpathlen) {
  871             /* Relative addressing without a current path. So we
  872                select the MF first. */
  873             r = select_part(card, MCRD_SEL_MF, pathptr[0], file);
  874             LOG_TEST_RET(card->ctx, r, "unable to select MF");
  875             priv->curpath[0] = pathptr[0];
  876             priv->curpathlen = 1;
  877             priv->is_ef = 0;
  878         }
  879         if (priv->is_ef) {
  880             if (!(priv->curpathlen > 1))
  881                 return SC_ERROR_INTERNAL;
  882             priv->curpathlen--;
  883             priv->is_ef = 0;
  884         }
  885         /* Free the previously allocated file so we do not leak memory here */
  886         if (file) {
  887             sc_file_free(*file);
  888             *file = NULL;
  889         }
  890         r = select_down(card, pathptr, 1, 0, file);
  891     }
  892 
  893     return r;
  894 }
  895 
  896 /* This drivers select command handler. */
  897 static int
  898 mcrd_select_file(sc_card_t * card, const sc_path_t * path, sc_file_t ** file)
  899 {
  900     struct mcrd_priv_data *priv = DRVDATA(card);
  901     int r = 0;
  902 
  903     SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE);
  904 
  905     if (path->type == SC_PATH_TYPE_DF_NAME) {
  906         if (path->len > 16)
  907             return SC_ERROR_INVALID_ARGUMENTS;
  908         r = do_select(card, MCRD_SEL_AID, path->value, path->len, file);
  909         priv->curpathlen = 0;
  910     } else {
  911         unsigned short int pathtmp[SC_MAX_PATH_SIZE / 2];
  912         unsigned short int *pathptr;
  913         int samepath = 1;
  914         size_t pathlen, n;
  915 
  916         if ((path->len & 1) || path->len > sizeof(pathtmp))
  917             return SC_ERROR_INVALID_ARGUMENTS;
  918 
  919         memset(pathtmp, 0, sizeof pathtmp);
  920         pathptr = pathtmp;
  921         for (n = 0; n < path->len; n += 2)
  922             pathptr[n >> 1] =
  923                 (unsigned short)((path->value[n] << 8) | path->value[n + 1]);
  924         pathlen = path->len >> 1;
  925 
  926         if (pathlen == priv->curpathlen && priv->is_ef != 2) {
  927             for (n = 0; n < pathlen; n++) {
  928                 if (priv->curpath[n] != pathptr[n]) {
  929                     samepath = 0;
  930                     break;
  931                 }
  932             }
  933         } else if (priv->curpathlen < pathlen && priv->is_ef != 2) {
  934             for (n = 0; n < priv->curpathlen; n++) {
  935                 if (priv->curpath[n] != pathptr[n]) {
  936                     samepath = 0;
  937                     break;
  938                 }
  939             }
  940             pathptr = pathptr + n;
  941             pathlen = pathlen - n;
  942         }
  943 
  944         if (samepath != 1 || priv->is_ef == 0 || priv->is_ef == 1) {
  945             if (path->type == SC_PATH_TYPE_PATH)
  946                 r = select_file_by_path(card, pathptr, pathlen, file);
  947             else {  /* SC_PATH_TYPE_FILEID */
  948                 r = select_file_by_fid(card, pathptr, pathlen, file);
  949             }
  950         }
  951     }
  952 
  953     return r;
  954 }
  955 
  956 /* It seems that MICARDO does not fully comply with ISO, so I use
  957    values gathered from peeking actual signing operations using a
  958    different system.
  959    It has been generalized [?] and modified by information coming from
  960    openpgp card implementation, EstEID 'manual' and some other sources. -mp
  961    */
  962 static int mcrd_set_security_env(sc_card_t * card,
  963                  const sc_security_env_t * env, int se_num)
  964 {
  965     struct mcrd_priv_data *priv;
  966     sc_apdu_t apdu;
  967     u8 sbuf[5] = {0x83, 0x03, 0x80, 0, 0};
  968     int r = 0, locked = 0;
  969 
  970     if (card == NULL || env == NULL)
  971         return SC_ERROR_INTERNAL;
  972     LOG_FUNC_CALLED(card->ctx);
  973     priv = DRVDATA(card);
  974 
  975     /* some sanity checks */
  976     if (env->flags & SC_SEC_ENV_ALG_PRESENT) {
  977         if (env->algorithm != SC_ALGORITHM_RSA &&
  978             (is_esteid_card(card) && env->algorithm != SC_ALGORITHM_EC))
  979             return SC_ERROR_INVALID_ARGUMENTS;
  980     }
  981     if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT)
  982         || env->key_ref_len != 1)
  983         return SC_ERROR_INVALID_ARGUMENTS;
  984 
  985     switch (env->operation) {
  986     case SC_SEC_OPERATION_DECIPHER:
  987     case SC_SEC_OPERATION_DERIVE:
  988         sc_log(card->ctx, "Using keyref %d to decipher\n", env->key_ref[0]);
  989         mcrd_delete_ref_to_authkey(card);
  990         mcrd_delete_ref_to_signkey(card);
  991         break;
  992     case SC_SEC_OPERATION_SIGN:
  993         sc_log(card->ctx, "Using keyref %d to sign\n", env->key_ref[0]);
  994         break;
  995     default:
  996         return SC_ERROR_INVALID_ARGUMENTS;
  997     }
  998     priv->sec_env = *env;
  999     if (is_esteid_card(card)) {
 1000         return 0;
 1001     }
 1002 
 1003     sbuf[3] = env->key_ref[0];
 1004     switch (env->operation) {
 1005     case SC_SEC_OPERATION_DECIPHER:
 1006     case SC_SEC_OPERATION_DERIVE:
 1007         sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB8, sbuf, 5, NULL, 0);
 1008         break;
 1009     case SC_SEC_OPERATION_SIGN:
 1010         sc_format_apdu_ex(&apdu, 0x00, 0x22, 0x41, 0xB6, sbuf, 5, NULL, 0);
 1011         break;
 1012     default:
 1013         return SC_ERROR_INVALID_ARGUMENTS;
 1014     }
 1015 
 1016     if (se_num > 0) {
 1017         r = sc_lock(card);
 1018         LOG_TEST_RET(card->ctx, r, "sc_lock() failed");
 1019         locked = 1;
 1020     }
 1021     if (apdu.datalen != 0) {
 1022         r = sc_transmit_apdu(card, &apdu);
 1023         if (r) {
 1024             sc_log(card->ctx,
 1025                 "%s: APDU transmit failed", sc_strerror(r));
 1026             goto err;
 1027         }
 1028         r = sc_check_sw(card, apdu.sw1, apdu.sw2);
 1029         if (r) {
 1030             sc_log(card->ctx,
 1031                 "%s: Card returned error", sc_strerror(r));
 1032             goto err;
 1033         }
 1034     }
 1035     if (se_num <= 0)
 1036         return 0;
 1037     sc_unlock(card);
 1038     LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
 1039     return sc_check_sw(card, apdu.sw1, apdu.sw2);
 1040 err:
 1041     if (locked)
 1042         sc_unlock(card);
 1043     return r;
 1044 }
 1045 
 1046 /* heavily modified by -mp */
 1047 static int mcrd_compute_signature(sc_card_t * card,
 1048                     const u8 * data, size_t datalen,
 1049                     u8 * out, size_t outlen)
 1050 {
 1051     struct mcrd_priv_data *priv = DRVDATA(card);
 1052     sc_security_env_t *env = NULL;
 1053     int r;
 1054     sc_apdu_t apdu;
 1055 
 1056     if (data == NULL || out == NULL)
 1057         return SC_ERROR_INVALID_ARGUMENTS;
 1058     env = &priv->sec_env;
 1059 
 1060     LOG_FUNC_CALLED(card->ctx);
 1061     if (env->operation != SC_SEC_OPERATION_SIGN)
 1062         return SC_ERROR_INVALID_ARGUMENTS;
 1063     if (datalen > 255)
 1064         SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
 1065 
 1066     sc_log(card->ctx,
 1067          "Will compute signature (%d) for %"SC_FORMAT_LEN_SIZE_T"u (0x%02"SC_FORMAT_LEN_SIZE_T"x) bytes using key %d algorithm %d flags %d\n",
 1068          env->operation, datalen, datalen, env->key_ref[0],
 1069          env->algorithm, env->algorithm_flags);
 1070 
 1071     if (env->key_ref[0] == 1) /* authentication key */
 1072         sc_format_apdu_ex(&apdu, 0x00, 0x88, 0, 0, data, datalen, out, MIN(0x80U, outlen));
 1073     else
 1074         sc_format_apdu_ex(&apdu, 0x00, 0x2A, 0x9E, 0x9A, data, datalen, out, MIN(0x80U, outlen));
 1075     r = sc_transmit_apdu(card, &apdu);
 1076     LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
 1077     r = sc_check_sw(card, apdu.sw1, apdu.sw2);
 1078     LOG_TEST_RET(card->ctx, r, "Card returned error");
 1079 
 1080     SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, (int)apdu.resplen);
 1081 }
 1082 
 1083 static int mcrd_decipher(struct sc_card *card,
 1084                          const u8 * crgram, size_t crgram_len,
 1085                          u8 * out, size_t outlen)
 1086 {
 1087     sc_security_env_t *env = NULL;
 1088     int r = 0;
 1089     size_t sbuf_len = 0;
 1090     sc_apdu_t apdu;
 1091     u8 *sbuf = NULL;
 1092     struct sc_asn1_entry asn1_control[2], asn1_ephermal[2], asn1_public[2];
 1093 
 1094     if (card == NULL || crgram == NULL || out == NULL)
 1095         return SC_ERROR_INVALID_ARGUMENTS;
 1096     env = &DRVDATA(card)->sec_env;
 1097 
 1098     LOG_FUNC_CALLED(card->ctx);
 1099     if (env->operation != SC_SEC_OPERATION_DERIVE)
 1100         SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, iso_ops->decipher(card, crgram, crgram_len, out, outlen));
 1101     if (crgram_len > 255)
 1102         SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
 1103 
 1104     sc_log(card->ctx, 
 1105          "Will derive (%d) for %"SC_FORMAT_LEN_SIZE_T"u (0x%02"SC_FORMAT_LEN_SIZE_T"x) bytes using key %d algorithm %d flags %d\n",
 1106          env->operation, crgram_len, crgram_len, env->key_ref[0],
 1107          env->algorithm, env->algorithm_flags);
 1108 
 1109     // Encode TLV
 1110     sc_copy_asn1_entry(c_asn1_control, asn1_control);
 1111     sc_copy_asn1_entry(c_asn1_ephermal, asn1_ephermal);
 1112     sc_copy_asn1_entry(c_asn1_public, asn1_public);
 1113     sc_format_asn1_entry(asn1_public + 0, (void*)crgram, &crgram_len, 1);
 1114     sc_format_asn1_entry(asn1_ephermal + 0, &asn1_public, NULL, 1);
 1115     sc_format_asn1_entry(asn1_control + 0, &asn1_ephermal, NULL, 1);
 1116     r = sc_asn1_encode(card->ctx, asn1_control, &sbuf, &sbuf_len);
 1117     LOG_TEST_RET(card->ctx, r, "Error encoding TLV.");
 1118 
 1119     // Create APDU
 1120     sc_format_apdu_ex(&apdu, 0x00, 0x2A, 0x80, 0x86, sbuf, sbuf_len, out, MIN(0x80U, outlen));
 1121     r = sc_transmit_apdu(card, &apdu);
 1122     sc_mem_clear(sbuf, sbuf_len);
 1123     free(sbuf);
 1124     LOG_TEST_RET(card->ctx, r, "APDU transmit failed");
 1125 
 1126     r = sc_check_sw(card, apdu.sw1, apdu.sw2);
 1127     LOG_TEST_RET(card->ctx, r, "Card returned error");
 1128 
 1129     SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, (int)apdu.resplen);
 1130 }
 1131 
 1132 /* added by -mp, to give pin information in the card driver (pkcs15emu->driver needed) */
 1133 static int mcrd_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data *data,
 1134             int *tries_left)
 1135 {
 1136     int r;
 1137     LOG_FUNC_CALLED(card->ctx);
 1138     data->pin1.offset = 5;
 1139     data->pin2.offset = 5;
 1140 
 1141     if (is_esteid_card(card) && data->cmd == SC_PIN_CMD_GET_INFO) {
 1142         sc_path_t tmppath;
 1143         u8 buf[16];
 1144         unsigned int ref_to_record[] = {3,1,2};
 1145 
 1146         /* the file with key pin info (tries left) 4.5 EF_PwdC */
 1147         /* XXX: cheat the file path cache by always starting fresh from MF */
 1148         r = sc_select_file (card, sc_get_mf_path(), NULL);
 1149         if (r < 0)
 1150             return SC_ERROR_INTERNAL;
 1151 
 1152         sc_format_path ("3f000016", &tmppath);
 1153         r = sc_select_file (card, &tmppath, NULL);
 1154         if (r < 0)
 1155             return SC_ERROR_INTERNAL;
 1156 
 1157         /* read the number of tries left for the PIN */
 1158         r = sc_read_record (card, ref_to_record[data->pin_reference], buf, sizeof(buf), SC_RECORD_BY_REC_NR);
 1159         if (r < 0)
 1160             return SC_ERROR_INTERNAL;
 1161         if (buf[0] != 0x80 || buf[3] != 0x90)
 1162             return SC_ERROR_INTERNAL;
 1163         data->pin1.tries_left = buf[5];
 1164         data->pin1.max_tries = buf[2];
 1165         data->pin1.logged_in = SC_PIN_STATE_UNKNOWN;
 1166         return SC_SUCCESS;
 1167     }
 1168 
 1169     if (card->type == SC_CARD_TYPE_MCRD_GENERIC) {
 1170         sc_log(card->ctx, "modify pin reference for D-Trust\n");
 1171         if (data->pin_reference == 0x02)
 1172             data->pin_reference = data->pin_reference | 0x80;
 1173     }
 1174     SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, iso_ops->pin_cmd(card, data, tries_left));
 1175 }
 1176 
 1177 /* Driver binding */
 1178 static struct sc_card_driver *sc_get_driver(void)
 1179 {
 1180     struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
 1181     if (iso_ops == NULL)
 1182         iso_ops = iso_drv->ops;
 1183 
 1184     mcrd_ops = *iso_drv->ops;
 1185     mcrd_ops.match_card = mcrd_match_card;
 1186     mcrd_ops.init = mcrd_init;
 1187     mcrd_ops.finish = mcrd_finish;
 1188     mcrd_ops.select_file = mcrd_select_file;
 1189     mcrd_ops.set_security_env = mcrd_set_security_env;
 1190     mcrd_ops.compute_signature = mcrd_compute_signature;
 1191     mcrd_ops.decipher = mcrd_decipher;
 1192     mcrd_ops.pin_cmd = mcrd_pin_cmd;
 1193 
 1194     return &mcrd_drv;
 1195 }
 1196 
 1197 struct sc_card_driver *sc_get_mcrd_driver(void)
 1198 {
 1199     return sc_get_driver();
 1200 }