"Fossies" - the Fresh Open Source Software Archive

Member "opensc-0.22.0/src/libopensc/pkcs15.c" (10 Aug 2021, 85294 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 "pkcs15.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  * pkcs15.c: PKCS #15 general functions
    3  *
    4  * Copyright (C) 2001, 2002  Juha Yrjölä <juha.yrjola@iki.fi>
    5  *
    6  * This library is free software; you can redistribute it and/or
    7  * modify it under the terms of the GNU Lesser General Public
    8  * License as published by the Free Software Foundation; either
    9  * version 2.1 of the License, or (at your option) any later version.
   10  *
   11  * This library is distributed in the hope that it will be useful,
   12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   14  * Lesser General Public License for more details.
   15  *
   16  * You should have received a copy of the GNU Lesser General Public
   17  * License along with this library; if not, write to the Free Software
   18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   19  */
   20 
   21 #ifdef HAVE_CONFIG_H
   22 #include <config.h>
   23 #endif
   24 
   25 #include <stdlib.h>
   26 #include <string.h>
   27 #include <stdio.h>
   28 #include <assert.h>
   29 #include <ctype.h>
   30 
   31 #include "cardctl.h"
   32 #include "internal.h"
   33 #include "pkcs15.h"
   34 #include "asn1.h"
   35 #include "common/libscdl.h"
   36 
   37 #ifdef ENABLE_OPENSSL
   38 #include <openssl/sha.h>
   39 #endif
   40 
   41 #ifdef HAVE_SYS_TIME_H
   42 #include <sys/time.h>
   43 #endif
   44 
   45 static const struct sc_asn1_entry c_asn1_twlabel[] = {
   46     { "twlabel", SC_ASN1_UTF8STRING, SC_ASN1_TAG_UTF8STRING, 0, NULL, NULL },
   47     { NULL, 0, 0, 0, NULL, NULL }
   48 };
   49 
   50 static const struct sc_asn1_entry c_asn1_algorithm_info[7] = {
   51     { "reference",      SC_ASN1_INTEGER,    SC_ASN1_TAG_INTEGER,    0, NULL, NULL },
   52     { "algorithmPKCS#11",   SC_ASN1_INTEGER,    SC_ASN1_TAG_INTEGER,    0, NULL, NULL },
   53     { "parameters",     SC_ASN1_CHOICE,     0,          0, NULL, NULL },
   54     { "supportedOperations",SC_ASN1_BIT_FIELD,  SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL },
   55     { "objId",      SC_ASN1_OBJECT,     SC_ASN1_TAG_OBJECT, SC_ASN1_OPTIONAL, NULL, NULL },
   56     { "algRef",     SC_ASN1_INTEGER,    SC_ASN1_TAG_INTEGER,    SC_ASN1_OPTIONAL, NULL, NULL },
   57     { NULL, 0, 0, 0, NULL, NULL }
   58 };
   59 
   60 static const struct sc_asn1_entry c_asn1_algorithm_info_parameters[3] = {
   61     { "PKCS15RSAParameters",SC_ASN1_NULL,       SC_ASN1_TAG_NULL,   0, NULL, NULL },
   62     { "PKCS15ECParameters", SC_ASN1_OBJECT,     SC_ASN1_TAG_OBJECT, 0, NULL, NULL },
   63     { NULL, 0, 0, 0, NULL, NULL }
   64 };
   65 
   66 /*
   67  * in src/libopensc/types.h SC_MAX_SUPPORTED_ALGORITHMS  defined as 16
   68  */
   69 static const struct sc_asn1_entry c_asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1] = {
   70     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   71     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   72     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   73     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   74     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   75     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   76     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   77     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   78     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   79     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   80     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   81     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   82     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   83     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   84     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   85     { "algorithmInfo", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
   86     { NULL, 0, 0, 0, NULL, NULL }
   87 };
   88 
   89 #define C_ASN1_LAST_UPDATE_SIZE 3
   90 static const struct sc_asn1_entry c_asn1_last_update[C_ASN1_LAST_UPDATE_SIZE] = {
   91     { "generalizedTime",    SC_ASN1_GENERALIZEDTIME, SC_ASN1_TAG_GENERALIZEDTIME,   SC_ASN1_OPTIONAL, NULL, NULL },
   92     { "referencedTime", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS,  SC_ASN1_OPTIONAL, NULL, NULL },
   93     { NULL, 0, 0, 0, NULL, NULL }
   94 };
   95 
   96 #define C_ASN1_PROFILE_INDICATION_SIZE 3
   97 static const struct sc_asn1_entry c_asn1_profile_indication[C_ASN1_PROFILE_INDICATION_SIZE] = {
   98     { "profileOID",     SC_ASN1_OBJECT,     SC_ASN1_TAG_OBJECT,     SC_ASN1_OPTIONAL, NULL, NULL },
   99     { "profileName",    SC_ASN1_UTF8STRING, SC_ASN1_TAG_UTF8STRING, SC_ASN1_OPTIONAL, NULL, NULL },
  100     { NULL, 0, 0, 0, NULL, NULL }
  101 };
  102 
  103 #define C_ASN1_TOKI_ATTRS_SIZE 15
  104 static const struct sc_asn1_entry c_asn1_toki_attrs[C_ASN1_TOKI_ATTRS_SIZE] = {
  105     { "version",        SC_ASN1_INTEGER,        SC_ASN1_TAG_INTEGER, 0, NULL, NULL },
  106     { "serialNumber",   SC_ASN1_OCTET_STRING,   SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
  107     { "manufacturerID", SC_ASN1_UTF8STRING,     SC_ASN1_TAG_UTF8STRING, SC_ASN1_OPTIONAL, NULL, NULL },
  108     { "label",      SC_ASN1_UTF8STRING,     SC_ASN1_CTX | 0, SC_ASN1_OPTIONAL, NULL, NULL },
  109     /* XXX the Taiwanese ID card erroneously uses explicit tagging */
  110     { "label-tw",       SC_ASN1_STRUCT,     SC_ASN1_CTX | 0 | SC_ASN1_CONS, SC_ASN1_OPTIONAL, NULL, NULL },
  111     { "tokenflags",     SC_ASN1_BIT_FIELD,      SC_ASN1_TAG_BIT_STRING, 0, NULL, NULL },
  112     { "seInfo",     SC_ASN1_SE_INFO,        SC_ASN1_CONS | SC_ASN1_TAG_SEQUENCE, SC_ASN1_OPTIONAL, NULL, NULL },
  113     { "recordInfo",     SC_ASN1_STRUCT,     SC_ASN1_CONS | SC_ASN1_CTX | 1, SC_ASN1_OPTIONAL, NULL, NULL },
  114     { "supportedAlgorithms", SC_ASN1_STRUCT,    SC_ASN1_CONS | SC_ASN1_CTX | 2, SC_ASN1_OPTIONAL, NULL, NULL },
  115     { "issuerId",       SC_ASN1_UTF8STRING,     SC_ASN1_CTX | 3, SC_ASN1_OPTIONAL, NULL, NULL },
  116     { "holderId",       SC_ASN1_UTF8STRING,     SC_ASN1_CTX | 4, SC_ASN1_OPTIONAL, NULL, NULL },
  117     { "lastUpdate",     SC_ASN1_STRUCT,     SC_ASN1_CONS | SC_ASN1_CTX | 5, SC_ASN1_OPTIONAL, NULL, NULL },
  118     { "preferredLanguage", SC_ASN1_PRINTABLESTRING, SC_ASN1_TAG_PRINTABLESTRING, SC_ASN1_OPTIONAL, NULL, NULL },
  119     { "profileIndication", SC_ASN1_STRUCT,      SC_ASN1_CONS | SC_ASN1_CTX | 6, SC_ASN1_OPTIONAL, NULL, NULL },
  120     { NULL, 0, 0, 0, NULL, NULL }
  121 };
  122 
  123 static const struct sc_asn1_entry c_asn1_tokeninfo[] = {
  124     { "TokenInfo", SC_ASN1_STRUCT, SC_ASN1_CONS | SC_ASN1_TAG_SEQUENCE, 0, NULL, NULL },
  125     { NULL, 0, 0, 0, NULL, NULL }
  126 };
  127 
  128 static void sc_pkcs15_free_unusedspace(struct sc_pkcs15_card *);
  129 static void sc_pkcs15_remove_dfs(struct sc_pkcs15_card *);
  130 static void sc_pkcs15_remove_objects(struct sc_pkcs15_card *);
  131 static int sc_pkcs15_aux_get_md_guid(struct sc_pkcs15_card *, const struct sc_pkcs15_object *,
  132         unsigned, unsigned char *, size_t *);
  133 static void sc_pkcs15_clear_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo);
  134 
  135 int sc_pkcs15_parse_tokeninfo(sc_context_t *ctx,
  136     sc_pkcs15_tokeninfo_t *ti, const u8 *buf, size_t blen)
  137 {
  138     int r;
  139     size_t ii;
  140     u8 serial[128];
  141     size_t serial_len = sizeof(serial);
  142     u8 mnfid[SC_PKCS15_MAX_LABEL_SIZE];
  143     size_t mnfid_len  = sizeof(mnfid) - 1;
  144     u8 label[SC_PKCS15_MAX_LABEL_SIZE];
  145     size_t label_len = sizeof(label) - 1;
  146     u8 last_update[32], profile_indication[SC_PKCS15_MAX_LABEL_SIZE];
  147     size_t lupdate_len = sizeof(last_update) - 1, pi_len = sizeof(profile_indication) - 1;
  148     size_t flags_len   = sizeof(ti->flags);
  149     u8 preferred_language[3];
  150     size_t lang_length = sizeof(preferred_language);
  151     struct sc_asn1_entry asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1],
  152             asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7],
  153             asn1_algo_infos_parameters[SC_MAX_SUPPORTED_ALGORITHMS][3];
  154     size_t reference_len = sizeof(ti->supported_algos[0].reference);
  155     size_t mechanism_len = sizeof(ti->supported_algos[0].mechanism);
  156     size_t parameter_len = sizeof(ti->supported_algos[0].parameters);
  157     size_t operations_len = sizeof(ti->supported_algos[0].operations);
  158     size_t algo_ref_len = sizeof(ti->supported_algos[0].algo_ref);
  159 
  160     struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE];
  161     struct sc_asn1_entry asn1_profile_indication[C_ASN1_PROFILE_INDICATION_SIZE];
  162     struct sc_asn1_entry asn1_toki_attrs[C_ASN1_TOKI_ATTRS_SIZE], asn1_tokeninfo[3], asn1_twlabel[3];
  163 
  164     memset(last_update, 0, sizeof(last_update));
  165     memset(label, 0, sizeof(label));
  166     memset(profile_indication, 0, sizeof(profile_indication));
  167     memset(mnfid, 0, sizeof(mnfid));
  168 
  169     sc_copy_asn1_entry(c_asn1_twlabel, asn1_twlabel);
  170     sc_copy_asn1_entry(c_asn1_toki_attrs, asn1_toki_attrs);
  171     sc_copy_asn1_entry(c_asn1_tokeninfo, asn1_tokeninfo);
  172     sc_copy_asn1_entry(c_asn1_last_update, asn1_last_update);
  173     sc_format_asn1_entry(asn1_twlabel, label, &label_len, 0);
  174     sc_copy_asn1_entry(c_asn1_profile_indication, asn1_profile_indication);
  175 
  176     for (ii=0; ii<SC_MAX_SUPPORTED_ALGORITHMS; ii++) {
  177         sc_copy_asn1_entry(c_asn1_algorithm_info, asn1_algo_infos[ii]);
  178         sc_copy_asn1_entry(c_asn1_algorithm_info_parameters,
  179             asn1_algo_infos_parameters[ii]);
  180     }
  181     sc_copy_asn1_entry(c_asn1_supported_algorithms, asn1_supported_algorithms);
  182 
  183     for (ii=0; ii<SC_MAX_SUPPORTED_ALGORITHMS; ii++)   {
  184         sc_format_asn1_entry(asn1_algo_infos[ii] + 0, &ti->supported_algos[ii].reference, &reference_len, 0);
  185         sc_format_asn1_entry(asn1_algo_infos[ii] + 1, &ti->supported_algos[ii].mechanism, &mechanism_len, 0);
  186         sc_format_asn1_entry(asn1_algo_infos[ii] + 2,
  187             asn1_algo_infos_parameters[ii], NULL, 0);
  188         sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 0,
  189             NULL, NULL, 0);
  190         sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 1,
  191             &ti->supported_algos[ii].parameters, &parameter_len, 0);
  192         sc_format_asn1_entry(asn1_algo_infos[ii] + 3, &ti->supported_algos[ii].operations, &operations_len, 0);
  193         sc_format_asn1_entry(asn1_algo_infos[ii] + 4, &ti->supported_algos[ii].algo_id, NULL, 1);
  194         sc_format_asn1_entry(asn1_algo_infos[ii] + 5, &ti->supported_algos[ii].algo_ref, &algo_ref_len, 0);
  195         sc_format_asn1_entry(asn1_supported_algorithms + ii, asn1_algo_infos[ii], NULL, 0);
  196     }
  197 
  198     sc_format_asn1_entry(asn1_last_update + 0, last_update, &lupdate_len, 0);
  199     sc_format_asn1_entry(asn1_last_update + 1, &ti->last_update.path, NULL, 0);
  200 
  201     sc_format_asn1_entry(asn1_profile_indication + 0, &ti->profile_indication.oid, NULL, 0);
  202     sc_format_asn1_entry(asn1_profile_indication + 1, profile_indication, &pi_len, 0);
  203 
  204     sc_format_asn1_entry(asn1_toki_attrs + 0, &ti->version, NULL, 0);
  205     sc_format_asn1_entry(asn1_toki_attrs + 1, serial, &serial_len, 0);
  206     sc_format_asn1_entry(asn1_toki_attrs + 2, mnfid, &mnfid_len, 0);
  207     sc_format_asn1_entry(asn1_toki_attrs + 3, label, &label_len, 0);
  208     sc_format_asn1_entry(asn1_toki_attrs + 4, asn1_twlabel, NULL, 0);
  209     sc_format_asn1_entry(asn1_toki_attrs + 5, &ti->flags, &flags_len, 0);
  210     sc_format_asn1_entry(asn1_toki_attrs + 6, &ti->seInfo, &ti->num_seInfo, 0);
  211     sc_format_asn1_entry(asn1_toki_attrs + 7, NULL, NULL, 0);
  212     sc_format_asn1_entry(asn1_toki_attrs + 8, asn1_supported_algorithms, NULL, 0);
  213     sc_format_asn1_entry(asn1_toki_attrs + 9, NULL, NULL, 0);
  214     sc_format_asn1_entry(asn1_toki_attrs + 10, NULL, NULL, 0);
  215     sc_format_asn1_entry(asn1_toki_attrs + 11, asn1_last_update, NULL, 0);
  216     sc_format_asn1_entry(asn1_toki_attrs + 12, preferred_language, &lang_length, 0);
  217     sc_format_asn1_entry(asn1_toki_attrs + 13, asn1_profile_indication, NULL, 0);
  218     sc_format_asn1_entry(asn1_tokeninfo, asn1_toki_attrs, NULL, 0);
  219 
  220     r = sc_asn1_decode(ctx, asn1_tokeninfo, buf, blen, NULL, NULL);
  221     if (r != SC_SUCCESS) {
  222         /* The decoding could have allocated something we need to free */
  223         sc_pkcs15_clear_tokeninfo(ti);
  224         LOG_TEST_RET(ctx, r, "ASN.1 parsing of EF(TokenInfo) failed");
  225     }
  226 
  227     if (asn1_toki_attrs[1].flags & SC_ASN1_PRESENT && serial_len > 0)   {
  228         free(ti->serial_number);
  229         ti->serial_number = malloc(serial_len * 2 + 1);
  230         if (ti->serial_number == NULL)
  231             return SC_ERROR_OUT_OF_MEMORY;
  232         sc_bin_to_hex(serial, serial_len, ti->serial_number, serial_len * 2 + 1, 0);
  233         sc_log(ctx, "TokenInfo.serialNunmber '%s'", ti->serial_number);
  234     }
  235 
  236     if (ti->manufacturer_id == NULL) {
  237         if (asn1_toki_attrs[2].flags & SC_ASN1_PRESENT)
  238             ti->manufacturer_id = strdup((char *) mnfid);
  239         else
  240             ti->manufacturer_id = strdup("(unknown)");
  241         if (ti->manufacturer_id == NULL)
  242             return SC_ERROR_OUT_OF_MEMORY;
  243     }
  244     if (ti->label == NULL) {
  245         if (asn1_toki_attrs[3].flags & SC_ASN1_PRESENT ||
  246             asn1_toki_attrs[4].flags & SC_ASN1_PRESENT)
  247             ti->label = strdup((char *) label);
  248         else
  249             ti->label = strdup("(unknown)");
  250         if (ti->label == NULL)
  251             return SC_ERROR_OUT_OF_MEMORY;
  252     }
  253     if (asn1_toki_attrs[11].flags & SC_ASN1_PRESENT) {
  254         if (asn1_last_update[0].flags & SC_ASN1_PRESENT)   {
  255             sc_log(ctx, "LastUpdate.generalizedTime present");
  256             ti->last_update.gtime = strdup((char *)last_update);
  257             if (ti->last_update.gtime == NULL)
  258                 return SC_ERROR_OUT_OF_MEMORY;
  259         }
  260         else if (asn1_last_update[1].flags & SC_ASN1_PRESENT)  {
  261             sc_log(ctx, "LastUpdate.referencedTime present");
  262         }
  263     }
  264     if (asn1_toki_attrs[12].flags & SC_ASN1_PRESENT) {
  265         preferred_language[2] = 0;
  266         ti->preferred_language = strdup((char *)preferred_language);
  267         if (ti->preferred_language == NULL)
  268             return SC_ERROR_OUT_OF_MEMORY;
  269     }
  270 
  271     sc_init_oid(&ti->profile_indication.oid);
  272     if (asn1_toki_attrs[13].flags & SC_ASN1_PRESENT) {
  273         if (asn1_profile_indication[0].flags & SC_ASN1_PRESENT)   {
  274             sc_log(ctx, "ProfileIndication.oid present");
  275         }
  276         else if (asn1_profile_indication[1].flags & SC_ASN1_PRESENT)  {
  277             sc_log(ctx, "ProfileIndication.name present");
  278             ti->profile_indication.name = strdup((char *)profile_indication);
  279             if (ti->profile_indication.name == NULL)
  280                 return SC_ERROR_OUT_OF_MEMORY;
  281         }
  282     }
  283 
  284     sc_log(ctx, "LastUpdate.path '%s'", sc_print_path(&ti->last_update.path));
  285     sc_log(ctx, "ProfileIndication.name '%s'",  ti->profile_indication.name);
  286     return SC_SUCCESS;
  287 }
  288 
  289 
  290 int
  291 sc_pkcs15_encode_tokeninfo(sc_context_t *ctx, sc_pkcs15_tokeninfo_t *ti,
  292         u8 **buf, size_t *buflen)
  293 {
  294     int r, ii;
  295     size_t serial_len, mnfid_len, label_len, flags_len, last_upd_len, pi_len;
  296 
  297     struct sc_asn1_entry asn1_toki_attrs[C_ASN1_TOKI_ATTRS_SIZE];
  298     struct sc_asn1_entry asn1_tokeninfo[2];
  299     struct sc_asn1_entry asn1_supported_algorithms[SC_MAX_SUPPORTED_ALGORITHMS + 1],
  300             asn1_algo_infos[SC_MAX_SUPPORTED_ALGORITHMS][7],
  301             asn1_algo_infos_parameters[SC_MAX_SUPPORTED_ALGORITHMS][3];
  302     size_t reference_len = sizeof(ti->supported_algos[0].reference);
  303     size_t mechanism_len = sizeof(ti->supported_algos[0].mechanism);
  304     size_t parameter_len = sizeof(ti->supported_algos[0].parameters);
  305     size_t operations_len = sizeof(ti->supported_algos[0].operations);
  306     size_t algo_ref_len = sizeof(ti->supported_algos[0].algo_ref);
  307     struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE];
  308     struct sc_asn1_entry asn1_profile_indication[C_ASN1_PROFILE_INDICATION_SIZE];
  309 
  310     sc_copy_asn1_entry(c_asn1_toki_attrs, asn1_toki_attrs);
  311     sc_copy_asn1_entry(c_asn1_tokeninfo, asn1_tokeninfo);
  312     sc_copy_asn1_entry(c_asn1_last_update, asn1_last_update);
  313     sc_copy_asn1_entry(c_asn1_profile_indication, asn1_profile_indication);
  314 
  315     for (ii=0; ii<SC_MAX_SUPPORTED_ALGORITHMS && ti->supported_algos[ii].reference; ii++) {
  316         sc_copy_asn1_entry(c_asn1_algorithm_info, asn1_algo_infos[ii]);
  317         sc_copy_asn1_entry(c_asn1_algorithm_info_parameters,
  318             asn1_algo_infos_parameters[ii]);
  319     }
  320     sc_copy_asn1_entry(c_asn1_supported_algorithms, asn1_supported_algorithms);
  321 
  322     for (ii=0; ii<SC_MAX_SUPPORTED_ALGORITHMS && ti->supported_algos[ii].reference; ii++)   {
  323         sc_format_asn1_entry(asn1_algo_infos[ii] + 0, &ti->supported_algos[ii].reference, &reference_len, 1);
  324         sc_format_asn1_entry(asn1_algo_infos[ii] + 1, &ti->supported_algos[ii].mechanism, &mechanism_len, 1);
  325         sc_format_asn1_entry(asn1_algo_infos[ii] + 2,
  326             asn1_algo_infos_parameters[ii], NULL, 1);
  327         if (!sc_valid_oid(&ti->supported_algos[ii].parameters)) {
  328             sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 0,
  329                 NULL, NULL, 1);
  330         }
  331         else {
  332             sc_format_asn1_entry(asn1_algo_infos_parameters[ii] + 1,
  333                 &ti->supported_algos[ii].parameters, &parameter_len, 0);
  334         }
  335         sc_format_asn1_entry(asn1_algo_infos[ii] + 3, &ti->supported_algos[ii].operations, &operations_len, 1);
  336         sc_format_asn1_entry(asn1_algo_infos[ii] + 4, &ti->supported_algos[ii].algo_id, NULL, 1);
  337         sc_format_asn1_entry(asn1_algo_infos[ii] + 5, &ti->supported_algos[ii].algo_ref, &algo_ref_len, 1);
  338         sc_format_asn1_entry(asn1_supported_algorithms + ii, asn1_algo_infos[ii], NULL, 1);
  339     }
  340 
  341     sc_format_asn1_entry(asn1_toki_attrs + 0, &ti->version, NULL, 1);
  342     if (ti->serial_number != NULL) {
  343         u8 serial[128];
  344         serial_len = 0;
  345         if (strlen(ti->serial_number)/2 > sizeof(serial))
  346             return SC_ERROR_BUFFER_TOO_SMALL;
  347         serial_len = sizeof(serial);
  348         if (sc_hex_to_bin(ti->serial_number, serial, &serial_len) < 0)
  349             return SC_ERROR_INVALID_ARGUMENTS;
  350         sc_format_asn1_entry(asn1_toki_attrs + 1, serial, &serial_len, 1);
  351     }
  352     else   {
  353         sc_format_asn1_entry(asn1_toki_attrs + 1, NULL, NULL, 0);
  354     }
  355 
  356     if (ti->manufacturer_id != NULL) {
  357         mnfid_len = strlen(ti->manufacturer_id);
  358         sc_format_asn1_entry(asn1_toki_attrs + 2, ti->manufacturer_id, &mnfid_len, 1);
  359     }
  360     else    {
  361         sc_format_asn1_entry(asn1_toki_attrs + 2, NULL, NULL, 0);
  362     }
  363 
  364     if (ti->label != NULL) {
  365         label_len = strlen(ti->label);
  366         sc_format_asn1_entry(asn1_toki_attrs + 3, ti->label, &label_len, 1);
  367     }
  368     else   {
  369         sc_format_asn1_entry(asn1_toki_attrs + 3, NULL, NULL, 0);
  370     }
  371 
  372     if (ti->flags) {
  373         flags_len = sizeof(ti->flags);
  374         sc_format_asn1_entry(asn1_toki_attrs + 5, &ti->flags, &flags_len, 1);
  375     }
  376     else   {
  377         sc_format_asn1_entry(asn1_toki_attrs + 5, NULL, NULL, 0);
  378     }
  379 
  380     if (ti->num_seInfo)
  381         sc_format_asn1_entry(asn1_toki_attrs + 6, ti->seInfo, &ti->num_seInfo, 1);
  382     else
  383         sc_format_asn1_entry(asn1_toki_attrs + 6, NULL, NULL, 0);
  384 
  385     sc_format_asn1_entry(asn1_toki_attrs + 7, NULL, NULL, 0);
  386 
  387     if (ti->supported_algos[0].reference)
  388         sc_format_asn1_entry(asn1_toki_attrs + 8, asn1_supported_algorithms, NULL, 1);
  389     else
  390         sc_format_asn1_entry(asn1_toki_attrs + 8, NULL, NULL, 0);
  391 
  392     sc_format_asn1_entry(asn1_toki_attrs + 9, NULL, NULL, 0);
  393     sc_format_asn1_entry(asn1_toki_attrs + 10, NULL, NULL, 0);
  394 
  395     if (ti->last_update.path.len) {
  396         sc_format_asn1_entry(asn1_last_update + 0, &ti->last_update.path, NULL, 1);
  397         sc_format_asn1_entry(asn1_toki_attrs + 11, asn1_last_update, NULL, 1);
  398     }
  399     else if (ti->last_update.gtime != NULL) {
  400         last_upd_len = strlen(ti->last_update.gtime);
  401         sc_format_asn1_entry(asn1_last_update + 0, ti->last_update.gtime, &last_upd_len, 1);
  402         sc_format_asn1_entry(asn1_toki_attrs + 11, asn1_last_update, NULL, 1);
  403     }
  404     else   {
  405         sc_format_asn1_entry(asn1_toki_attrs + 11, NULL, NULL, 0);
  406     }
  407     sc_format_asn1_entry(asn1_toki_attrs + 12, NULL, NULL, 0);
  408 
  409     if (sc_valid_oid(&ti->profile_indication.oid))   {
  410         sc_format_asn1_entry(asn1_profile_indication + 0, &ti->profile_indication.oid, NULL, 1);
  411         sc_format_asn1_entry(asn1_toki_attrs + 13, asn1_profile_indication, NULL, 1);
  412     }
  413     else if (ti->profile_indication.name)   {
  414         pi_len = strlen(ti->profile_indication.name);
  415         sc_format_asn1_entry(asn1_profile_indication + 1, ti->profile_indication.name, &pi_len, 1);
  416         sc_format_asn1_entry(asn1_toki_attrs + 13, asn1_profile_indication, NULL, 1);
  417     }
  418     else    {
  419         sc_format_asn1_entry(asn1_toki_attrs + 13, NULL, NULL, 0);
  420     }
  421 
  422     sc_format_asn1_entry(asn1_tokeninfo, asn1_toki_attrs, NULL, 1);
  423 
  424     r = sc_asn1_encode(ctx, asn1_tokeninfo, buf, buflen);
  425     LOG_TEST_RET(ctx, r, "sc_asn1_encode() failed");
  426 
  427     return SC_SUCCESS;
  428 }
  429 
  430 static const struct sc_asn1_entry c_asn1_ddo[] = {
  431     { "oid",       SC_ASN1_OBJECT, SC_ASN1_TAG_OBJECT, SC_ASN1_OPTIONAL, NULL, NULL },
  432     { "odfPath",       SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_TAG_SEQUENCE, SC_ASN1_OPTIONAL, NULL, NULL },
  433     { "tokenInfoPath", SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_CTX | 0, SC_ASN1_OPTIONAL, NULL, NULL },
  434     { "unusedPath",    SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_CTX | 1, SC_ASN1_OPTIONAL, NULL, NULL },
  435 /* According to PKCS#15 v1.1 here is the place for the future extensions.
  436  * The following data are used when ODF record points to the xDF files in a different application.
  437  */
  438     { "ddoIIN",    SC_ASN1_OCTET_STRING, SC_ASN1_APP | 0x02, SC_ASN1_OPTIONAL, NULL, NULL },
  439     { "ddoAID",    SC_ASN1_OCTET_STRING, SC_ASN1_APP | 0x0F, SC_ASN1_OPTIONAL, NULL, NULL },
  440     { NULL, 0, 0, 0, NULL, NULL }
  441 };
  442 
  443 static void
  444 fix_authentic_ddo(struct sc_pkcs15_card *p15card)
  445 {
  446     /* AuthentIC v3.2 card has invalid ODF and tokenInfo paths encoded into DDO.
  447      * Cleanup this attributes -- default values must be OK.
  448      */
  449     if (p15card->card->type == SC_CARD_TYPE_OBERTHUR_AUTHENTIC_3_2)   {
  450         sc_file_free(p15card->file_odf);
  451         p15card->file_odf = NULL;
  452         sc_file_free(p15card->file_tokeninfo);
  453         p15card->file_tokeninfo = NULL;
  454     }
  455 }
  456 
  457 static int
  458 parse_ddo(struct sc_pkcs15_card *p15card, const u8 * buf, size_t buflen)
  459 {
  460     struct sc_context *ctx = p15card->card->ctx;
  461     struct sc_asn1_entry asn1_ddo[7];
  462     sc_path_t odf_path, ti_path, us_path;
  463     struct sc_iid iid;
  464     struct sc_aid aid;
  465     int r;
  466 
  467     LOG_FUNC_CALLED(ctx);
  468 
  469     iid.len = sizeof(iid.value);
  470     aid.len = sizeof(aid.value);
  471 
  472     sc_copy_asn1_entry(c_asn1_ddo, asn1_ddo);
  473     sc_format_asn1_entry(asn1_ddo + 1, &odf_path, NULL, 0);
  474     sc_format_asn1_entry(asn1_ddo + 2, &ti_path, NULL, 0);
  475     sc_format_asn1_entry(asn1_ddo + 3, &us_path, NULL, 0);
  476     sc_format_asn1_entry(asn1_ddo + 4, iid.value, &iid.len, 0);
  477     sc_format_asn1_entry(asn1_ddo + 5, aid.value, &aid.len, 0);
  478 
  479     r = sc_asn1_decode(ctx, asn1_ddo, buf, buflen, NULL, NULL);
  480     LOG_TEST_RET(ctx, r, "DDO parsing failed");
  481 
  482     if (asn1_ddo[1].flags & SC_ASN1_PRESENT) {
  483         sc_file_free(p15card->file_odf);
  484         p15card->file_odf = sc_file_new();
  485         if (p15card->file_odf == NULL)
  486             goto mem_err;
  487         p15card->file_odf->path = odf_path;
  488     }
  489     if (asn1_ddo[2].flags & SC_ASN1_PRESENT) {
  490         sc_file_free(p15card->file_tokeninfo);
  491         p15card->file_tokeninfo = sc_file_new();
  492         if (p15card->file_tokeninfo == NULL)
  493             goto mem_err;
  494         p15card->file_tokeninfo->path = ti_path;
  495     }
  496     if (asn1_ddo[3].flags & SC_ASN1_PRESENT) {
  497         sc_file_free(p15card->file_unusedspace);
  498         p15card->file_unusedspace = sc_file_new();
  499         if (p15card->file_unusedspace == NULL)
  500             goto mem_err;
  501         p15card->file_unusedspace->path = us_path;
  502     }
  503     if (asn1_ddo[4].flags & SC_ASN1_PRESENT) {
  504         sc_debug(ctx, SC_LOG_DEBUG_ASN1, "DDO.IID '%s'", sc_dump_hex(iid.value, iid.len));
  505         memcpy(&p15card->app->ddo.iid, &iid, sizeof(struct sc_iid));
  506     }
  507     if (asn1_ddo[5].flags & SC_ASN1_PRESENT) {
  508         sc_debug(ctx, SC_LOG_DEBUG_ASN1, "DDO.AID '%s'", sc_dump_hex(aid.value, aid.len));
  509         memcpy(&p15card->app->ddo.aid, &aid, sizeof(struct sc_aid));
  510     }
  511 
  512     fix_authentic_ddo(p15card);
  513     LOG_FUNC_RETURN(ctx, SC_SUCCESS);
  514 mem_err:
  515     sc_file_free(p15card->file_odf);
  516     p15card->file_odf = NULL;
  517     sc_file_free(p15card->file_tokeninfo);
  518     p15card->file_tokeninfo = NULL;
  519     sc_file_free(p15card->file_unusedspace);
  520     p15card->file_unusedspace = NULL;
  521     LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
  522 }
  523 
  524 
  525 char *
  526 sc_pkcs15_get_lastupdate(struct sc_pkcs15_card *p15card)
  527 {
  528     struct sc_context *ctx  = p15card->card->ctx;
  529     struct sc_file *file = NULL;
  530     struct sc_asn1_entry asn1_last_update[C_ASN1_LAST_UPDATE_SIZE];
  531     unsigned char *content, last_update[32];
  532     size_t lupdate_len = sizeof(last_update) - 1;
  533     int r, content_len;
  534     size_t size;
  535 
  536     if (p15card->tokeninfo->last_update.gtime)
  537         goto done;
  538 
  539     if (!p15card->tokeninfo->last_update.path.len)
  540         return NULL;
  541 
  542     r = sc_select_file(p15card->card, &p15card->tokeninfo->last_update.path, &file);
  543     if (r < 0)
  544         return NULL;
  545 
  546     size = file->size ? file->size : 1024;
  547 
  548     content = calloc(size, 1);
  549     if (!content)
  550         return NULL;
  551 
  552     r = sc_read_binary(p15card->card, 0, content, size, 0);
  553     if (r < 0)
  554         return NULL;
  555     content_len = r;
  556 
  557     sc_file_free(file);
  558 
  559     sc_copy_asn1_entry(c_asn1_last_update, asn1_last_update);
  560     sc_format_asn1_entry(asn1_last_update + 0, last_update, &lupdate_len, 0);
  561 
  562     r = sc_asn1_decode(ctx, asn1_last_update, content, content_len, NULL, NULL);
  563     free(content);
  564     if (r < 0)
  565         return NULL;
  566 
  567     p15card->tokeninfo->last_update.gtime = strdup((char *)last_update);
  568     if (!p15card->tokeninfo->last_update.gtime)
  569         return NULL;
  570 done:
  571     sc_log(ctx, "lastUpdate.gtime '%s'", p15card->tokeninfo->last_update.gtime);
  572     return p15card->tokeninfo->last_update.gtime;
  573 }
  574 
  575 
  576 static const struct sc_asn1_entry c_asn1_odf[] = {
  577     { "privateKeys",     SC_ASN1_STRUCT, SC_ASN1_CTX | 0 | SC_ASN1_CONS, 0, NULL, NULL },
  578     { "publicKeys",      SC_ASN1_STRUCT, SC_ASN1_CTX | 1 | SC_ASN1_CONS, 0, NULL, NULL },
  579     { "trustedPublicKeys",   SC_ASN1_STRUCT, SC_ASN1_CTX | 2 | SC_ASN1_CONS, 0, NULL, NULL },
  580     { "secretKeys",      SC_ASN1_STRUCT, SC_ASN1_CTX | 3 | SC_ASN1_CONS, 0, NULL, NULL },
  581     { "certificates",    SC_ASN1_STRUCT, SC_ASN1_CTX | 4 | SC_ASN1_CONS, 0, NULL, NULL },
  582     { "trustedCertificates", SC_ASN1_STRUCT, SC_ASN1_CTX | 5 | SC_ASN1_CONS, 0, NULL, NULL },
  583     { "usefulCertificates",  SC_ASN1_STRUCT, SC_ASN1_CTX | 6 | SC_ASN1_CONS, 0, NULL, NULL },
  584     { "dataObjects",     SC_ASN1_STRUCT, SC_ASN1_CTX | 7 | SC_ASN1_CONS, 0, NULL, NULL },
  585     { "authObjects",     SC_ASN1_STRUCT, SC_ASN1_CTX | 8 | SC_ASN1_CONS, 0, NULL, NULL },
  586     { NULL, 0, 0, 0, NULL, NULL }
  587 };
  588 
  589 static const unsigned int odf_indexes[] = {
  590     SC_PKCS15_PRKDF,
  591     SC_PKCS15_PUKDF,
  592     SC_PKCS15_PUKDF_TRUSTED,
  593     SC_PKCS15_SKDF,
  594     SC_PKCS15_CDF,
  595     SC_PKCS15_CDF_TRUSTED,
  596     SC_PKCS15_CDF_USEFUL,
  597     SC_PKCS15_DODF,
  598     SC_PKCS15_AODF,
  599 };
  600 
  601 
  602 static int
  603 parse_odf(const unsigned char * buf, size_t buflen, struct sc_pkcs15_card *p15card)
  604 {
  605     const unsigned char *p = buf;
  606     size_t left = buflen;
  607     int r, i, type;
  608     struct sc_path path;
  609     struct sc_asn1_entry asn1_obj_or_path[] = {
  610         { "path", SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_SEQUENCE, 0, &path, NULL },
  611         { NULL, 0, 0, 0, NULL, NULL }
  612     };
  613     struct sc_asn1_entry asn1_odf[10];
  614 
  615     sc_copy_asn1_entry(c_asn1_odf, asn1_odf);
  616     for (i = 0; asn1_odf[i].name != NULL; i++)
  617         sc_format_asn1_entry(asn1_odf + i, asn1_obj_or_path, NULL, 0);
  618     while (left > 0) {
  619         r = sc_asn1_decode_choice(p15card->card->ctx, asn1_odf, p, left, &p, &left);
  620         if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
  621             break;
  622         if (r < 0)
  623             return r;
  624         type = r;
  625         if (p15card->file_app) {
  626             r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &path);
  627             if (r < 0)
  628                 return r;
  629             r = sc_pkcs15_add_df(p15card, odf_indexes[type], &path);
  630             if (r)
  631                 return r;
  632         }
  633     }
  634     return 0;
  635 }
  636 
  637 
  638 int
  639 sc_pkcs15_encode_odf(struct sc_context *ctx, struct sc_pkcs15_card *p15card,
  640              unsigned char **buf, size_t *buflen)
  641 {
  642     struct sc_path path;
  643     struct sc_asn1_entry asn1_obj_or_path[] = {
  644         { "path", SC_ASN1_PATH, SC_ASN1_CONS | SC_ASN1_SEQUENCE, 0, &path, NULL },
  645         { NULL, 0, 0, 0, NULL, NULL }
  646     };
  647     struct sc_asn1_entry *asn1_paths = NULL;
  648     struct sc_asn1_entry *asn1_odf = NULL;
  649     int df_count = 0, r, c = 0;
  650     const int nr_indexes = sizeof(odf_indexes)/sizeof(odf_indexes[0]);
  651     struct sc_pkcs15_df *df;
  652 
  653     df = p15card->df_list;
  654     while (df != NULL) {
  655         df_count++;
  656         df = df->next;
  657     };
  658     if (df_count == 0)
  659         LOG_TEST_RET(ctx, SC_ERROR_OBJECT_NOT_FOUND, "No DF's found.");
  660 
  661     asn1_odf = malloc(sizeof(struct sc_asn1_entry) * (df_count + 1));
  662     if (asn1_odf == NULL) {
  663         r = SC_ERROR_OUT_OF_MEMORY;
  664         goto err;
  665     }
  666     asn1_paths = malloc(sizeof(struct sc_asn1_entry) * (df_count * 2));
  667     if (asn1_paths == NULL) {
  668         r = SC_ERROR_OUT_OF_MEMORY;
  669         goto err;
  670     }
  671     for (df = p15card->df_list; df != NULL; df = df->next) {
  672         int j, type = -1;
  673 
  674         for (j = 0; j < nr_indexes; j++)
  675             if (odf_indexes[j] == df->type) {
  676                 type = j;
  677                 break;
  678             }
  679         if (type == -1) {
  680             sc_log(ctx, "Unsupported DF type.");
  681             continue;
  682         }
  683         asn1_odf[c] = c_asn1_odf[type];
  684         sc_format_asn1_entry(asn1_odf + c, asn1_paths + 2*c, NULL, 1);
  685         sc_copy_asn1_entry(asn1_obj_or_path, asn1_paths + 2*c);
  686         sc_format_asn1_entry(asn1_paths + 2*c, &df->path, NULL, 1);
  687         c++;
  688     }
  689     asn1_odf[c].name = NULL;
  690     r = sc_asn1_encode(ctx, asn1_odf, buf, buflen);
  691 err:
  692     if (asn1_paths != NULL)
  693         free(asn1_paths);
  694     if (asn1_odf != NULL)
  695         free(asn1_odf);
  696     return r;
  697 }
  698 
  699 
  700 struct sc_pkcs15_card *
  701 sc_pkcs15_card_new(void)
  702 {
  703     struct sc_pkcs15_card *p15card;
  704 
  705     p15card = calloc(1, sizeof(struct sc_pkcs15_card));
  706     if (p15card == NULL)
  707         return NULL;
  708 
  709     p15card->tokeninfo = calloc(1, sizeof(struct sc_pkcs15_tokeninfo));
  710     if (p15card->tokeninfo == NULL) {
  711         free(p15card);
  712         return NULL;
  713     }
  714 
  715     p15card->magic = SC_PKCS15_CARD_MAGIC;
  716     return p15card;
  717 }
  718 
  719 
  720 struct sc_pkcs15_tokeninfo *
  721 sc_pkcs15_tokeninfo_new(void)
  722 {
  723     struct sc_pkcs15_tokeninfo *tokeninfo;
  724 
  725     tokeninfo = calloc(1, sizeof(struct sc_pkcs15_tokeninfo));
  726     if (tokeninfo == NULL) {
  727         return NULL;
  728     }
  729 
  730     sc_init_oid(&tokeninfo->profile_indication.oid);
  731 
  732     return tokeninfo;
  733 }
  734 
  735 static void
  736 sc_pkcs15_clear_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo)
  737 {
  738     if (!tokeninfo)
  739         return;
  740 
  741     free(tokeninfo->label);
  742     tokeninfo->label = NULL;
  743     free(tokeninfo->serial_number);
  744     tokeninfo->serial_number = NULL;
  745     free(tokeninfo->manufacturer_id);
  746     tokeninfo->manufacturer_id = NULL;
  747     free(tokeninfo->last_update.gtime);
  748     tokeninfo->last_update.gtime = NULL;
  749     free(tokeninfo->preferred_language);
  750     tokeninfo->preferred_language = NULL;
  751     free(tokeninfo->profile_indication.name);
  752     tokeninfo->profile_indication.name = NULL;
  753     if (tokeninfo->seInfo != NULL) {
  754         unsigned i;
  755         for (i = 0; i < tokeninfo->num_seInfo; i++)
  756             free(tokeninfo->seInfo[i]);
  757         free(tokeninfo->seInfo);
  758         tokeninfo->seInfo = NULL;
  759     }
  760 }
  761 
  762 void
  763 sc_pkcs15_free_tokeninfo(struct sc_pkcs15_tokeninfo *tokeninfo)
  764 {
  765     if (!tokeninfo)
  766         return;
  767 
  768     sc_pkcs15_clear_tokeninfo(tokeninfo);
  769     free(tokeninfo);
  770 }
  771 
  772 void
  773 sc_pkcs15_free_app(struct sc_pkcs15_card *p15card)
  774 {
  775     if (p15card && p15card->app) {
  776         free(p15card->app->label);
  777         free(p15card->app->ddo.value);
  778         free(p15card->app);
  779         p15card->app = NULL;
  780     }
  781 }
  782 
  783 
  784 void
  785 sc_pkcs15_card_free(struct sc_pkcs15_card *p15card)
  786 {
  787     if (p15card == NULL || p15card->magic != SC_PKCS15_CARD_MAGIC)
  788         return;
  789 
  790     if (p15card->ops.clear)
  791         p15card->ops.clear(p15card);
  792 
  793     /* For more complicated MD data a dedicated release procedure
  794      * has to be implemented. */
  795     if (p15card->md_data)
  796         free(p15card->md_data);
  797 
  798     sc_pkcs15_free_app(p15card);
  799     sc_pkcs15_remove_objects(p15card);
  800     sc_pkcs15_remove_dfs(p15card);
  801     sc_pkcs15_free_unusedspace(p15card);
  802     p15card->unusedspace_read = 0;
  803 
  804     sc_file_free(p15card->file_app);
  805     sc_file_free(p15card->file_tokeninfo);
  806     sc_file_free(p15card->file_odf);
  807     sc_file_free(p15card->file_unusedspace);
  808 
  809     p15card->magic = 0;
  810     sc_pkcs15_free_tokeninfo(p15card->tokeninfo);
  811     sc_pkcs15_free_app(p15card);
  812     free(p15card);
  813 }
  814 
  815 
  816 void
  817 sc_pkcs15_card_clear(struct sc_pkcs15_card *p15card)
  818 {
  819     if (p15card == NULL)
  820         return;
  821 
  822     if (p15card->ops.clear)
  823         p15card->ops.clear(p15card);
  824 
  825     p15card->flags = 0;
  826     p15card->tokeninfo->version = 0;
  827     p15card->tokeninfo->flags   = 0;
  828 
  829     sc_pkcs15_remove_objects(p15card);
  830     sc_pkcs15_remove_dfs(p15card);
  831 
  832     p15card->df_list = NULL;
  833     sc_file_free(p15card->file_app);
  834     p15card->file_app = NULL;
  835     sc_file_free(p15card->file_tokeninfo);
  836     p15card->file_tokeninfo = NULL;
  837     sc_file_free(p15card->file_odf);
  838     p15card->file_odf = NULL;
  839     sc_file_free(p15card->file_unusedspace);
  840     p15card->file_unusedspace = NULL;
  841 
  842     free(p15card->tokeninfo->label);
  843     p15card->tokeninfo->label = NULL;
  844     free(p15card->tokeninfo->serial_number);
  845     p15card->tokeninfo->serial_number = NULL;
  846     free(p15card->tokeninfo->manufacturer_id);
  847     p15card->tokeninfo->manufacturer_id = NULL;
  848     free(p15card->tokeninfo->last_update.gtime);
  849     p15card->tokeninfo->last_update.gtime = NULL;
  850     free(p15card->tokeninfo->preferred_language);
  851     p15card->tokeninfo->preferred_language = NULL;
  852     free(p15card->tokeninfo->profile_indication.name);
  853     p15card->tokeninfo->profile_indication.name = NULL;
  854     if (p15card->tokeninfo->seInfo != NULL) {
  855         size_t i;
  856         for (i = 0; i < p15card->tokeninfo->num_seInfo; i++)
  857             free(p15card->tokeninfo->seInfo[i]);
  858         free(p15card->tokeninfo->seInfo);
  859         p15card->tokeninfo->seInfo     = NULL;
  860         p15card->tokeninfo->num_seInfo = 0;
  861     }
  862 }
  863 
  864 
  865 struct sc_app_info *
  866 sc_find_app(struct sc_card *card, struct sc_aid *aid)
  867 {
  868     int ii;
  869 
  870     if (card->app_count <= 0)
  871         return NULL;
  872 
  873     if (!aid || !aid->len)
  874         return card->app[0];
  875 
  876     for (ii=0; ii < card->app_count; ii++) {
  877         if (card->app[ii]->aid.len != aid->len)
  878             continue;
  879         if (memcmp(card->app[ii]->aid.value, aid->value, aid->len))
  880             continue;
  881         return card->app[ii];
  882     }
  883     return NULL;
  884 }
  885 
  886 
  887 static struct sc_app_info *
  888 sc_dup_app_info(const struct sc_app_info *info)
  889 {
  890     struct sc_app_info *out = calloc(1, sizeof(struct sc_app_info));
  891 
  892     if (!out)
  893         return NULL;
  894 
  895     memcpy(out, info, sizeof(struct sc_app_info));
  896 
  897     if (info->label) {
  898         out->label = strdup(info->label);
  899         if (!out->label) {
  900             free(out);
  901             return NULL;
  902         }
  903     } else
  904         out->label = NULL;
  905 
  906     out->ddo.value = malloc(info->ddo.len);
  907     if (!out->ddo.value) {
  908         free(out->label);
  909         free(out);
  910         return NULL;
  911     }
  912     memcpy(out->ddo.value, info->ddo.value, info->ddo.len);
  913 
  914     return out;
  915 }
  916 
  917 
  918 struct sc_app_info *
  919 sc_pkcs15_get_application_by_type(struct sc_card * card, char *app_type)
  920 {
  921     struct sc_app_info *out = NULL;
  922     scconf_block *conf_block = NULL;
  923     int i, rv;
  924 
  925     if (!card)
  926         return NULL;
  927 
  928     if (card->app_count < 0)   {
  929         rv = sc_enum_apps(card);
  930         if (rv < 0 && rv != SC_ERROR_FILE_NOT_FOUND)
  931             return NULL;
  932     }
  933 
  934     conf_block = sc_get_conf_block(card->ctx, "framework", "pkcs15", 1);
  935     if (!conf_block)
  936         return NULL;
  937 
  938     for (i = 0; i < card->app_count; i++)   {
  939         struct sc_app_info *app_info = card->app[i];
  940         scconf_block **blocks = NULL;
  941         char str_path[SC_MAX_AID_STRING_SIZE];
  942 
  943         sc_bin_to_hex(app_info->aid.value, app_info->aid.len, str_path, sizeof(str_path), 0);
  944         blocks = scconf_find_blocks(card->ctx->conf, conf_block, "application", str_path);
  945         if (blocks)   {
  946             if (blocks[0])   {
  947                 char *type = (char *)scconf_get_str(blocks[0], "type", app_type);
  948                 if (!strcmp(type, app_type))   {
  949                     out = app_info;
  950                     free(blocks);
  951                     break;
  952                 }
  953             }
  954             free(blocks);
  955         }
  956     }
  957 
  958     return out;
  959 }
  960 
  961 
  962 int
  963 sc_pkcs15_bind_internal(struct sc_pkcs15_card *p15card, struct sc_aid *aid)
  964 {
  965     struct sc_path tmppath;
  966     struct sc_card    *card = p15card->card;
  967     struct sc_context *ctx  = card->ctx;
  968     struct sc_pkcs15_tokeninfo tokeninfo;
  969     struct sc_pkcs15_df *df;
  970     const struct sc_app_info *info = NULL;
  971     unsigned char *buf = NULL;
  972     size_t len;
  973     int    err, ok = 0;
  974 
  975     LOG_FUNC_CALLED(ctx);
  976     /* Enumerate apps now */
  977     if (card->app_count < 0) {
  978         err = sc_enum_apps(card);
  979         if (err != SC_SUCCESS)
  980             sc_log(ctx, "unable to enumerate apps: %s", sc_strerror(err));
  981     }
  982     sc_file_free(p15card->file_app);
  983     p15card->file_app = sc_file_new();
  984     if (p15card->file_app == NULL) {
  985         err = SC_ERROR_OUT_OF_MEMORY;
  986         goto end;
  987     }
  988 
  989     sc_format_path("3F005015", &p15card->file_app->path);
  990 
  991     info = sc_find_app(card, aid);
  992     if (info)   {
  993         sc_log(ctx, "bind to application('%s',aid:'%s')", info->label, sc_dump_hex(info->aid.value, info->aid.len));
  994         sc_pkcs15_free_app(p15card);
  995         p15card->app = sc_dup_app_info(info);
  996         if (!p15card->app)   {
  997             err = SC_ERROR_OUT_OF_MEMORY;
  998             goto end;
  999         }
 1000 
 1001         if (info->path.len)
 1002             p15card->file_app->path = info->path;
 1003 
 1004         if (info->ddo.value && info->ddo.len)
 1005             parse_ddo(p15card, info->ddo.value, info->ddo.len);
 1006 
 1007     }
 1008     else if (aid)   {
 1009         sc_log(ctx, "Application '%s' not found", sc_dump_hex(aid->value, aid->len));
 1010         err = SC_ERROR_INVALID_ARGUMENTS;
 1011         goto end;
 1012     }
 1013     sc_log(ctx, "application path '%s'", sc_print_path(&p15card->file_app->path));
 1014 
 1015     /* Check if pkcs15 directory exists */
 1016     err = sc_select_file(card, &p15card->file_app->path, NULL);
 1017 
 1018     /* If the above test failed on cards without EF(DIR),
 1019      * try to continue read ODF from 3F005031. -aet
 1020      */
 1021     if ((err != SC_SUCCESS) && (card->app_count < 1)) {
 1022         sc_format_path("3F00", &p15card->file_app->path);
 1023         err = SC_SUCCESS;
 1024     }
 1025 
 1026     if (err < 0)   {
 1027         sc_log (ctx, "Cannot select application path");
 1028         goto end;
 1029     }
 1030 
 1031     if (p15card->file_odf == NULL) {
 1032         /* check if an ODF is present; we don't know yet whether we have a pkcs15 card */
 1033         sc_format_path("5031", &tmppath);
 1034         err = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &tmppath);
 1035         if (err != SC_SUCCESS)   {
 1036             sc_log(ctx, "Cannot make absolute path to EF(ODF); error:%i", err);
 1037             goto end;
 1038         }
 1039         sc_log(ctx, "absolute path to EF(ODF) %s", sc_print_path(&tmppath));
 1040         err = sc_select_file(card, &tmppath, &p15card->file_odf);
 1041     }
 1042     else {
 1043         tmppath = p15card->file_odf->path;
 1044         sc_file_free(p15card->file_odf);
 1045         p15card->file_odf = NULL;
 1046         err = sc_select_file(card, &tmppath, &p15card->file_odf);
 1047     }
 1048 
 1049     if (err != SC_SUCCESS) {
 1050         sc_log(ctx, "EF(ODF) not found in '%s'", sc_print_path(&tmppath));
 1051         goto end;
 1052     }
 1053 
 1054     len = p15card->file_odf->size;
 1055     if (!len) {
 1056         sc_log(ctx, "EF(ODF) is empty");
 1057         goto end;
 1058     }
 1059     if (len > MAX_FILE_SIZE) {
 1060         sc_log(ctx, "EF(ODF) too large");
 1061         goto end;
 1062     }
 1063     buf = malloc(len);
 1064     if(buf == NULL) {
 1065         err = SC_ERROR_OUT_OF_MEMORY;
 1066         goto end;
 1067     }
 1068 
 1069     err = -1; /* file state: not in cache */
 1070     if (p15card->opts.use_file_cache) {
 1071         err = sc_pkcs15_read_cached_file(p15card, &tmppath, &buf, &len);
 1072         if (err == SC_SUCCESS)
 1073             err = len;
 1074     }
 1075     if (err < 0) {
 1076         err = sc_read_binary(card, 0, buf, len, 0);
 1077         if (err < 2) {
 1078             if (err < 0) {
 1079                 sc_log(ctx, "read EF(ODF) file error: %s", sc_strerror(err));
 1080             } else {
 1081                 err = SC_ERROR_PKCS15_APP_NOT_FOUND;
 1082                 sc_log(ctx, "Invalid content of EF(ODF): %s", sc_strerror(err));
 1083             }
 1084             goto end;
 1085         }
 1086         /* sc_read_binary may return less than requested */
 1087         len = err;
 1088 
 1089         if (p15card->opts.use_file_cache) {
 1090             sc_pkcs15_cache_file(p15card, &tmppath, buf, len);
 1091         }
 1092     }
 1093 
 1094     if (parse_odf(buf, len, p15card)) {
 1095         err = SC_ERROR_PKCS15_APP_NOT_FOUND;
 1096         sc_log(ctx, "Unable to parse ODF");
 1097         goto end;
 1098     }
 1099     free(buf);
 1100     buf = NULL;
 1101 
 1102     sc_log(ctx, "The following DFs were found:");
 1103     for (df = p15card->df_list; df; df = df->next)
 1104         sc_log(ctx, "  DF type %u, path %s, index %u, count %d", df->type,
 1105                 sc_print_path(&df->path), df->path.index, df->path.count);
 1106 
 1107     if (p15card->file_tokeninfo == NULL) {
 1108         sc_format_path("5032", &tmppath);
 1109         err = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &tmppath);
 1110         if (err != SC_SUCCESS)   {
 1111             sc_log(ctx, "Cannot make absolute path to EF(TokenInfo); error:%i", err);
 1112             goto end;
 1113         }
 1114         sc_log(ctx, "absolute path to EF(TokenInfo) %s", sc_print_path(&tmppath));
 1115     }
 1116     else {
 1117         tmppath = p15card->file_tokeninfo->path;
 1118         sc_file_free(p15card->file_tokeninfo);
 1119         p15card->file_tokeninfo = NULL;
 1120     }
 1121 
 1122     err = sc_select_file(card, &tmppath, &p15card->file_tokeninfo);
 1123     if (err)   {
 1124         sc_log(ctx, "cannot select EF(TokenInfo) file: %s", sc_strerror(err));
 1125         goto end;
 1126     }
 1127 
 1128     len = p15card->file_tokeninfo->size;
 1129     if (!len) {
 1130         sc_log(ctx, "EF(TokenInfo) is empty");
 1131         goto end;
 1132     }
 1133     if (len > MAX_FILE_SIZE) {
 1134         sc_log(ctx, "EF(TokenInfo) too large");
 1135         goto end;
 1136     }
 1137     buf = malloc(len);
 1138     if(buf == NULL) {
 1139         err = SC_ERROR_OUT_OF_MEMORY;
 1140         goto end;
 1141     }
 1142 
 1143     err = -1; /* file state: not in cache */
 1144     if (p15card->opts.use_file_cache) {
 1145         err = sc_pkcs15_read_cached_file(p15card, &tmppath, &buf, &len);
 1146         if (err == SC_SUCCESS)
 1147             err = len;
 1148     }
 1149     if (err < 0) {
 1150         err = sc_read_binary(card, 0, buf, len, 0);
 1151         if (err <= 2) {
 1152             if (err < 0)   {
 1153                 sc_log(ctx, "read EF(TokenInfo) file error: %s", sc_strerror(err));
 1154             } else {
 1155                 err = SC_ERROR_PKCS15_APP_NOT_FOUND;
 1156                 sc_log(ctx, "Invalid content of EF(TokenInfo): %s", sc_strerror(err));
 1157             }
 1158             goto end;
 1159         }
 1160         /* sc_read_binary may return less than requested */
 1161         len = err;
 1162 
 1163         if (p15card->opts.use_file_cache) {
 1164             sc_pkcs15_cache_file(p15card, &tmppath, buf, len);
 1165         }
 1166     }
 1167 
 1168     memset(&tokeninfo, 0, sizeof(tokeninfo));
 1169     err = sc_pkcs15_parse_tokeninfo(ctx, &tokeninfo, buf, (size_t)err);
 1170     if (err != SC_SUCCESS)   {
 1171         sc_log(ctx, "cannot parse TokenInfo content: %s", sc_strerror(err));
 1172         goto end;
 1173     }
 1174 
 1175     sc_pkcs15_clear_tokeninfo(p15card->tokeninfo);
 1176     *(p15card->tokeninfo) = tokeninfo;
 1177 
 1178     if (!p15card->tokeninfo->serial_number && 0 == card->serialnr.len) {
 1179         sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &card->serialnr);
 1180     }
 1181 
 1182     if (!p15card->tokeninfo->serial_number && card->serialnr.len)   {
 1183         char *serial = calloc(1, card->serialnr.len*2 + 1);
 1184         size_t ii;
 1185         if (!serial) {
 1186             err = SC_ERROR_OUT_OF_MEMORY;
 1187             goto end;
 1188         }
 1189 
 1190         for(ii=0;ii<card->serialnr.len;ii++)
 1191             sprintf(serial + ii*2, "%02X", *(card->serialnr.value + ii));
 1192 
 1193         p15card->tokeninfo->serial_number = serial;
 1194         sc_log(ctx, "p15card->tokeninfo->serial_number %s", p15card->tokeninfo->serial_number);
 1195     }
 1196 
 1197     ok = 1;
 1198 end:
 1199     if(buf != NULL)
 1200         free(buf);
 1201     if (!ok) {
 1202         sc_pkcs15_card_clear(p15card);
 1203         if (err == SC_ERROR_FILE_NOT_FOUND)
 1204             err = SC_ERROR_WRONG_CARD;
 1205         LOG_FUNC_RETURN(ctx, err);
 1206     }
 1207 
 1208     LOG_FUNC_RETURN(ctx, SC_SUCCESS);
 1209 }
 1210 
 1211 
 1212 int
 1213 sc_pkcs15_bind(struct sc_card *card, struct sc_aid *aid,
 1214         struct sc_pkcs15_card **p15card_out)
 1215 {
 1216     struct sc_pkcs15_card *p15card = NULL;
 1217     struct sc_context *ctx;
 1218     scconf_block *conf_block = NULL;
 1219     int r, emu_first, enable_emu;
 1220     const char *private_certificate;
 1221 
 1222     if (card == NULL || p15card_out == NULL) {
 1223         return SC_ERROR_INVALID_ARGUMENTS;
 1224     }
 1225     ctx = card->ctx;
 1226 
 1227     LOG_FUNC_CALLED(ctx);
 1228     sc_log(ctx, "application(aid:'%s')", aid ? sc_dump_hex(aid->value, aid->len) : "empty");
 1229 
 1230     p15card = sc_pkcs15_card_new();
 1231     if (p15card == NULL)
 1232         LOG_FUNC_RETURN(ctx, SC_ERROR_OUT_OF_MEMORY);
 1233 
 1234     p15card->card = card;
 1235     p15card->opts.use_file_cache = 0;
 1236     p15card->opts.use_pin_cache = 1;
 1237     p15card->opts.pin_cache_counter = 10;
 1238     p15card->opts.pin_cache_ignore_user_consent = 0;
 1239     if(0 == strcmp(ctx->app_name, "tokend")) {
 1240         private_certificate = "ignore";
 1241         p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE;
 1242     } else {
 1243         private_certificate = "protect";
 1244         p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT;
 1245     }
 1246 
 1247     conf_block = sc_get_conf_block(ctx, "framework", "pkcs15", 1);
 1248     if (conf_block) {
 1249         p15card->opts.use_file_cache = scconf_get_bool(conf_block, "use_file_caching", p15card->opts.use_file_cache);
 1250         p15card->opts.use_pin_cache = scconf_get_bool(conf_block, "use_pin_caching", p15card->opts.use_pin_cache);
 1251         p15card->opts.pin_cache_counter = scconf_get_int(conf_block, "pin_cache_counter", p15card->opts.pin_cache_counter);
 1252         p15card->opts.pin_cache_ignore_user_consent = scconf_get_bool(conf_block, "pin_cache_ignore_user_consent",
 1253                 p15card->opts.pin_cache_ignore_user_consent);
 1254         private_certificate = scconf_get_str(conf_block, "private_certificate", private_certificate);
 1255     }
 1256     if (0 == strcmp(private_certificate, "protect")) {
 1257         p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_PROTECT;
 1258     } else if (0 == strcmp(private_certificate, "ignore")) {
 1259         p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_IGNORE;
 1260     } else if (0 == strcmp(private_certificate, "declassify")) {
 1261         p15card->opts.private_certificate = SC_PKCS15_CARD_OPTS_PRIV_CERT_DECLASSIFY;
 1262     }
 1263     sc_log(ctx, "PKCS#15 options: use_file_cache=%d use_pin_cache=%d pin_cache_counter=%d pin_cache_ignore_user_consent=%d private_certificate=%d",
 1264             p15card->opts.use_file_cache, p15card->opts.use_pin_cache,p15card->opts.pin_cache_counter,
 1265             p15card->opts.pin_cache_ignore_user_consent, p15card->opts.private_certificate);
 1266 
 1267     r = sc_lock(card);
 1268     if (r) {
 1269         sc_log(ctx, "sc_lock() failed: %s", sc_strerror(r));
 1270         sc_pkcs15_card_free(p15card);
 1271         LOG_FUNC_RETURN(ctx, r);
 1272     }
 1273 
 1274     enable_emu = scconf_get_bool(conf_block, "enable_pkcs15_emulation", 1);
 1275     if (enable_emu) {
 1276         sc_log(ctx, "PKCS#15 emulation enabled");
 1277         emu_first = scconf_get_bool(conf_block, "try_emulation_first", 0);
 1278         if (emu_first || sc_pkcs15_is_emulation_only(card)) {
 1279             r = sc_pkcs15_bind_synthetic(p15card, aid);
 1280             if (r == SC_SUCCESS)
 1281                 goto done;
 1282             r = sc_pkcs15_bind_internal(p15card, aid);
 1283             if (r < 0)
 1284                 goto error;
 1285         } else {
 1286             r = sc_pkcs15_bind_internal(p15card, aid);
 1287             if (r == SC_SUCCESS)
 1288                 goto done;
 1289             r = sc_pkcs15_bind_synthetic(p15card, aid);
 1290             if (r < 0)
 1291                 goto error;
 1292         }
 1293     }
 1294     else {
 1295         r = sc_pkcs15_bind_internal(p15card, aid);
 1296         if (r < 0)
 1297             goto error;
 1298     }
 1299 done:
 1300     *p15card_out = p15card;
 1301     sc_unlock(card);
 1302     LOG_FUNC_RETURN(ctx, SC_SUCCESS);
 1303 error:
 1304     sc_unlock(card);
 1305     sc_pkcs15_card_free(p15card);
 1306     LOG_FUNC_RETURN(ctx, r);
 1307 }
 1308 
 1309 
 1310 int
 1311 sc_pkcs15_unbind(struct sc_pkcs15_card *p15card)
 1312 {
 1313     if (p15card == NULL || p15card->magic != SC_PKCS15_CARD_MAGIC) {
 1314         return SC_ERROR_INVALID_ARGUMENTS;
 1315     }
 1316 
 1317     LOG_FUNC_CALLED(p15card->card->ctx);
 1318     if (p15card->dll_handle)
 1319         sc_dlclose(p15card->dll_handle);
 1320     sc_pkcs15_pincache_clear(p15card);
 1321     sc_pkcs15_card_free(p15card);
 1322     return 0;
 1323 }
 1324 
 1325 
 1326 static int
 1327 __sc_pkcs15_search_objects(struct sc_pkcs15_card *p15card, unsigned int class_mask, unsigned int type,
 1328             int (*func)(sc_pkcs15_object_t *, void *), void *func_arg,
 1329             sc_pkcs15_object_t **ret, size_t ret_size)
 1330 {
 1331     struct sc_pkcs15_object *obj = NULL;
 1332     struct sc_pkcs15_df *df = NULL;
 1333     unsigned int    df_mask = 0;
 1334     size_t      match_count = 0;
 1335     int r;
 1336 
 1337     if (type)
 1338         class_mask |= SC_PKCS15_TYPE_TO_CLASS(type);
 1339 
 1340     /* Make sure the class mask we have makes sense */
 1341     if (class_mask == 0
 1342             || (class_mask & ~(
 1343                     SC_PKCS15_SEARCH_CLASS_PRKEY |
 1344                     SC_PKCS15_SEARCH_CLASS_PUBKEY |
 1345                     SC_PKCS15_SEARCH_CLASS_SKEY |
 1346                     SC_PKCS15_SEARCH_CLASS_CERT |
 1347                     SC_PKCS15_SEARCH_CLASS_DATA |
 1348                     SC_PKCS15_SEARCH_CLASS_AUTH))) {
 1349         LOG_FUNC_RETURN(p15card->card->ctx, SC_ERROR_INVALID_ARGUMENTS);
 1350     }
 1351 
 1352     if (class_mask & SC_PKCS15_SEARCH_CLASS_PRKEY)
 1353         df_mask |= (1 << SC_PKCS15_PRKDF);
 1354     if (class_mask & SC_PKCS15_SEARCH_CLASS_PUBKEY)
 1355         df_mask |= (1 << SC_PKCS15_PUKDF) | (1 << SC_PKCS15_PUKDF_TRUSTED);
 1356     if (class_mask & SC_PKCS15_SEARCH_CLASS_CERT)
 1357         df_mask |= (1 << SC_PKCS15_CDF) | (1 << SC_PKCS15_CDF_TRUSTED) | (1 << SC_PKCS15_CDF_USEFUL);
 1358     if (class_mask & SC_PKCS15_SEARCH_CLASS_DATA)
 1359         df_mask |= (1 << SC_PKCS15_DODF);
 1360     if (class_mask & SC_PKCS15_SEARCH_CLASS_AUTH)
 1361         df_mask |= (1 << SC_PKCS15_AODF);
 1362     if (class_mask & SC_PKCS15_SEARCH_CLASS_SKEY)
 1363         df_mask |= (1 << SC_PKCS15_SKDF);
 1364 
 1365     /* Make sure all the DFs we want to search have been
 1366      * enumerated. */
 1367     for (df = p15card->df_list; df != NULL; df = df->next) {
 1368         if (!(df_mask & (1 << df->type)))   {
 1369             continue;
 1370         }
 1371         if (df->enumerated)
 1372             continue;
 1373         /* Enumerate the DF's, so p15card->obj_list is populated. */
 1374         if (p15card->ops.parse_df)
 1375             r = p15card->ops.parse_df(p15card, df);
 1376         else
 1377             r = sc_pkcs15_parse_df(p15card, df);
 1378         if (r != SC_SUCCESS)
 1379             continue;
 1380     }
 1381 
 1382     /* And now loop over all objects */
 1383     for (obj = p15card->obj_list; obj != NULL; obj = obj->next) {
 1384         /* Check object type */
 1385         if (!(class_mask & SC_PKCS15_TYPE_TO_CLASS(obj->type)))
 1386             continue;
 1387         if (type != 0
 1388          && obj->type != type
 1389          && (obj->type & SC_PKCS15_TYPE_CLASS_MASK) != type)
 1390             continue;
 1391 
 1392         /* Potential candidate, apply search function */
 1393         if (func != NULL && func(obj, func_arg) <= 0)
 1394             continue;
 1395         /* Okay, we have a match. */
 1396         match_count++;
 1397         if (!ret || ret_size <= 0)
 1398             continue;
 1399         ret[match_count-1] = obj;
 1400         if (ret_size <= match_count)
 1401             break;
 1402     }
 1403 
 1404     return match_count;
 1405 }
 1406 
 1407 
 1408 int
 1409 sc_pkcs15_get_objects(struct sc_pkcs15_card *p15card, unsigned int type,
 1410         struct sc_pkcs15_object **ret, size_t ret_size)
 1411 {
 1412     return sc_pkcs15_get_objects_cond(p15card, type, NULL, NULL, ret, ret_size);
 1413 }
 1414 
 1415 
 1416 static int
 1417 compare_obj_id(struct sc_pkcs15_object *obj, const struct sc_pkcs15_id *id)
 1418 {
 1419     void *data = obj->data;
 1420 
 1421     switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
 1422     case SC_PKCS15_TYPE_CERT:
 1423         return sc_pkcs15_compare_id(&((struct sc_pkcs15_cert_info *) data)->id, id);
 1424     case SC_PKCS15_TYPE_PRKEY:
 1425         return sc_pkcs15_compare_id(&((struct sc_pkcs15_prkey_info *) data)->id, id);
 1426     case SC_PKCS15_TYPE_PUBKEY:
 1427         return sc_pkcs15_compare_id(&((struct sc_pkcs15_pubkey_info *) data)->id, id);
 1428     case SC_PKCS15_TYPE_SKEY:
 1429         return sc_pkcs15_compare_id(&((struct sc_pkcs15_skey_info *) data)->id, id);
 1430     case SC_PKCS15_TYPE_AUTH:
 1431         return sc_pkcs15_compare_id(&((struct sc_pkcs15_auth_info *) data)->auth_id, id);
 1432     case SC_PKCS15_TYPE_DATA_OBJECT:
 1433         return sc_pkcs15_compare_id(&((struct sc_pkcs15_data_info *) data)->id, id);
 1434     }
 1435     return 0;
 1436 }
 1437 
 1438 
 1439 static int
 1440 sc_obj_app_oid(struct sc_pkcs15_object *obj, const struct sc_object_id *app_oid)
 1441 {
 1442     if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) == SC_PKCS15_TYPE_DATA_OBJECT)
 1443         return sc_compare_oid(&((struct sc_pkcs15_data_info *) obj->data)->app_oid, app_oid);
 1444     return 0;
 1445 }
 1446 
 1447 
 1448 static int
 1449 compare_obj_usage(struct sc_pkcs15_object *obj, unsigned int mask, unsigned int value)
 1450 {
 1451     void        *data = obj->data;
 1452     unsigned int    usage;
 1453 
 1454     switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
 1455     case SC_PKCS15_TYPE_PRKEY:
 1456         usage = ((struct sc_pkcs15_prkey_info *) data)->usage;
 1457         break;
 1458     case SC_PKCS15_TYPE_PUBKEY:
 1459         usage = ((struct sc_pkcs15_pubkey_info *) data)->usage;
 1460         break;
 1461     default:
 1462         return 0;
 1463     }
 1464     return (usage & mask & value) != 0;
 1465 }
 1466 
 1467 
 1468 static int
 1469 compare_obj_flags(struct sc_pkcs15_object *obj, unsigned int mask, unsigned int value)
 1470 {
 1471     struct sc_pkcs15_auth_info *auth_info;
 1472     unsigned int    flags;
 1473 
 1474     switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
 1475     case SC_PKCS15_TYPE_AUTH:
 1476         auth_info = (struct sc_pkcs15_auth_info *) obj->data;
 1477         if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
 1478             return 0;
 1479         flags = auth_info->attrs.pin.flags;
 1480         break;
 1481     default:
 1482         return 0;
 1483     }
 1484     return !((flags ^ value) & mask);
 1485 }
 1486 
 1487 
 1488 static int
 1489 compare_obj_reference(struct sc_pkcs15_object *obj, int value)
 1490 {
 1491     struct sc_pkcs15_auth_info *auth_info;
 1492     void        *data = obj->data;
 1493     int     reference;
 1494 
 1495     switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
 1496     case SC_PKCS15_TYPE_AUTH:
 1497         auth_info = (struct sc_pkcs15_auth_info *) obj->data;
 1498         if (auth_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
 1499             return 0;
 1500         reference = auth_info->attrs.pin.reference;
 1501         break;
 1502     case SC_PKCS15_TYPE_PRKEY:
 1503         reference = ((struct sc_pkcs15_prkey_info *) data)->key_reference;
 1504         break;
 1505     default:
 1506         return 0;
 1507     }
 1508     return reference == value;
 1509 }
 1510 
 1511 
 1512 static int
 1513 compare_obj_path(struct sc_pkcs15_object *obj, const struct sc_path *path)
 1514 {
 1515     void *data = obj->data;
 1516 
 1517     switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
 1518     case SC_PKCS15_TYPE_PRKEY:
 1519         return sc_compare_path(&((struct sc_pkcs15_prkey_info *) data)->path, path);
 1520     case SC_PKCS15_TYPE_PUBKEY:
 1521         return sc_compare_path(&((struct sc_pkcs15_pubkey_info *) data)->path, path);
 1522     case SC_PKCS15_TYPE_SKEY:
 1523         return sc_compare_path(&((struct sc_pkcs15_skey_info *) data)->path, path);
 1524     case SC_PKCS15_TYPE_CERT:
 1525         return sc_compare_path(&((struct sc_pkcs15_cert_info *) data)->path, path);
 1526     case SC_PKCS15_TYPE_AUTH:
 1527         return sc_compare_path(&((struct sc_pkcs15_auth_info *) data)->path, path);
 1528     case SC_PKCS15_TYPE_DATA_OBJECT:
 1529         return sc_compare_path(&((struct sc_pkcs15_data_info *) data)->path, path);
 1530     }
 1531     return 0;
 1532 }
 1533 
 1534 
 1535 static int
 1536 compare_obj_data_name(struct sc_pkcs15_object *obj, const char *app_label, const char *label)
 1537 {
 1538     struct sc_pkcs15_data_info *cinfo = (struct sc_pkcs15_data_info *) obj->data;
 1539 
 1540     if (obj->type != SC_PKCS15_TYPE_DATA_OBJECT)
 1541         return 0;
 1542 
 1543     return !strncmp(cinfo->app_label, app_label, sizeof cinfo->app_label) &&
 1544         !strncmp(obj->label, label, sizeof obj->label);
 1545 }
 1546 
 1547 
 1548 static int
 1549 compare_obj_key(struct sc_pkcs15_object *obj, void *arg)
 1550 {
 1551     struct sc_pkcs15_search_key *sk = (struct sc_pkcs15_search_key *) arg;
 1552 
 1553     if (sk->id && !compare_obj_id(obj, sk->id))
 1554         return 0;
 1555     if (sk->app_oid && !sc_obj_app_oid(obj, sk->app_oid))
 1556         return 0;
 1557     if (sk->usage_mask && !compare_obj_usage(obj, sk->usage_mask, sk->usage_value))
 1558         return 0;
 1559     if (sk->flags_mask && !compare_obj_flags(obj, sk->flags_mask, sk->flags_value))
 1560         return 0;
 1561     if (sk->match_reference && !compare_obj_reference(obj, sk->reference))
 1562         return 0;
 1563     if (sk->path && !compare_obj_path(obj, sk->path))
 1564         return 0;
 1565     if (
 1566         sk->app_label && sk->label &&
 1567         !compare_obj_data_name(obj, sk->app_label, sk->label)
 1568     ) {
 1569         return 0;
 1570     }
 1571 
 1572     return 1;
 1573 }
 1574 
 1575 
 1576 static int
 1577 find_by_key(struct sc_pkcs15_card *p15card, unsigned int type, struct sc_pkcs15_search_key *sk,
 1578         struct sc_pkcs15_object **out)
 1579 {
 1580     int r;
 1581 
 1582     r = sc_pkcs15_get_objects_cond(p15card, type, compare_obj_key, sk, out, 1);
 1583     if (r < 0)
 1584         return r;
 1585     if (r == 0)
 1586         return SC_ERROR_OBJECT_NOT_FOUND;
 1587     return 0;
 1588 }
 1589 
 1590 
 1591 int
 1592 sc_pkcs15_search_objects(struct sc_pkcs15_card *p15card, struct sc_pkcs15_search_key *sk,
 1593             struct sc_pkcs15_object **ret, size_t ret_size)
 1594 {
 1595     return __sc_pkcs15_search_objects(p15card,
 1596             sk->class_mask, sk->type,
 1597             compare_obj_key, sk,
 1598             ret, ret_size);
 1599 }
 1600 
 1601 
 1602 int
 1603 sc_pkcs15_get_objects_cond(struct sc_pkcs15_card *p15card, unsigned int type,
 1604         int (* func)(struct sc_pkcs15_object *, void *),
 1605         void *func_arg, struct sc_pkcs15_object **ret, size_t ret_size)
 1606 {
 1607     return __sc_pkcs15_search_objects(p15card, 0, type,
 1608             func, func_arg, ret, ret_size);
 1609 }
 1610 
 1611 
 1612 int sc_pkcs15_find_object_by_id(struct sc_pkcs15_card *p15card,
 1613                 unsigned int type, const struct sc_pkcs15_id *id,
 1614                 struct sc_pkcs15_object **out)
 1615 {
 1616     struct sc_pkcs15_search_key sk;
 1617     int r;
 1618 
 1619     memset(&sk, 0, sizeof(sk));
 1620     sk.id = id;
 1621 
 1622     r = __sc_pkcs15_search_objects(p15card, 0, type, compare_obj_key, &sk, out, 1);
 1623     if (r < 0)
 1624         return r;
 1625     if (r == 0)
 1626         return SC_ERROR_OBJECT_NOT_FOUND;
 1627     return 0;
 1628 }
 1629 
 1630 
 1631 int
 1632 sc_pkcs15_find_cert_by_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
 1633         struct sc_pkcs15_object **out)
 1634 {
 1635     return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_CERT, id, out);
 1636 }
 1637 
 1638 
 1639 int
 1640 sc_pkcs15_find_prkey_by_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
 1641         struct sc_pkcs15_object **out)
 1642 {
 1643     return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_PRKEY, id, out);
 1644 }
 1645 
 1646 
 1647 int
 1648 sc_pkcs15_find_pubkey_by_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
 1649         struct sc_pkcs15_object **out)
 1650 {
 1651     return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_PUBKEY, id, out);
 1652 }
 1653 
 1654 
 1655 int
 1656 sc_pkcs15_find_skey_by_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
 1657         struct sc_pkcs15_object **out)
 1658 {
 1659     return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_SKEY, id, out);
 1660 }
 1661 
 1662 
 1663 int
 1664 sc_pkcs15_find_pin_by_auth_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
 1665         struct sc_pkcs15_object **out)
 1666 {
 1667     return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_AUTH, id, out);
 1668 }
 1669 
 1670 
 1671 int
 1672 sc_pkcs15_find_pin_by_reference(struct sc_pkcs15_card *p15card, const sc_path_t *path, int reference,
 1673         struct sc_pkcs15_object **out)
 1674 {
 1675     struct sc_pkcs15_search_key sk;
 1676 
 1677     memset(&sk, 0, sizeof(sk));
 1678     sk.match_reference = 1;
 1679     sk.reference = reference;
 1680     sk.path = path;
 1681 
 1682     return find_by_key(p15card, SC_PKCS15_TYPE_AUTH_PIN, &sk, out);
 1683 }
 1684 
 1685 
 1686 int
 1687 sc_pkcs15_find_pin_by_type_and_reference(struct sc_pkcs15_card *p15card, const struct sc_path *path,
 1688                 unsigned auth_method, int reference,
 1689                 struct sc_pkcs15_object **out)
 1690 {
 1691     struct sc_context *ctx = p15card->card->ctx;
 1692     struct sc_pkcs15_object *auth_objs[0x10];
 1693     size_t nn_objs, ii;
 1694     int r;
 1695 
 1696     /* Get all existing pkcs15 AUTH objects */
 1697     r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, auth_objs, 0x10);
 1698     LOG_TEST_RET(ctx, r, "Get PKCS#15 AUTH objects error");
 1699     nn_objs = r;
 1700 
 1701     for (ii=0; ii<nn_objs; ii++)   {
 1702         struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *)auth_objs[ii]->data;
 1703 
 1704         if (auth_info->auth_method != auth_method)
 1705             continue;
 1706         if (auth_info->auth_type == SC_PKCS15_PIN_AUTH_TYPE_PIN)
 1707             if (auth_info->attrs.pin.reference != reference)
 1708                 continue;
 1709 
 1710         if (path && !sc_compare_path(&auth_info->path, path))
 1711             continue;
 1712 
 1713         if (out)
 1714             *out = auth_objs[ii];
 1715 
 1716         return SC_SUCCESS;
 1717     }
 1718 
 1719     return SC_ERROR_OBJECT_NOT_FOUND;
 1720 }
 1721 
 1722 
 1723 int
 1724 sc_pkcs15_find_so_pin(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object **out)
 1725 {
 1726     struct sc_pkcs15_search_key sk;
 1727 
 1728     memset(&sk, 0, sizeof(sk));
 1729     sk.flags_mask = sk.flags_value = SC_PKCS15_PIN_FLAG_SO_PIN;
 1730 
 1731     return find_by_key(p15card, SC_PKCS15_TYPE_AUTH_PIN, &sk, out);
 1732 }
 1733 
 1734 
 1735 int
 1736 sc_pkcs15_find_pin_by_flags(struct sc_pkcs15_card *p15card,
 1737         unsigned flags, unsigned mask, int *index,
 1738         struct sc_pkcs15_object **out)
 1739 {
 1740     struct sc_context *ctx = p15card->card->ctx;
 1741     struct sc_pkcs15_object *auths[SC_PKCS15_MAX_PINS];
 1742     int r, i, num, idx = 0;
 1743 
 1744     LOG_FUNC_CALLED(ctx);
 1745     sc_log(ctx, "Find PIN flags:0x%X, mask:0x%X, index:%i", flags, mask, index ? *index : -1);
 1746     if (index)
 1747         idx = *index;
 1748     /* Get authentication PKCS#15 objects that are present in the given application */
 1749     r = sc_pkcs15_get_objects(p15card, SC_PKCS15_TYPE_AUTH_PIN, auths, SC_PKCS15_MAX_PINS);
 1750     if (r < 0)
 1751         return r;
 1752     num = r;
 1753 
 1754     for (i=idx; i<num; i++)   {
 1755         struct sc_pkcs15_auth_info *pin_info = (struct sc_pkcs15_auth_info *)(*(auths + i))->data;
 1756 
 1757         if (!pin_info || pin_info->auth_type != SC_PKCS15_PIN_AUTH_TYPE_PIN)
 1758             continue;
 1759 
 1760         if ((pin_info->attrs.pin.flags & mask) != flags)
 1761             continue;
 1762 
 1763         if (out)
 1764             *out = *(auths + i);
 1765         if (index)
 1766             *index = i;
 1767 
 1768         LOG_FUNC_RETURN(ctx, SC_SUCCESS);
 1769     }
 1770 
 1771     LOG_FUNC_RETURN(ctx, SC_ERROR_OBJECT_NOT_FOUND);
 1772 }
 1773 
 1774 
 1775 int
 1776 sc_pkcs15_find_data_object_by_id(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
 1777         struct sc_pkcs15_object **out)
 1778 {
 1779     return sc_pkcs15_find_object_by_id(p15card, SC_PKCS15_TYPE_DATA_OBJECT, id, out);
 1780 }
 1781 
 1782 
 1783 int
 1784 sc_pkcs15_find_data_object_by_app_oid(struct sc_pkcs15_card *p15card, const struct sc_object_id *app_oid,
 1785         struct sc_pkcs15_object **out)
 1786 {
 1787     struct sc_pkcs15_search_key sk;
 1788     int r;
 1789 
 1790     memset(&sk, 0, sizeof(sk));
 1791     sk.app_oid = app_oid;
 1792 
 1793     r = __sc_pkcs15_search_objects(p15card, 0, SC_PKCS15_TYPE_DATA_OBJECT,
 1794                 compare_obj_key, &sk,
 1795                 out, 1);
 1796     if (r < 0)
 1797         return r;
 1798     if (r == 0)
 1799         return SC_ERROR_OBJECT_NOT_FOUND;
 1800     return 0;
 1801 }
 1802 
 1803 
 1804 int
 1805 sc_pkcs15_find_data_object_by_name(struct sc_pkcs15_card *p15card, const char *app_label, const char *label,
 1806         struct sc_pkcs15_object **out)
 1807 {
 1808     struct sc_pkcs15_search_key sk;
 1809     int r;
 1810 
 1811     memset(&sk, 0, sizeof(sk));
 1812     sk.app_label = app_label;
 1813     sk.label = label;
 1814 
 1815     r = __sc_pkcs15_search_objects(p15card, 0, SC_PKCS15_TYPE_DATA_OBJECT,
 1816                 compare_obj_key, &sk,
 1817                 out, 1);
 1818     if (r < 0)
 1819         return r;
 1820     if (r == 0)
 1821         return SC_ERROR_OBJECT_NOT_FOUND;
 1822     return 0;
 1823 }
 1824 
 1825 
 1826 int
 1827 sc_pkcs15_find_prkey_by_id_usage(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_id *id,
 1828         unsigned int usage, struct sc_pkcs15_object **out)
 1829 {
 1830     struct sc_pkcs15_search_key sk;
 1831 
 1832     memset(&sk, 0, sizeof(sk));
 1833     sk.usage_mask = sk.usage_value = usage;
 1834     sk.id = id;
 1835 
 1836     return find_by_key(p15card, SC_PKCS15_TYPE_PRKEY, &sk, out);
 1837 }
 1838 
 1839 
 1840 int
 1841 sc_pkcs15_find_prkey_by_reference(struct sc_pkcs15_card *p15card, const struct sc_path *path,
 1842                 int reference,
 1843                 struct sc_pkcs15_object **out)
 1844 {
 1845     struct sc_pkcs15_search_key sk;
 1846 
 1847     memset(&sk, 0, sizeof(sk));
 1848     sk.match_reference = 1;
 1849     sk.reference = reference;
 1850     sk.path = path;
 1851 
 1852     return find_by_key(p15card, SC_PKCS15_TYPE_PRKEY, &sk, out);
 1853 }
 1854 
 1855 
 1856 int
 1857 sc_pkcs15_add_object(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj)
 1858 {
 1859     struct sc_pkcs15_object *p = p15card->obj_list;
 1860 
 1861     if (!obj)
 1862         return 0;
 1863     obj->next = obj->prev = NULL;
 1864     if (p15card->obj_list == NULL) {
 1865         p15card->obj_list = obj;
 1866         return 0;
 1867     }
 1868     while (p->next != NULL)
 1869         p = p->next;
 1870     p->next = obj;
 1871     obj->prev = p;
 1872 
 1873     return 0;
 1874 }
 1875 
 1876 
 1877 void
 1878 sc_pkcs15_remove_object(struct sc_pkcs15_card *p15card, struct sc_pkcs15_object *obj)
 1879 {
 1880     if (!obj)
 1881         return;
 1882     else if (obj->prev == NULL)
 1883         p15card->obj_list = obj->next;
 1884     else
 1885         obj->prev->next = obj->next;
 1886     if (obj->next != NULL)
 1887         obj->next->prev = obj->prev;
 1888 }
 1889 
 1890 
 1891 static void
 1892 sc_pkcs15_remove_objects(struct sc_pkcs15_card *p15card)
 1893 {
 1894     struct sc_pkcs15_object *cur = NULL, *next = NULL;
 1895 
 1896     if (!p15card || !p15card->obj_list)
 1897         return;
 1898     for (cur = p15card->obj_list; cur; cur = next)   {
 1899         next = cur->next;
 1900         sc_pkcs15_free_object(cur);
 1901     }
 1902 
 1903     p15card->obj_list = NULL;
 1904 }
 1905 
 1906 
 1907 void
 1908 sc_pkcs15_free_object(struct sc_pkcs15_object *obj)
 1909 {
 1910     if (!obj)
 1911         return;
 1912     switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
 1913     case SC_PKCS15_TYPE_PRKEY:
 1914         sc_pkcs15_free_prkey_info((sc_pkcs15_prkey_info_t *)obj->data);
 1915         break;
 1916     case SC_PKCS15_TYPE_PUBKEY:
 1917         /* This is normally passed to framework-pkcs15,
 1918          * but if something fails on the way, it would not get freed */
 1919         if (obj->emulated) {
 1920             sc_pkcs15_free_pubkey(obj->emulated);
 1921         }
 1922         sc_pkcs15_free_pubkey_info((sc_pkcs15_pubkey_info_t *)obj->data);
 1923         break;
 1924     case SC_PKCS15_TYPE_CERT:
 1925         sc_pkcs15_free_cert_info((sc_pkcs15_cert_info_t *)obj->data);
 1926         break;
 1927     case SC_PKCS15_TYPE_DATA_OBJECT:
 1928         sc_pkcs15_free_data_info((sc_pkcs15_data_info_t *)obj->data);
 1929         break;
 1930     case SC_PKCS15_TYPE_AUTH:
 1931         sc_pkcs15_free_auth_info((sc_pkcs15_auth_info_t *)obj->data);
 1932         break;
 1933     default:
 1934         free(obj->data);
 1935     }
 1936 
 1937     sc_pkcs15_free_object_content(obj);
 1938 
 1939     free(obj);
 1940 }
 1941 
 1942 
 1943 int
 1944 sc_pkcs15_add_df(struct sc_pkcs15_card *p15card, unsigned int type, const sc_path_t *path)
 1945 {
 1946     struct sc_pkcs15_df *p, *newdf;
 1947 
 1948     newdf = calloc(1, sizeof(struct sc_pkcs15_df));
 1949     if (newdf == NULL)
 1950         return SC_ERROR_OUT_OF_MEMORY;
 1951     newdf->path = *path;
 1952     newdf->type = type;
 1953 
 1954     if (p15card->df_list == NULL) {
 1955         p15card->df_list = newdf;
 1956         return 0;
 1957     }
 1958 
 1959     p = p15card->df_list;
 1960     while (p->next != NULL)
 1961         p = p->next;
 1962     p->next = newdf;
 1963     newdf->prev = p;
 1964 
 1965     return 0;
 1966 }
 1967 
 1968 
 1969 static void
 1970 sc_pkcs15_remove_dfs(struct sc_pkcs15_card *p15card)
 1971 {
 1972     struct sc_pkcs15_df *cur = NULL, *next = NULL;
 1973 
 1974     if (!p15card || !p15card->df_list)
 1975         return;
 1976 
 1977     for (cur = p15card->df_list; cur; cur = next)   {
 1978         next = cur->next;
 1979         free(cur);
 1980     }
 1981 
 1982     p15card->df_list = NULL;
 1983 }
 1984 
 1985 
 1986 int
 1987 sc_pkcs15_encode_df(struct sc_context *ctx, struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df,
 1988         unsigned char **buf_out, size_t *bufsize_out)
 1989 {
 1990     unsigned char *buf = NULL, *tmp = NULL, *p;
 1991     size_t bufsize = 0, tmpsize;
 1992     const struct sc_pkcs15_object *obj;
 1993     int (* func)(struct sc_context *, const struct sc_pkcs15_object *nobj,
 1994              unsigned char **nbuf, size_t *nbufsize) = NULL;
 1995     int r;
 1996 
 1997     if (p15card == NULL || p15card->magic != SC_PKCS15_CARD_MAGIC) {
 1998         return SC_ERROR_INVALID_ARGUMENTS;
 1999     }
 2000     switch (df->type) {
 2001     case SC_PKCS15_PRKDF:
 2002         func = sc_pkcs15_encode_prkdf_entry;
 2003         break;
 2004     case SC_PKCS15_PUKDF:
 2005     case SC_PKCS15_PUKDF_TRUSTED:
 2006         func = sc_pkcs15_encode_pukdf_entry;
 2007         break;
 2008     case SC_PKCS15_SKDF:
 2009         func = sc_pkcs15_encode_skdf_entry;
 2010         break;
 2011     case SC_PKCS15_CDF:
 2012     case SC_PKCS15_CDF_TRUSTED:
 2013     case SC_PKCS15_CDF_USEFUL:
 2014         func = sc_pkcs15_encode_cdf_entry;
 2015         break;
 2016     case SC_PKCS15_DODF:
 2017         func = sc_pkcs15_encode_dodf_entry;
 2018         break;
 2019     case SC_PKCS15_AODF:
 2020         func = sc_pkcs15_encode_aodf_entry;
 2021         break;
 2022     }
 2023     if (func == NULL) {
 2024         sc_log(ctx, "unknown DF type: %d", df->type);
 2025         *buf_out = NULL;
 2026         *bufsize_out = 0;
 2027         return 0;
 2028     }
 2029     for (obj = p15card->obj_list; obj != NULL; obj = obj->next) {
 2030         if (obj->df != df)
 2031             continue;
 2032         r = func(ctx, obj, &tmp, &tmpsize);
 2033         if (r) {
 2034             free(tmp);
 2035             free(buf);
 2036             return r;
 2037         }
 2038         if (!tmpsize)
 2039             continue;
 2040         p = (u8 *) realloc(buf, bufsize + tmpsize);
 2041         if (!p) {
 2042             free(tmp);
 2043             free(buf);
 2044             return SC_ERROR_OUT_OF_MEMORY;
 2045         }
 2046         buf = p;
 2047         memcpy(buf + bufsize, tmp, tmpsize);
 2048         free(tmp);
 2049         bufsize += tmpsize;
 2050     }
 2051     *buf_out = buf;
 2052     *bufsize_out = bufsize;
 2053 
 2054     return 0;
 2055 }
 2056 
 2057 
 2058 int
 2059 sc_pkcs15_parse_df(struct sc_pkcs15_card *p15card, struct sc_pkcs15_df *df)
 2060 {
 2061     struct sc_context *ctx = p15card->card->ctx;
 2062     unsigned char *buf;
 2063     const unsigned char *p;
 2064     size_t bufsize;
 2065     int r;
 2066     struct sc_pkcs15_object *obj = NULL;
 2067     int (* func)(struct sc_pkcs15_card *, struct sc_pkcs15_object *,
 2068              const u8 **nbuf, size_t *nbufsize) = NULL;
 2069 
 2070     sc_log(ctx, "called; path=%s, type=%d, enum=%d", sc_print_path(&df->path), df->type, df->enumerated);
 2071 
 2072     if (df->enumerated)
 2073         LOG_FUNC_RETURN(ctx, SC_SUCCESS);
 2074 
 2075     switch (df->type) {
 2076     case SC_PKCS15_PRKDF:
 2077         func = sc_pkcs15_decode_prkdf_entry;
 2078         break;
 2079     case SC_PKCS15_PUKDF:
 2080         func = sc_pkcs15_decode_pukdf_entry;
 2081         break;
 2082     case SC_PKCS15_SKDF:
 2083         func = sc_pkcs15_decode_skdf_entry;
 2084         break;
 2085     case SC_PKCS15_CDF:
 2086     case SC_PKCS15_CDF_TRUSTED:
 2087     case SC_PKCS15_CDF_USEFUL:
 2088         func = sc_pkcs15_decode_cdf_entry;
 2089         break;
 2090     case SC_PKCS15_DODF:
 2091         func = sc_pkcs15_decode_dodf_entry;
 2092         break;
 2093     case SC_PKCS15_AODF:
 2094         func = sc_pkcs15_decode_aodf_entry;
 2095         break;
 2096     }
 2097     if (func == NULL) {
 2098         sc_log(ctx, "unknown DF type: %d", df->type);
 2099         LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
 2100     }
 2101     r = sc_pkcs15_read_file(p15card, &df->path, &buf, &bufsize);
 2102     LOG_TEST_RET(ctx, r, "pkcs15 read file failed");
 2103 
 2104     p = buf;
 2105     while (bufsize && *p != 0x00) {
 2106 
 2107         obj = calloc(1, sizeof(struct sc_pkcs15_object));
 2108         if (obj == NULL) {
 2109             r = SC_ERROR_OUT_OF_MEMORY;
 2110             goto ret;
 2111         }
 2112         r = func(p15card, obj, &p, &bufsize);
 2113         if (r) {
 2114             free(obj);
 2115             if (r == SC_ERROR_ASN1_END_OF_CONTENTS) {
 2116                 r = 0;
 2117                 break;
 2118             }
 2119             sc_log(ctx, "%s: Error decoding DF entry", sc_strerror(r));
 2120             goto ret;
 2121         }
 2122 
 2123         obj->df = df;
 2124         r = sc_pkcs15_add_object(p15card, obj);
 2125         if (r) {
 2126             if (obj->data)
 2127                 free(obj->data);
 2128             free(obj);
 2129             sc_log(ctx, "%s: Error adding object", sc_strerror(r));
 2130             goto ret;
 2131         }
 2132     };
 2133 
 2134     if (r > 0)
 2135         r = 0;
 2136 ret:
 2137     df->enumerated = 1;
 2138     free(buf);
 2139     LOG_FUNC_RETURN(ctx, r);
 2140 }
 2141 
 2142 
 2143 int
 2144 sc_pkcs15_add_unusedspace(struct sc_pkcs15_card *p15card, const struct sc_path *path,
 2145         const struct sc_pkcs15_id *auth_id)
 2146 {
 2147     struct sc_context *ctx = p15card->card->ctx;
 2148     struct sc_pkcs15_unusedspace *p = p15card->unusedspace_list, *new_unusedspace;
 2149 
 2150     if (path->count == -1) {
 2151         char pbuf[SC_MAX_PATH_STRING_SIZE];
 2152 
 2153         int r = sc_path_print(pbuf, sizeof(pbuf), path);
 2154         if (r != SC_SUCCESS)
 2155             pbuf[0] = '\0';
 2156 
 2157         sc_log(ctx, "No offset and length present in path %s", pbuf);
 2158         return SC_ERROR_INVALID_ARGUMENTS;
 2159     }
 2160 
 2161     new_unusedspace = calloc(1, sizeof(sc_pkcs15_unusedspace_t));
 2162     if (new_unusedspace == NULL)
 2163         return SC_ERROR_OUT_OF_MEMORY;
 2164     new_unusedspace->path = *path;
 2165     if (auth_id != NULL)
 2166         new_unusedspace->auth_id = *auth_id;
 2167 
 2168     if (p15card->unusedspace_list == NULL) {
 2169         p15card->unusedspace_list = new_unusedspace;
 2170         return 0;
 2171     }
 2172     while (p->next != NULL)
 2173         p = p->next;
 2174     p->next = new_unusedspace;
 2175     new_unusedspace->prev = p;
 2176 
 2177     return 0;
 2178 }
 2179 
 2180 
 2181 void
 2182 sc_pkcs15_remove_unusedspace(struct sc_pkcs15_card *p15card, struct sc_pkcs15_unusedspace *unusedspace)
 2183 {
 2184     if (!unusedspace)
 2185         return;
 2186 
 2187     if (!unusedspace->prev)
 2188         p15card->unusedspace_list = unusedspace->next;
 2189     else
 2190         unusedspace->prev->next = unusedspace->next;
 2191 
 2192     if (unusedspace->next)
 2193         unusedspace->next->prev = unusedspace->prev;
 2194 
 2195     free(unusedspace);
 2196 }
 2197 
 2198 
 2199 static void
 2200 sc_pkcs15_free_unusedspace(struct sc_pkcs15_card *p15card)
 2201 {
 2202     struct sc_pkcs15_unusedspace *cur = NULL, *next = NULL;
 2203 
 2204     if (!p15card || !p15card->unusedspace_list)
 2205         return;
 2206     for (cur = p15card->unusedspace_list; cur; cur = next)   {
 2207         next = cur->next;
 2208         free(cur);
 2209     }
 2210 
 2211     p15card->unusedspace_list = NULL;
 2212 }
 2213 
 2214 
 2215 int
 2216 sc_pkcs15_encode_unusedspace(struct sc_context *ctx, struct sc_pkcs15_card *p15card,
 2217              unsigned char **buf, size_t *buflen)
 2218 {
 2219     struct sc_path dummy_path;
 2220     static const struct sc_asn1_entry c_asn1_unusedspace[] = {
 2221         { "UnusedSpace", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
 2222         { NULL, 0, 0, 0, NULL, NULL }
 2223     };
 2224     static const struct sc_asn1_entry c_asn1_unusedspace_values[] = {
 2225         { "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
 2226         { "authId", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
 2227         { NULL, 0, 0, 0, NULL, NULL }
 2228     };
 2229     struct sc_asn1_entry *asn1_unusedspace = NULL;
 2230     struct sc_asn1_entry *asn1_values = NULL;
 2231     int unusedspace_count = 0, r, c = 0;
 2232     struct sc_pkcs15_unusedspace *unusedspace = NULL;
 2233 
 2234     sc_format_path("3F00", &dummy_path);
 2235     dummy_path.index = dummy_path.count = 0;
 2236 
 2237     unusedspace = p15card->unusedspace_list;
 2238     for ( ; unusedspace != NULL; unusedspace = unusedspace->next)
 2239         unusedspace_count++;
 2240     if (unusedspace_count == 0) {
 2241         /* The standard says there has to be at least 1 entry,
 2242          * so we use a path with a length of 0 bytes */
 2243         r = sc_pkcs15_add_unusedspace(p15card, &dummy_path, NULL);
 2244         if (r)
 2245             return r;
 2246         unusedspace_count = 1;
 2247     }
 2248 
 2249     asn1_unusedspace = (struct sc_asn1_entry *)
 2250         malloc(sizeof(struct sc_asn1_entry) * (unusedspace_count + 1));
 2251     if (asn1_unusedspace == NULL) {
 2252         r = SC_ERROR_OUT_OF_MEMORY;
 2253         goto err;
 2254     }
 2255     asn1_values = (struct sc_asn1_entry *)
 2256         malloc(sizeof(struct sc_asn1_entry) * (unusedspace_count * 3));
 2257     if (asn1_values == NULL) {
 2258         r = SC_ERROR_OUT_OF_MEMORY;
 2259         goto err;
 2260     }
 2261 
 2262     for (unusedspace = p15card->unusedspace_list; unusedspace != NULL; unusedspace = unusedspace->next) {
 2263         sc_copy_asn1_entry(c_asn1_unusedspace, asn1_unusedspace + c);
 2264         sc_format_asn1_entry(asn1_unusedspace + c, asn1_values + 3*c, NULL, 1);
 2265         sc_copy_asn1_entry(c_asn1_unusedspace_values, asn1_values + 3*c);
 2266         sc_format_asn1_entry(asn1_values + 3*c, &unusedspace->path, NULL, 1);
 2267         sc_format_asn1_entry(asn1_values + 3*c+1, &unusedspace->auth_id, NULL,
 2268                unusedspace->auth_id.len > 0 ? 1 : 0);
 2269         c++;
 2270     }
 2271     asn1_unusedspace[c].name = NULL;
 2272 
 2273     r = sc_asn1_encode(ctx, asn1_unusedspace, buf, buflen);
 2274 
 2275 err:
 2276     if (asn1_values != NULL)
 2277         free(asn1_values);
 2278     if (asn1_unusedspace != NULL)
 2279         free(asn1_unusedspace);
 2280 
 2281     /* If we added the dummy entry, remove it now */
 2282     if (unusedspace_count == 1 && sc_compare_path(&p15card->unusedspace_list->path, &dummy_path))
 2283         sc_pkcs15_remove_unusedspace(p15card, p15card->unusedspace_list);
 2284 
 2285     return r;
 2286 }
 2287 
 2288 
 2289 int
 2290 sc_pkcs15_parse_unusedspace(const unsigned char *buf, size_t buflen, struct sc_pkcs15_card *p15card)
 2291 {
 2292     const unsigned char *p = buf;
 2293     size_t left = buflen;
 2294     int r;
 2295     struct sc_path path;
 2296     struct sc_pkcs15_id auth_id;
 2297     struct sc_asn1_entry asn1_unusedspace[] = {
 2298         { "UnusedSpace", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
 2299         { NULL, 0, 0, 0, NULL, NULL }
 2300     };
 2301     struct sc_asn1_entry asn1_unusedspace_values[] = {
 2302         { "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
 2303         { "authId", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
 2304         { NULL, 0, 0, 0, NULL, NULL }
 2305     };
 2306 
 2307     /* Clean the list if already present */
 2308     sc_pkcs15_free_unusedspace(p15card);
 2309 
 2310     sc_format_asn1_entry(asn1_unusedspace, asn1_unusedspace_values, NULL, 1);
 2311     sc_format_asn1_entry(asn1_unusedspace_values, &path, NULL, 1);
 2312     sc_format_asn1_entry(asn1_unusedspace_values+1, &auth_id, NULL, 0);
 2313 
 2314     while (left > 0) {
 2315         memset(&auth_id, 0, sizeof(auth_id));
 2316         r = sc_asn1_decode(p15card->card->ctx, asn1_unusedspace, p, left, &p, &left);
 2317         if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
 2318             break;
 2319         if (r < 0)
 2320             return r;
 2321         /* If the path length is 0, it's a dummy path then don't add it.
 2322          * If the path length isn't included (-1) then it's against the standard
 2323          *   but we'll just ignore it instead of returning an error. */
 2324         if (path.count > 0 && p15card->file_app) {
 2325             r = sc_pkcs15_make_absolute_path(&p15card->file_app->path, &path);
 2326             if (r < 0)
 2327                 return r;
 2328             r = sc_pkcs15_add_unusedspace(p15card, &path, &auth_id);
 2329             if (r)
 2330                 return r;
 2331         }
 2332     }
 2333 
 2334     p15card->unusedspace_read = 1;
 2335 
 2336     return 0;
 2337 }
 2338 
 2339 
 2340 int
 2341 sc_pkcs15_read_file(struct sc_pkcs15_card *p15card, const struct sc_path *in_path,
 2342         unsigned char **buf, size_t *buflen)
 2343 {
 2344     struct sc_context *ctx;
 2345     struct sc_file *file = NULL;
 2346     unsigned char *data = NULL;
 2347     size_t  len = 0, offset = 0;
 2348     int r;
 2349 
 2350     if (p15card == NULL || p15card->card == NULL || in_path == NULL || buf == NULL) {
 2351         return SC_ERROR_INVALID_ARGUMENTS;
 2352     }
 2353     ctx = p15card->card->ctx;
 2354 
 2355     LOG_FUNC_CALLED(ctx);
 2356     sc_log(ctx, "path=%s, index=%u, count=%d", sc_print_path(in_path), in_path->index, in_path->count);
 2357 
 2358     r = -1; /* file state: not in cache */
 2359     if (p15card->opts.use_file_cache) {
 2360         r = sc_pkcs15_read_cached_file(p15card, in_path, &data, &len);
 2361 
 2362         if (!r && in_path->aid.len > 0 && in_path->len >= 2)   {
 2363             struct sc_path parent = *in_path;
 2364 
 2365             parent.len -= 2;
 2366             parent.type = SC_PATH_TYPE_PATH;
 2367             r = sc_select_file(p15card->card, &parent, NULL);
 2368         }
 2369     }
 2370 
 2371     if (r) {
 2372         r = sc_lock(p15card->card);
 2373         if (r)
 2374             goto fail;
 2375         r = sc_select_file(p15card->card, in_path, &file);
 2376         if (r)
 2377             goto fail_unlock;
 2378 
 2379         /* Handle the case where the ASN.1 Path object specified
 2380          * index and length values */
 2381         if (in_path->count < 0) {
 2382             if (file->size)
 2383                 len = file->size;
 2384             else
 2385                 len = 1024;
 2386             offset = 0;
 2387         }
 2388         else {
 2389             offset = in_path->index;
 2390             len = in_path->count;
 2391             /* Make sure we're within proper bounds */
 2392             if (offset >= file->size || offset + len > file->size) {
 2393                 r = SC_ERROR_INVALID_ASN1_OBJECT;
 2394                 goto fail_unlock;
 2395             }
 2396         }
 2397         data = malloc(len);
 2398         if (data == NULL) {
 2399             r = SC_ERROR_OUT_OF_MEMORY;
 2400             goto fail_unlock;
 2401         }
 2402 
 2403         if (file->ef_structure == SC_FILE_EF_LINEAR_VARIABLE_TLV) {
 2404             unsigned int i;
 2405             size_t l, record_len;
 2406             unsigned char *head = data;
 2407 
 2408             for (i=1; ; i++) {
 2409                 l = len - (head - data);
 2410                 if (l > 256) {
 2411                     l = 256;
 2412                 }
 2413                 r = sc_read_record(p15card->card, i, head, l, SC_RECORD_BY_REC_NR);
 2414                 if (r == SC_ERROR_RECORD_NOT_FOUND)
 2415                     break;
 2416                 if (r < 0) {
 2417                     goto fail_unlock;
 2418                 }
 2419                 if (r < 2)
 2420                     break;
 2421                 record_len = head[1];
 2422                 if (record_len != 0xff) {
 2423                     memmove(head, head+2, r-2);
 2424                     head += (r-2);
 2425                 }
 2426                 else {
 2427                     if (r < 4)
 2428                         break;
 2429                     memmove(head, head+4, r-4);
 2430                     head += (r-4);
 2431                 }
 2432             }
 2433             len = head-data;
 2434         }
 2435         else {
 2436             r = sc_read_binary(p15card->card, offset, data, len, 0);
 2437             if (r < 0) {
 2438                 goto fail_unlock;
 2439             }
 2440             /* sc_read_binary may return less than requested */
 2441             len = r;
 2442         }
 2443         sc_unlock(p15card->card);
 2444 
 2445         sc_file_free(file);
 2446 
 2447         if (len && p15card->opts.use_file_cache) {
 2448             sc_pkcs15_cache_file(p15card, in_path, data, len);
 2449         }
 2450     }
 2451     *buf = data;
 2452     *buflen = len;
 2453     LOG_FUNC_RETURN(ctx, SC_SUCCESS);
 2454 
 2455 fail_unlock:
 2456     sc_unlock(p15card->card);
 2457 fail:
 2458     free(data);
 2459     sc_file_free(file);
 2460     LOG_FUNC_RETURN(ctx, r);
 2461 }
 2462 
 2463 
 2464 int
 2465 sc_pkcs15_compare_id(const struct sc_pkcs15_id *id1, const struct sc_pkcs15_id *id2)
 2466 {
 2467     if (id1 == NULL || id2 == NULL)
 2468         return 0;
 2469     if (id1->len != id2->len)
 2470         return 0;
 2471     return memcmp(id1->value, id2->value, id1->len) == 0;
 2472 }
 2473 
 2474 
 2475 void
 2476 sc_pkcs15_format_id(const char *str, struct sc_pkcs15_id *id)
 2477 {
 2478     size_t len;
 2479 
 2480     if (!id)
 2481         return;
 2482     len = sizeof(id->value);
 2483 
 2484     if (sc_hex_to_bin(str, id->value, &len) != SC_SUCCESS)
 2485         id->len = 0;
 2486     else
 2487         id->len = len;
 2488 }
 2489 
 2490 
 2491 const char *
 2492 sc_pkcs15_print_id(const struct sc_pkcs15_id *id)
 2493 {
 2494     static char buffer[256];
 2495 
 2496     sc_bin_to_hex(id->value, id->len, buffer, sizeof(buffer), '\0');
 2497     return buffer;
 2498 }
 2499 
 2500 
 2501 int
 2502 sc_pkcs15_hex_string_to_id(const char *in, struct sc_pkcs15_id *out)
 2503 {
 2504     out->len = sizeof(out->value);
 2505     return sc_hex_to_bin(in, out->value, &out->len);
 2506 }
 2507 
 2508 
 2509 int
 2510 sc_pkcs15_make_absolute_path(const struct sc_path *parent, struct sc_path *child)
 2511 {
 2512     /* nothing to do if child has valid 'aid' */
 2513     if (child->aid.len)
 2514         return SC_SUCCESS;
 2515 
 2516     if (parent->aid.len)   {
 2517         sc_path_t ppath;
 2518 
 2519         /* child inherits parent's 'aid' */
 2520         child->aid = parent->aid;
 2521         if (!parent->len)
 2522             return SC_SUCCESS;
 2523 
 2524         /* parent has valid 'path' -- concatenate it with the child's one */
 2525         memcpy(&ppath, parent, sizeof(sc_path_t));
 2526         ppath.aid.len = 0;
 2527         ppath.type = SC_PATH_TYPE_FROM_CURRENT;
 2528         return sc_concatenate_path(child, &ppath, child);
 2529 
 2530     }
 2531     else if (parent->type == SC_PATH_TYPE_DF_NAME)   {
 2532         /* child inherits parent's 'DF NAME' as 'aid' */
 2533         if (parent->len > sizeof(child->aid.value))
 2534             return SC_ERROR_WRONG_LENGTH;
 2535 
 2536         memcpy(child->aid.value, parent->value, parent->len);
 2537         child->aid.len = parent->len;
 2538 
 2539         return SC_SUCCESS;
 2540     }
 2541 
 2542     /* a 0 length path stays a 0 length path */
 2543     if (child->len == 0)
 2544         return SC_SUCCESS;
 2545 
 2546     if (sc_compare_path_prefix(sc_get_mf_path(), child))
 2547         return SC_SUCCESS;
 2548 
 2549     return sc_concatenate_path(child, parent, child);
 2550 }
 2551 
 2552 
 2553 void sc_pkcs15_free_object_content(struct sc_pkcs15_object *obj)
 2554 {
 2555     if (obj->content.value && obj->content.len)   {
 2556         if (SC_PKCS15_TYPE_AUTH & obj->type
 2557             || SC_PKCS15_TYPE_SKEY & obj->type
 2558             || SC_PKCS15_TYPE_PRKEY & obj->type) {
 2559             /* clean everything that potentially contains a secret */
 2560             sc_mem_clear(obj->content.value, obj->content.len);
 2561             sc_mem_secure_free(obj->content.value, obj->content.len);
 2562         } else {
 2563             free(obj->content.value);
 2564         }
 2565     }
 2566     obj->content.value = NULL;
 2567     obj->content.len = 0;
 2568 }
 2569 
 2570 
 2571 int
 2572 sc_pkcs15_allocate_object_content(struct sc_context *ctx, struct sc_pkcs15_object *obj,
 2573         const unsigned char *value, size_t len)
 2574 {
 2575     unsigned char *tmp_buf;
 2576 
 2577     if (!obj)
 2578         return SC_ERROR_INVALID_ARGUMENTS;
 2579 
 2580     if (!value || !len)   {
 2581         sc_pkcs15_free_object_content(obj);
 2582         return SC_SUCCESS;
 2583     }
 2584 
 2585     /* Need to pass by temporary variable,
 2586      * because 'value' and 'content.value' pointers can be the sames.
 2587      */
 2588     if (SC_PKCS15_TYPE_AUTH & obj->type
 2589             || SC_PKCS15_TYPE_SKEY & obj->type
 2590             || SC_PKCS15_TYPE_PRKEY & obj->type) {
 2591         tmp_buf = sc_mem_secure_alloc(len);
 2592     } else {
 2593         tmp_buf = malloc(len);
 2594     }
 2595     if (!tmp_buf)
 2596         return SC_ERROR_OUT_OF_MEMORY;
 2597 
 2598     memcpy(tmp_buf, value, len);
 2599 
 2600     sc_pkcs15_free_object_content(obj);
 2601 
 2602     obj->content.value = tmp_buf;
 2603     obj->content.len = len;
 2604 
 2605     return SC_SUCCESS;
 2606 }
 2607 
 2608 
 2609 struct sc_supported_algo_info *
 2610 sc_pkcs15_get_supported_algo(struct sc_pkcs15_card *p15card, unsigned operation, unsigned mechanism)
 2611 {
 2612     struct sc_context *ctx = p15card->card->ctx;
 2613     struct sc_supported_algo_info *info = NULL;
 2614     int ii;
 2615 
 2616     for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference; ii++)
 2617         if ((p15card->tokeninfo->supported_algos[ii].operations & operation)
 2618                 && (p15card->tokeninfo->supported_algos[ii].mechanism == mechanism))
 2619             break;
 2620 
 2621     if (ii < SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference)   {
 2622         info = &p15card->tokeninfo->supported_algos[ii];
 2623         sc_log(ctx, "found supported algorithm (ref:%X,mech:%X,ops:%X,algo_ref:%X)",
 2624                 info->reference, info->mechanism, info->operations, info->algo_ref);
 2625     }
 2626 
 2627     return info;
 2628 }
 2629 
 2630 struct sc_supported_algo_info *
 2631 sc_pkcs15_get_specific_supported_algo(struct sc_pkcs15_card *p15card, unsigned operation, unsigned mechanism, const struct sc_object_id *algo_oid)
 2632 {
 2633     struct sc_context *ctx = p15card->card->ctx;
 2634     struct sc_supported_algo_info *info = NULL;
 2635     int ii;
 2636 
 2637     if (algo_oid == NULL)
 2638         return NULL;
 2639 
 2640     for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference; ii++)
 2641         if ((p15card->tokeninfo->supported_algos[ii].operations & operation)
 2642                 && (p15card->tokeninfo->supported_algos[ii].mechanism == mechanism)
 2643                 && sc_compare_oid(algo_oid, &p15card->tokeninfo->supported_algos[ii].algo_id) == 1)
 2644             break;
 2645 
 2646     if (ii < SC_MAX_SUPPORTED_ALGORITHMS && p15card->tokeninfo->supported_algos[ii].reference)   {
 2647         info = &p15card->tokeninfo->supported_algos[ii];
 2648         sc_log(ctx, "found supported algorithm (ref:%X,mech:%X,ops:%X,algo_ref:%X)",
 2649                 info->reference, info->mechanism, info->operations, info->algo_ref);
 2650     }
 2651 
 2652     return info;
 2653 }
 2654 
 2655 int
 2656 sc_pkcs15_get_generalized_time(struct sc_context *ctx, char **out)
 2657 {
 2658 #ifdef HAVE_GETTIMEOFDAY
 2659     struct timeval tv;
 2660 #endif
 2661     struct tm tm;
 2662     time_t t;
 2663 
 2664     if (!ctx || !out)
 2665         return SC_ERROR_INVALID_ARGUMENTS;
 2666     *out = NULL;
 2667 
 2668 #ifdef HAVE_GETTIMEOFDAY
 2669     gettimeofday(&tv, NULL);
 2670     t = tv.tv_sec;
 2671 #else
 2672     t = time(NULL);
 2673 #endif
 2674 
 2675 #ifdef _WIN32
 2676     if (0 != gmtime_s(&tm, &t))
 2677         LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
 2678 #else
 2679     if (NULL == gmtime_r(&t, &tm))
 2680         LOG_FUNC_RETURN(ctx, SC_ERROR_INTERNAL);
 2681 #endif
 2682 
 2683     *out = calloc(1, 16);
 2684     if (*out == NULL)
 2685         LOG_TEST_RET(ctx, SC_ERROR_OUT_OF_MEMORY, "memory failure");
 2686 
 2687     /* print time in generalized time format */
 2688     if (!strftime(*out, 16, "%Y%m%d%H%M%SZ", &tm)) {
 2689         free(*out);
 2690         LOG_TEST_RET(ctx, SC_ERROR_INTERNAL, "strftime failed");
 2691     }
 2692 
 2693     return SC_SUCCESS;
 2694 }
 2695 
 2696 
 2697 int
 2698 sc_pkcs15_add_supported_algo_ref(struct sc_pkcs15_object *obj, struct sc_supported_algo_info *algo)
 2699 {
 2700     unsigned int ii, *algo_refs = NULL;
 2701 
 2702     if (!algo)
 2703         return SC_SUCCESS;
 2704 
 2705     switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
 2706     case SC_PKCS15_TYPE_PRKEY:
 2707         algo_refs = ((struct sc_pkcs15_prkey_info *)obj->data)->algo_refs;
 2708         break;
 2709     case SC_PKCS15_TYPE_PUBKEY:
 2710         algo_refs = ((struct sc_pkcs15_pubkey_info *)obj->data)->algo_refs;
 2711         break;
 2712     case SC_PKCS15_TYPE_SKEY:
 2713         algo_refs = ((struct sc_pkcs15_skey_info *)obj->data)->algo_refs;
 2714         break;
 2715     }
 2716     if (!algo_refs)
 2717         return SC_ERROR_NOT_SUPPORTED;
 2718 
 2719     for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS && *(algo_refs + ii);ii++)
 2720         if (*(algo_refs + ii) == algo->reference)
 2721             return SC_SUCCESS;
 2722 
 2723     for (ii=0;ii<SC_MAX_SUPPORTED_ALGORITHMS;ii++)   {
 2724         if (*(algo_refs + ii) == 0)   {
 2725             *(algo_refs + ii) = algo->reference;
 2726             return SC_SUCCESS;
 2727         }
 2728     }
 2729 
 2730     return SC_ERROR_TOO_MANY_OBJECTS;
 2731 }
 2732 
 2733 
 2734 int
 2735 sc_pkcs15_get_object_id(const struct sc_pkcs15_object *obj, struct sc_pkcs15_id *out)
 2736 {
 2737     if (!obj || !out)
 2738         return SC_ERROR_INVALID_ARGUMENTS;
 2739 
 2740     switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
 2741     case SC_PKCS15_TYPE_CERT:
 2742         *out = ((struct sc_pkcs15_cert_info *) obj->data)->id;
 2743         break;
 2744     case SC_PKCS15_TYPE_PRKEY:
 2745         *out = ((struct sc_pkcs15_prkey_info *) obj->data)->id;
 2746         break;
 2747     case SC_PKCS15_TYPE_PUBKEY:
 2748         *out = ((struct sc_pkcs15_pubkey_info *) obj->data)->id;
 2749         break;
 2750     case SC_PKCS15_TYPE_SKEY:
 2751         *out = ((struct sc_pkcs15_skey_info *) obj->data)->id;
 2752         break;
 2753     case SC_PKCS15_TYPE_AUTH:
 2754         *out = ((struct sc_pkcs15_auth_info *) obj->data)->auth_id;
 2755         break;
 2756     case SC_PKCS15_TYPE_DATA_OBJECT:
 2757         *out = ((struct sc_pkcs15_data_info *) obj->data)->id;
 2758         break;
 2759     default:
 2760         return SC_ERROR_NOT_SUPPORTED;
 2761     }
 2762 
 2763     return SC_SUCCESS;
 2764 }
 2765 
 2766 /*
 2767  * Simplified GUID serializing.
 2768  * Ex. {3F2504E0-4F89-11D3-9A0C-0305E82C3301}
 2769  *
 2770  * There is no variant, version number and other special meaning fields
 2771  *  that are described in RFC-4122 .
 2772  */
 2773 int
 2774 sc_pkcs15_serialize_guid(unsigned char *in, size_t in_size, unsigned flags,
 2775         char *out, size_t out_size)
 2776 {
 2777     int ii, jj, offs = 0;
 2778 
 2779     if (in_size < 16)
 2780         return SC_ERROR_BUFFER_TOO_SMALL;
 2781     if (out_size < 39)
 2782         return SC_ERROR_BUFFER_TOO_SMALL;
 2783 
 2784     *out = '\0';
 2785     if (!flags)
 2786         strcpy(out, "{");
 2787     for (ii=0; ii<4; ii++)
 2788         sprintf(out + strlen(out), "%02x", *(in + offs++));
 2789     for (jj=0; jj<3; jj++)   {
 2790         strcat(out, "-");
 2791         for (ii=0; ii<2; ii++)
 2792             sprintf(out + strlen(out), "%02x", *(in + offs++));
 2793     }
 2794     strcat(out, "-");
 2795     for (ii=0; ii<6; ii++)
 2796         sprintf(out + strlen(out), "%02x", *(in + offs++));
 2797     if (!flags)
 2798         strcat(out, "}");
 2799 
 2800     return SC_SUCCESS;
 2801 }
 2802 
 2803 
 2804 int
 2805 sc_pkcs15_get_object_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj,
 2806         unsigned flags, unsigned char *out, size_t *out_size)
 2807 {
 2808     struct sc_context *ctx = p15card->card->ctx;
 2809     struct sc_serial_number serialnr;
 2810     struct sc_pkcs15_id  id;
 2811     unsigned char guid_bin[SC_PKCS15_MAX_ID_SIZE + SC_MAX_SERIALNR];
 2812     int rv, guid_bin_size;
 2813 
 2814     LOG_FUNC_CALLED(ctx);
 2815     if(!out || !out_size)
 2816         LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
 2817 
 2818     if (p15card->ops.get_guid)   {
 2819         rv = p15card->ops.get_guid(p15card, obj, out, out_size);
 2820         LOG_FUNC_RETURN(ctx, rv);
 2821     }
 2822 
 2823     rv = sc_pkcs15_aux_get_md_guid(p15card, obj, flags, out, out_size);
 2824     if (rv == SC_SUCCESS)
 2825         LOG_FUNC_RETURN(ctx, SC_SUCCESS);
 2826     else if (rv != SC_ERROR_NOT_SUPPORTED)
 2827         LOG_TEST_RET(ctx, rv, "Failed to get alternative object GUID");
 2828 
 2829     memset(out, 0, *out_size);
 2830 
 2831     rv = sc_pkcs15_get_object_id(obj, &id);
 2832     LOG_TEST_RET(ctx, rv, "Cannot get object's ID");
 2833 
 2834     if (p15card->tokeninfo && p15card->tokeninfo->serial_number)   {
 2835         /* The serial from EF(TokenInfo) is preferred because of the
 2836          * "--serial" parameter of pkcs15-init. */
 2837         serialnr.len = SC_MAX_SERIALNR;
 2838         rv = sc_hex_to_bin(p15card->tokeninfo->serial_number, serialnr.value, &serialnr.len);
 2839         if (rv) {
 2840             /* Fallback in case hex_to_bin fails due to unexpected characters */
 2841             serialnr.len = strlen(p15card->tokeninfo->serial_number);
 2842             if (serialnr.len > SC_MAX_SERIALNR)
 2843                 serialnr.len = SC_MAX_SERIALNR;
 2844 
 2845             memcpy(serialnr.value, p15card->tokeninfo->serial_number, serialnr.len);
 2846         }
 2847     } else if (p15card->card->serialnr.len)   {
 2848         serialnr = p15card->card->serialnr;
 2849     } else   {
 2850         rv = sc_card_ctl(p15card->card, SC_CARDCTL_GET_SERIALNR, &serialnr);
 2851         LOG_TEST_RET(ctx, rv, "'GET_SERIALNR' CTL failed and other serial numbers not present");
 2852     }
 2853 
 2854     memset(guid_bin, 0, sizeof(guid_bin));
 2855     memcpy(guid_bin, id.value, id.len);
 2856     memcpy(guid_bin + id.len, serialnr.value, serialnr.len);
 2857     guid_bin_size = id.len + serialnr.len;
 2858 
 2859     /*
 2860      * If OpenSSL is available (SHA1), then rather use the hash of the data
 2861      * - this also protects against data being too short
 2862      */
 2863 #ifdef ENABLE_OPENSSL
 2864     SHA1(guid_bin, guid_bin_size, guid_bin);
 2865     guid_bin_size = SHA_DIGEST_LENGTH;
 2866 #else
 2867     /* If guid_bin has a size larger than 16 bytes
 2868      * force the remaining bytes up to 16 bytes to be zero
 2869      * so sc_pkcs15_serialize_guid won't fail because the size is less than 16
 2870      */
 2871     if (guid_bin_size < 16)
 2872         guid_bin_size = 16;
 2873 #endif
 2874 
 2875     rv = sc_pkcs15_serialize_guid(guid_bin, guid_bin_size, flags, (char *)out, *out_size);
 2876     LOG_TEST_RET(ctx, rv, "Serialize GUID error");
 2877 
 2878     *out_size = strlen((char *)out);
 2879     LOG_FUNC_RETURN(ctx, rv);
 2880 }
 2881 
 2882 
 2883 static int
 2884 sc_pkcs15_aux_get_md_guid(struct sc_pkcs15_card *p15card, const struct sc_pkcs15_object *obj,
 2885         unsigned flags,
 2886         unsigned char *out, size_t *out_size)
 2887 {
 2888     struct sc_context *ctx = p15card->card->ctx;
 2889     struct sc_pkcs15_prkey_info *prkey_info = NULL;
 2890     int rv;
 2891 
 2892     LOG_FUNC_CALLED(ctx);
 2893     if(!out || !out_size)
 2894         LOG_FUNC_RETURN(ctx, SC_ERROR_INVALID_ARGUMENTS);
 2895 
 2896     if ((obj->type & SC_PKCS15_TYPE_CLASS_MASK) != SC_PKCS15_TYPE_PRKEY)
 2897         LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
 2898 
 2899     prkey_info = (struct sc_pkcs15_prkey_info *)obj->data;
 2900     if (!prkey_info->aux_data || prkey_info->aux_data->type != SC_AUX_DATA_TYPE_MD_CMAP_RECORD)
 2901         LOG_FUNC_RETURN(ctx, SC_ERROR_NOT_SUPPORTED);
 2902 
 2903     rv = sc_aux_data_get_md_guid(ctx, prkey_info->aux_data, flags, out, out_size);
 2904     LOG_FUNC_RETURN(ctx, rv);
 2905 }
 2906 
 2907 
 2908 void
 2909 sc_pkcs15_free_key_params(struct sc_pkcs15_key_params *params)
 2910 {
 2911     if (!params)
 2912         return;
 2913     if (params->data && params->free_params)
 2914         params->free_params(params->data);
 2915     else if (params->data)
 2916         free(params->data);
 2917 
 2918     params->data = NULL;
 2919 }
 2920