Ticket #177: itacns-patch4.diff

File itacns-patch4.diff, 39.9 KB (added by ep, 18 months ago)

Updated; further clean-up performed.

  • etc/opensc.conf.in

    diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in
    index 3d00b1b..c432e21 100644
    a b app default { 
    275275                # enable_builtin_emulation = no; 
    276276                # 
    277277                # List of the builtin pkcs15 emulators to test 
    278                 # Default: esteid, openpgp, tcos, starcert, infocamere, postecert, actalis, atrust-acos, gemsafeGPK, gemsafeV1, tccardos, PIV-II; 
     278                # Default: esteid, openpgp, tcos, starcert, itacns, infocamere, postecert, actalis, atrust-acos, gemsafeGPK, gemsafeV1, tccardos, PIV-II; 
    279279                # builtin_emulators = openpgp; 
    280280 
    281281                # additional settings per driver 
  • src/libopensc/Makefile.am

    diff --git a/src/libopensc/Makefile.am b/src/libopensc/Makefile.am
    index 8837952..dfe8ef0 100644
    a b libopensc_la_SOURCES = \ 
    3737        card-incrypto34.c card-piv.c card-muscle.c card-acos5.c \ 
    3838        card-asepcos.c card-akis.c card-gemsafeV1.c card-rutoken.c \ 
    3939        card-rtecp.c card-westcos.c card-myeid.c card-ias.c \ 
    40         card-javacard.c \ 
     40        card-javacard.c card-itacns.c \ 
    4141        \ 
    4242        pkcs15-openpgp.c pkcs15-infocamere.c pkcs15-starcert.c \ 
    4343        pkcs15-tcos.c pkcs15-esteid.c pkcs15-postecert.c pkcs15-gemsafeGPK.c \ 
    4444        pkcs15-actalis.c pkcs15-atrust-acos.c pkcs15-tccardos.c pkcs15-piv.c \ 
    4545        pkcs15-esinit.c pkcs15-westcos.c pkcs15-pteid.c pkcs15-oberthur.c \ 
     46        pkcs15-itacns.c \ 
    4647        compression.c p15card-helper.c \ 
    4748        libopensc.exports 
    4849if WIN32 
  • src/libopensc/Makefile.mak

    diff --git a/src/libopensc/Makefile.mak b/src/libopensc/Makefile.mak
    index e93ac0c..230ef76 100644
    a b OBJECTS = \ 
    2121        card-incrypto34.obj card-piv.obj card-muscle.obj card-acos5.obj \ 
    2222        card-asepcos.obj card-akis.obj card-gemsafeV1.obj card-rutoken.obj \ 
    2323        card-rtecp.obj card-westcos.obj card-myeid.obj card-ias.obj \ 
    24         card-javacard.obj \ 
     24        card-javacard.obj card-itacns.obj \ 
    2525        \ 
    2626        pkcs15-openpgp.obj pkcs15-infocamere.obj pkcs15-starcert.obj \ 
    2727        pkcs15-tcos.obj pkcs15-esteid.obj pkcs15-postecert.obj pkcs15-gemsafeGPK.obj \ 
    2828        pkcs15-actalis.obj pkcs15-atrust-acos.obj pkcs15-tccardos.obj pkcs15-piv.obj \ 
    2929        pkcs15-esinit.obj pkcs15-westcos.obj pkcs15-pteid.obj pkcs15-oberthur.obj \ 
     30        pkcs15-itacns.obj \ 
    3031        compression.obj p15card-helper.obj \ 
    3132        $(TOPDIR)\win32\versioninfo.res 
    3233 
  • src/libopensc/card-cardos.c

    diff --git a/src/libopensc/card-cardos.c b/src/libopensc/card-cardos.c
    index 555eabe..f6cff9f 100644
    a b  
    3030#include "asn1.h" 
    3131#include "cardctl.h" 
    3232 
     33#define MAX_LE 240 
     34 
    3335static const struct sc_card_operations *iso_ops = NULL; 
    3436 
    3537static struct sc_card_operations cardos_ops; 
    cardos_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, 
    813815                SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_INVALID_ARGUMENTS); 
    814816        if (outlen < datalen) 
    815817                SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_VERBOSE, SC_ERROR_BUFFER_TOO_SMALL); 
    816         outlen = datalen; 
     818 
     819        if (outlen > MAX_LE) 
     820                outlen = MAX_LE; 
    817821 
    818822        /* XXX As we don't know what operations are allowed with a 
    819823         * certain key, let's try RSA_PURE etc. and see which operation 
  • new file src/libopensc/card-itacns.c

    diff --git a/src/libopensc/card-itacns.c b/src/libopensc/card-itacns.c
    new file mode 100644
    index 0000000..ff233f3
    - +  
     1/* 
     2 * card-itacns.c: Support for Italian CNS 
     3 * 
     4 * Copyright (C) 2008  Emanuele Pucciarelli <ep@acm.org> 
     5 * Copyright (C) 2005  ST Incard srl, Giuseppe Amato <giuseppe dot amato at st dot com>, <midori3@gmail.com> 
     6 * Copyright (C) 2002  Andreas Jellinghaus <aj@dungeon.inka.de> 
     7 * Copyright (C) 2001  Juha Yrjölä <juha.yrjola@iki.fi> 
     8 * 
     9 * This library is free software; you can redistribute it and/or 
     10 * modify it under the terms of the GNU Lesser General Public 
     11 * License as published by the Free Software Foundation; either 
     12 * version 2.1 of the License, or (at your option) any later version. 
     13 * 
     14 * This library is distributed in the hope that it will be useful, 
     15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
     17 * Lesser General Public License for more details. 
     18 * 
     19 * You should have received a copy of the GNU Lesser General Public 
     20 * License along with this library; if not, write to the Free Software 
     21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
     22 */ 
     23 
     24/* 
     25 * Specifications for the development of this driver come from: 
     26 * http://www.cnipa.gov.it/html/docs/CNS%20Functional%20Specification%201.1.5_11012010.pdf 
     27 */ 
     28 
     29#include "internal.h" 
     30#include "cardctl.h" 
     31#include "itacns.h" 
     32#include <ctype.h> 
     33#include <string.h> 
     34#include <stdlib.h> 
     35 
     36#define ITACNS_MAX_PAYLOAD 0xff 
     37 
     38static const struct sc_card_operations *default_ops = NULL; 
     39 
     40static struct sc_card_operations itacns_ops; 
     41static struct sc_card_driver itacns_drv = { 
     42        "Carta Nazionale dei Servizi", 
     43        "itacns", 
     44        &itacns_ops, 
     45        NULL, 0, NULL 
     46}; 
     47 
     48/* 
     49 * Card matching 
     50 */ 
     51 
     52 
     53/* List of ATR's for "hard" matching. */ 
     54static struct sc_atr_table itacns_atrs[] = { 
     55        { "3b:f4:18:00:ff:81:31:80:55:00:31:80:00:c7", NULL, NULL, SC_CARD_TYPE_ITACNS_CIE_V1, 0, NULL}, 
     56        { NULL, NULL, NULL, 0, 0, NULL} 
     57}; 
     58 
     59/* Output debug info */ 
     60#define matchdebug(idx, c) do { \ 
     61                sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Matching %x against atr[%d] == %x", c, idx, atr[idx]); \ 
     62        } while(0); 
     63 
     64/* Check that we are not looking at values beyond the ATR's length. 
     65 * If we are, then the card does not match. */ 
     66#define itacns_atr_l(idx) do {if (idx >= card->atr_len) return 0;} while(0); 
     67 
     68/* Match byte exactly and increment index. */ 
     69#define itacns_atr_match(idx, c) do { \ 
     70                itacns_atr_l(idx); \ 
     71                matchdebug(idx, c); \ 
     72                if (((u8)atr[idx]) != c) return 0; \ 
     73                idx++; \ 
     74        } while(0); 
     75 
     76/* Match masked bits and increment index. */ 
     77#define itacns_atr_mmatch(idx, c, mask) do { \ 
     78                itacns_atr_l(idx); \ 
     79                if ((((u8)atr[idx]) & mask) != c) return 0; \ 
     80                idx ++; \ 
     81        } while(0); 
     82 
     83/* Macro to access private driver data. */ 
     84#define DRVDATA(card) ((itacns_drv_data_t *) card->drv_data) 
     85 
     86 
     87int itacns_match_cns_card(sc_card_t *card, int i) 
     88{ 
     89        unsigned char *atr = card->atr; 
     90        sc_context_t *ctx; 
     91        ctx = card->ctx; 
     92 
     93 
     94        itacns_atr_match(i, 0x01); /* H7 */ 
     95        i += 2; /* H8, H9 */ 
     96        itacns_atr_match(i, 'C'); /* H10 */ 
     97        itacns_atr_match(i, 'N'); /* H11 */ 
     98        itacns_atr_match(i, 'S'); /* H12 */ 
     99 
     100        /* H13 */ 
     101        /* Version byte: h.l, h in the high nibble, l in the low nibble. */ 
     102        if(card->driver) { 
     103                DRVDATA(card)->cns_version = atr[i]; 
     104        } 
     105        /* Warn if the version is not 1.0. */ 
     106        if(atr[i] != 0x10) { 
     107                char version[8]; 
     108                snprintf(version, sizeof(version), "%d.%d", (atr[i] >> 4) & 0x0f, atr[i] & 0x0f); 
     109                sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "CNS card version %s; no official specifications " 
     110                        "are published. Proceeding anyway.\n", version); 
     111        } 
     112        i++; 
     113 
     114        itacns_atr_match(i, 0x31); /* H14 */ 
     115        itacns_atr_match(i, 0x80); /* H15 */ 
     116 
     117        card->type = SC_CARD_TYPE_ITACNS_CNS; 
     118 
     119        return 1; 
     120} 
     121 
     122int itacns_match_cie_card(sc_card_t *card, int i) 
     123{ 
     124        unsigned char *atr = card->atr; 
     125        sc_context_t *ctx; 
     126        ctx = card->ctx; 
     127 
     128        itacns_atr_match(i, 0x02); /* H7 */ 
     129        itacns_atr_match(i, 'I'); /* H8 */ 
     130        itacns_atr_match(i, 'T'); /* H9 */ 
     131        itacns_atr_match(i, 'I'); /* H10 */ 
     132        itacns_atr_match(i, 'D'); /* H11 */ 
     133        itacns_atr_match(i, 0x20); /* H12 */ 
     134        itacns_atr_match(i, 0x20); /* H13 */ 
     135        itacns_atr_match(i, 0x31); /* H14 */ 
     136        itacns_atr_match(i, 0x80); /* H15 */ 
     137 
     138        card->type = SC_CARD_TYPE_ITACNS_CIE_V2; 
     139 
     140        return 1; 
     141} 
     142 
     143int itacns_match_card(sc_card_t *card) 
     144{ 
     145        int i = 0, r; 
     146        unsigned char *atr = card->atr; 
     147        sc_context_t *ctx; 
     148        ctx = card->ctx; 
     149 
     150        /* Try table first */ 
     151        r = _sc_match_atr(card, itacns_atrs, &card->type); 
     152        if(r >= 0) return 1; 
     153 
     154        /* The ATR was not recognized; try to match it 
     155           according to the official specs. */ 
     156 
     157        /* Check ATR up to byte H6 */ 
     158        itacns_atr_match(i, 0x3b); /* TS */ 
     159        itacns_atr_mmatch(i, 0x8f, 0x8f); /* T0 */ 
     160        /* TA1, TB1, TC1 */ 
     161        if(atr[1] & 0x40) i++; 
     162        if(atr[1] & 0x20) i++; 
     163        if(atr[1] & 0x10) i++; 
     164        /* TD1 */ 
     165        int td1_idx = i; 
     166        itacns_atr_mmatch(i, 0x81, 0x8f); 
     167        /* TA2, TB2, TC2 */ 
     168        if(atr[td1_idx] & 0x40) i++; 
     169        if(atr[td1_idx] & 0x20) i++; 
     170        if(atr[td1_idx] & 0x10) i++; 
     171        /* TD2 */ 
     172        itacns_atr_match(i, 0x31); 
     173        i += 2; /* TA3, TB3 */ 
     174        itacns_atr_match(i, 0x00); /* H1 */ 
     175        itacns_atr_match(i, 0x6b); /* H2 */ 
     176        /* Store interesting data */ 
     177        if(card->driver) { 
     178                DRVDATA(card)->ic_manufacturer_code = card->atr[i]; 
     179                DRVDATA(card)->mask_manufacturer_code = card->atr[i+1]; 
     180                DRVDATA(card)->os_version_h = card->atr[i+2]; 
     181                DRVDATA(card)->os_version_l = card->atr[i+3]; 
     182        } 
     183        i += 4; /* H3, H4, H5, H6 */ 
     184 
     185        /* Check final part. */ 
     186        if (itacns_match_cns_card(card, i)) return 1; 
     187        if (itacns_match_cie_card(card, i)) return 1; 
     188 
     189        /* No card type was matched. */ 
     190        return 0; 
     191} 
     192 
     193/* 
     194 * Initialization and termination 
     195 */ 
     196 
     197static int itacns_init(sc_card_t *card) 
     198{ 
     199        SC_FUNC_CALLED(card->ctx, 1); 
     200 
     201        unsigned long   flags; 
     202 
     203        card->name = "CNS card"; 
     204        card->cla = 0x00; 
     205 
     206        card->drv_data = calloc(1, sizeof(itacns_drv_data_t)); 
     207 
     208        /* Match ATR again to find the card data. */ 
     209        itacns_match_card(card); 
     210 
     211        /* Set up algorithm info. */ 
     212        flags = SC_ALGORITHM_NEED_USAGE 
     213                | SC_ALGORITHM_RSA_RAW 
     214                | SC_ALGORITHM_RSA_HASHES 
     215                ; 
     216        _sc_card_add_rsa_alg(card, 1024, flags, 0); 
     217 
     218        return 0; 
     219} 
     220 
     221static int itacns_finish(struct sc_card *card) 
     222{ 
     223        if(card->drv_data) { 
     224                free(card->drv_data); 
     225        } 
     226        return 0; 
     227} 
     228 
     229 
     230 
     231/* 
     232 * Restore the indicated SE 
     233 */ 
     234static int itacns_restore_security_env(sc_card_t *card, int se_num) 
     235{ 
     236        sc_apdu_t apdu; 
     237        int     r; 
     238 
     239        SC_FUNC_CALLED(card->ctx, 1); 
     240 
     241        /* 
     242         * The Italian CNS requires a 0-valued Lc byte at the end of the APDU 
     243         * (see paragraph 13.14 of the Functional Specification), but since 
     244         * it is invalid, we "cheat" and pretend it's a Le byte. 
     245         * 
     246         * For this workaround, we must allocate and supply a response buffer, 
     247         * even though we know it will not be used (and we do not even check it). 
     248         */ 
     249 
     250        u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; 
     251        sc_format_apdu(card, &apdu, SC_APDU_CASE_2, 0x22, 0xF3, se_num); 
     252        apdu.resp = rbuf; 
     253        apdu.resplen = sizeof(rbuf); 
     254        apdu.le = 0; 
     255 
     256        r = sc_transmit_apdu(card, &apdu); 
     257        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); 
     258 
     259        r = sc_check_sw(card, apdu.sw1, apdu.sw2); 
     260        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); 
     261 
     262        SC_FUNC_RETURN(card->ctx, 1, r); 
     263} 
     264 
     265/* 
     266 * Set the security context 
     267 * Things get a little messy here. It seems you cannot do any 
     268 * crypto without a security environment - but there isn't really 
     269 * a way to specify the security environment in PKCS15. 
     270 * What I'm doing here (for now) is to assume that for a key 
     271 * object with ID 0xNN there is always a corresponding SE object 
     272 * with the same ID. 
     273 * XXX Need to find out how the Aladdin drivers do it. 
     274 */ 
     275static int itacns_set_security_env(sc_card_t *card, 
     276                    const sc_security_env_t *env, int se_num) 
     277{ 
     278        sc_apdu_t apdu; 
     279        u8      data[3]; 
     280        int     key_id, r; 
     281 
     282        assert(card != NULL && env != NULL); 
     283 
     284        if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) 
     285         || env->key_ref_len != 1) { 
     286                sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "No or invalid key reference\n"); 
     287                return SC_ERROR_INVALID_ARGUMENTS; 
     288        } 
     289        key_id = env->key_ref[0]; 
     290 
     291        /* CIE v1 cards need to restore security environment 0x30; all the others 
     292           so far want 0x03. */ 
     293        r = itacns_restore_security_env(card, (card->type == SC_CARD_TYPE_ITACNS_CIE_V1 
     294                ? 0x30 : 0x03)); 
     295        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); 
     296 
     297        sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF1, 0); 
     298        switch (env->operation) { 
     299        case SC_SEC_OPERATION_DECIPHER: 
     300                apdu.p2 = 0xB8; 
     301                break; 
     302        case SC_SEC_OPERATION_SIGN: 
     303                apdu.p2 = 0xB6; 
     304                break; 
     305        case SC_SEC_OPERATION_AUTHENTICATE: 
     306                apdu.p2 = 0xA4; 
     307                break; 
     308        default: 
     309                return SC_ERROR_INVALID_ARGUMENTS; 
     310        } 
     311 
     312        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Setting sec env for key_id=%d\n", key_id); 
     313 
     314        data[0] = 0x83; 
     315        data[1] = 0x01; 
     316        data[2] = key_id; 
     317        apdu.lc = apdu.datalen = 3; 
     318        apdu.data = data; 
     319 
     320        r = sc_transmit_apdu(card, &apdu); 
     321        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); 
     322 
     323        r = sc_check_sw(card, apdu.sw1, apdu.sw2); 
     324        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); 
     325 
     326        SC_FUNC_RETURN(card->ctx, 1, r); 
     327} 
     328 
     329/* 
     330 * The 0x80 thing tells the card it's okay to search parent 
     331 * directories as well for the referenced object. 
     332 * This is necessary for some Italian CNS cards, and to be avoided 
     333 * for others. Right now it seems that it is only needed with 
     334 * cards by STIncard. 
     335 */ 
     336static int 
     337itacns_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, 
     338                 int *tries_left) 
     339{ 
     340        data->flags |= SC_PIN_CMD_NEED_PADDING; 
     341        /* Enable backtracking for STIncard cards. */ 
     342        if(DRVDATA(card)->mask_manufacturer_code == ITACNS_MASKMAN_STINCARD) { 
     343                data->pin_reference |= 0x80; 
     344        } 
     345 
     346        /* FIXME: the following values depend on what pin length was 
     347         * used when creating the BS objects */ 
     348        if (data->pin1.max_length == 0) 
     349                data->pin1.max_length = 8; 
     350        if (data->pin2.max_length == 0) 
     351                data->pin2.max_length = 8; 
     352        return default_ops->pin_cmd(card, data, tries_left); 
     353} 
     354 
     355static int itacns_read_binary(sc_card_t *card, 
     356                               unsigned int idx, u8 *buf, size_t count, 
     357                               unsigned long flags) 
     358{ 
     359        size_t already_read = 0; 
     360        size_t requested; 
     361        int r; 
     362        while(1) { 
     363                requested = count - already_read; 
     364                if(requested > ITACNS_MAX_PAYLOAD) requested = ITACNS_MAX_PAYLOAD; 
     365                r = default_ops->read_binary(card, idx+already_read, &buf[already_read], 
     366                        requested, flags); 
     367                if(r < 0) return r; 
     368                already_read += r; 
     369                if (r == 0 || r < requested || already_read == count) { 
     370                        /* We have finished */ 
     371                        return already_read; 
     372                } 
     373        } 
     374} 
     375 
     376static int itacns_list_files(sc_card_t *card, u8 *buf, size_t buflen) { 
     377        struct sc_card_operations *list_ops; 
     378 
     379        if (DRVDATA(card) && DRVDATA(card)->mask_manufacturer_code == ITACNS_MASKMAN_SIEMENS) { 
     380                list_ops = sc_get_cardos_driver()->ops; 
     381        } else { 
     382                list_ops = sc_get_incrypto34_driver()->ops; 
     383        } 
     384        return list_ops->list_files(card, buf, buflen); 
     385} 
     386 
     387static void add_acl_entry(sc_file_t *file, int op, u8 byte) 
     388{ 
     389        unsigned int method, key_ref = SC_AC_KEY_REF_NONE; 
     390 
     391        switch (byte) { 
     392        case 0x00: 
     393                method = SC_AC_NONE; 
     394                break; 
     395        case 0xFF: 
     396        case 0x66: 
     397                method = SC_AC_NEVER; 
     398                break; 
     399        default: 
     400                if (byte > 0x1F) { 
     401                        method = SC_AC_UNKNOWN; 
     402                } else { 
     403                        method = SC_AC_CHV; 
     404                        key_ref = byte; 
     405                } 
     406                break; 
     407        } 
     408        sc_file_add_acl_entry(file, op, method, key_ref); 
     409} 
     410 
     411static const int df_acl[9] = { 
     412        -1,                     /* LCYCLE (life cycle change) */ 
     413        SC_AC_OP_UPDATE,        /* UPDATE Objects */ 
     414        SC_AC_OP_WRITE,                 /* APPEND Objects */ 
     415 
     416        SC_AC_OP_INVALIDATE,    /* DF */ 
     417        SC_AC_OP_REHABILITATE,  /* DF */ 
     418        SC_AC_OP_DELETE,        /* DF */ 
     419 
     420        SC_AC_OP_WRITE,                 /* ADMIN DF */ 
     421        SC_AC_OP_CREATE,        /* Files */ 
     422        -1                      /* Reserved */ 
     423}; 
     424static const int ef_acl[9] = { 
     425        SC_AC_OP_READ,          /* Data */ 
     426        SC_AC_OP_UPDATE,        /* Data (write file content) */ 
     427        SC_AC_OP_WRITE,         /* */ 
     428 
     429        SC_AC_OP_INVALIDATE,    /* EF */ 
     430        SC_AC_OP_REHABILITATE,  /* EF */ 
     431        SC_AC_OP_ERASE,         /* (delete) EF */ 
     432 
     433        /* XXX: ADMIN should be an ACL type of its own, or mapped 
     434         * to erase */ 
     435        SC_AC_OP_ERASE,                 /* ADMIN EF (modify meta information?) */ 
     436        -1,                     /* INC (-> cylic fixed files) */ 
     437        -1                      /* DEC */ 
     438}; 
     439 
     440static void parse_sec_attr(sc_file_t *file, const u8 *buf, size_t len) 
     441{ 
     442        size_t i; 
     443        const int *idx; 
     444 
     445        idx = (file->type == SC_FILE_TYPE_DF) ?  df_acl : ef_acl; 
     446 
     447        /* acl defaults to 0xFF if unspecified */ 
     448        for (i = 0; i < 9; i++) 
     449                if (idx[i] != -1) 
     450                        add_acl_entry(file, idx[i], (u8)((i < len) ? buf[i] : 0xFF)); 
     451} 
     452 
     453static int itacns_select_file(sc_card_t *card, 
     454                              const sc_path_t *in_path, 
     455                              sc_file_t **file) 
     456{ 
     457        int r; 
     458 
     459        SC_FUNC_CALLED(card->ctx, SC_LOG_DEBUG_VERBOSE); 
     460        r = default_ops->select_file(card, in_path, file); 
     461        if (r >= 0 && file) 
     462                parse_sec_attr((*file), (*file)->sec_attr, (*file)->sec_attr_len); 
     463        SC_FUNC_RETURN(card->ctx, SC_LOG_DEBUG_NORMAL, r); 
     464} 
     465 
     466 
     467static struct sc_card_driver * sc_get_driver(void) 
     468{ 
     469        if (!default_ops) 
     470                default_ops = sc_get_iso7816_driver()->ops; 
     471        itacns_ops = *default_ops; 
     472        itacns_ops.match_card = itacns_match_card; 
     473        itacns_ops.init = itacns_init; 
     474        itacns_ops.finish = itacns_finish; 
     475        itacns_ops.set_security_env = itacns_set_security_env; 
     476        itacns_ops.restore_security_env = itacns_restore_security_env; 
     477        itacns_ops.pin_cmd = itacns_pin_cmd; 
     478        itacns_ops.read_binary = itacns_read_binary; 
     479        itacns_ops.list_files = itacns_list_files; 
     480        itacns_ops.select_file = itacns_select_file; 
     481        return &itacns_drv; 
     482} 
     483 
     484struct sc_card_driver * sc_get_itacns_driver(void) 
     485{ 
     486        return sc_get_driver(); 
     487} 
  • src/libopensc/cards.h

    diff --git a/src/libopensc/cards.h b/src/libopensc/cards.h
    index b5d8bda..843a762 100644
    a b enum { 
    167167        /* Generic JavaCards without supported applet */ 
    168168        SC_CARD_TYPE_JAVACARD_BASE = 23000, 
    169169        SC_CARD_TYPE_JAVACARD, 
     170 
     171        /* Italian CNS cards */ 
     172        SC_CARD_TYPE_ITACNS_BASE = 24000, 
     173        SC_CARD_TYPE_ITACNS_GENERIC, 
     174        SC_CARD_TYPE_ITACNS_CNS, 
     175        SC_CARD_TYPE_ITACNS_CIE_V2, 
     176        SC_CARD_TYPE_ITACNS_CIE_V1, 
     177 
    170178}; 
    171179 
    172180extern sc_card_driver_t *sc_get_default_driver(void); 
    extern sc_card_driver_t *sc_get_westcos_driver(void); 
    198206extern sc_card_driver_t *sc_get_myeid_driver(void); 
    199207extern sc_card_driver_t *sc_get_ias_driver(void); 
    200208extern sc_card_driver_t *sc_get_javacard_driver(void); 
     209extern sc_card_driver_t *sc_get_itacns_driver(void); 
    201210 
    202211#ifdef __cplusplus 
    203212} 
  • src/libopensc/ctx.c

    diff --git a/src/libopensc/ctx.c b/src/libopensc/ctx.c
    index 4158d87..becd065 100644
    a b static const struct _sc_driver_entry internal_card_drivers[] = { 
    9393#endif 
    9494        /* javacard without supported applet - last before default */ 
    9595        { "javacard",   (void *(*)(void)) sc_get_javacard_driver }, 
    96  
     96        { "itacns",     (void *(*)(void)) sc_get_itacns_driver }, 
    9797        /* The default driver should be last, as it handles all the 
    9898         * unrecognized cards. */ 
    9999        { "default",    (void *(*)(void)) sc_get_default_driver }, 
  • src/libopensc/iso7816.c

    diff --git a/src/libopensc/iso7816.c b/src/libopensc/iso7816.c
    index 9d826ad..52d10af 100644
    a b static int iso7816_get_challenge(sc_card_t *card, u8 *rnd, size_t len) 
    520520        return 0; 
    521521} 
    522522 
     523/* This belongs to ETSI TS 101 206-3, not to ISO 7816. */ 
     524static int iso7816_give_random(sc_card_t *card, u8 *rnd, size_t len) 
     525{ 
     526        int r; 
     527        sc_apdu_t apdu; 
     528 
     529        sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 
     530                       0x86, 0x00, 0x00); 
     531        apdu.cla = 0x80; 
     532        apdu.data = rnd; 
     533        apdu.lc = apdu.datalen = len; 
     534 
     535        r = sc_transmit_apdu(card, &apdu); 
     536        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); 
     537        return sc_check_sw(card, apdu.sw1, apdu.sw2); 
     538} 
     539 
    523540static int iso7816_construct_fci(sc_card_t *card, const sc_file_t *file, 
    524541        u8 *out, size_t *outlen) 
    525542{ 
    static struct sc_card_operations iso_ops = { 
    10011018        iso7816_select_file, 
    10021019        iso7816_get_response, 
    10031020        iso7816_get_challenge, 
     1021        iso7816_give_random, 
    10041022        NULL,                   /* verify */ 
    10051023        NULL,                   /* logout */ 
    10061024        iso7816_restore_security_env, 
  • new file src/libopensc/itacns.h

    diff --git a/src/libopensc/itacns.h b/src/libopensc/itacns.h
    new file mode 100644
    index 0000000..742627b
    - +  
     1#ifndef _OPENSC_ITACNS_H 
     2#define _OPENSC_ITACNS_H 
     3 
     4typedef struct { 
     5        u8 ic_manufacturer_code; 
     6        u8 mask_manufacturer_code; 
     7        u8 os_version_h; 
     8        u8 os_version_l; 
     9        u8 cns_version; 
     10} itacns_drv_data_t; 
     11 
     12#define ITACNS_MASKMAN_SIEMENS          0x08 
     13#define ITACNS_MASKMAN_STINCARD         0x09 
     14 
     15#endif /* _OPENSC_ITACNS_H */ 
  • src/libopensc/opensc.h

    diff --git a/src/libopensc/opensc.h b/src/libopensc/opensc.h
    index 7d95488..796cef0 100644
    a b struct sc_card_operations { 
    441441                           struct sc_file **file_out); 
    442442        int (*get_response)(struct sc_card *card, size_t *count, u8 *buf); 
    443443        int (*get_challenge)(struct sc_card *card, u8 * buf, size_t count); 
     444        /* This belongs to ETSI TS 101 206-3, not to ISO 7816. */ 
     445        int (*give_random)(struct sc_card *card, u8 * buf, size_t count); 
    444446 
    445447        /* 
    446448         * ISO 7816-8 functions 
  • new file src/libopensc/pkcs15-itacns.c

    diff --git a/src/libopensc/pkcs15-itacns.c b/src/libopensc/pkcs15-itacns.c
    new file mode 100644
    index 0000000..83fd6b0
    - +  
     1/* 
     2 * PKCS15 emulation layer for Italian CNS. 
     3 * 
     4 * Copyright (C) 2008, Emanuele Pucciarelli <ep@acm.org> 
     5 * Many snippets have been taken out from other PKCS15 emulation layer 
     6 * modules in this directory; their copyright is their authors'. 
     7 * 
     8 * This library is free software; you can redistribute it and/or 
     9 * modify it under the terms of the GNU Lesser General Public 
     10 * License as published by the Free Software Foundation; either 
     11 * version 2.1 of the License, or (at your option) any later version. 
     12 * 
     13 * This library is distributed in the hope that it will be useful, 
     14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
     15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
     16 * Lesser General Public License for more details. 
     17 * 
     18 * You should have received a copy of the GNU Lesser General Public 
     19 * License along with this library; if not, write to the Free Software 
     20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
     21 */ 
     22 
     23/* 
     24 * Specifications for the development of this driver come from: 
     25 * http://www.servizidemografici.interno.it/sitoCNSD/documentazioneRicerca.do?metodo=contenutoDocumento&servizio=documentazione&ID_DOCUMENTO=1043 
     26 */ 
     27 
     28 
     29#ifdef HAVE_CONFIG_H 
     30#include <config.h> 
     31#endif 
     32 
     33#include "pkcs15.h" 
     34#include "log.h" 
     35#include "cards.h" 
     36#include "itacns.h" 
     37#include <stdlib.h> 
     38#include <string.h> 
     39#include <stdio.h> 
     40#include "common/compat_strlcpy.h" 
     41 
     42#ifdef ENABLE_OPENSSL 
     43#include <openssl/x509v3.h> 
     44#endif 
     45 
     46int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *, 
     47                                    sc_pkcs15emu_opt_t *); 
     48 
     49static const char path_serial[] = "10001003"; 
     50static const char path_personal_data[] = "11001102"; 
     51 
     52/* Manufacturers */ 
     53 
     54char * itacns_mask_manufacturers[] = { 
     55        "Unknown", 
     56        "Kaitech", 
     57        "Gemplus", 
     58        "Ghirlanda", 
     59        "Giesecke & Devrient", 
     60        "Oberthur Card Systems", 
     61        "Orga", 
     62        "Axalto", 
     63        "Siemens", 
     64        "STIncard", 
     65        "GEP", 
     66        "EPS Corp", 
     67        "Athena" 
     68}; 
     69 
     70char * iso7816_ic_manufacturers[] = { 
     71        "Unknown", 
     72        "Motorola", 
     73        "STMicroelectronics", 
     74        "Hitachi", 
     75        "Philips Semiconductors", 
     76        "Siemens", 
     77        "Cylinc", 
     78        "Texas Instruments", 
     79        "Fujitsu", 
     80        "Matsushita", 
     81        "NEC", 
     82        "Oki", 
     83        "Toshiba", 
     84        "Mitsubishi", 
     85        "Samsung", 
     86        "Hyundai", 
     87        "LG" 
     88}; 
     89 
     90/* Data files */ 
     91 
     92static const struct { 
     93        char *label; 
     94        char *path; 
     95        int cie_only; 
     96} itacns_data_files[] = { 
     97        { "EF_DatiProcessore", "3F0010001002", 0 }, 
     98        { "EF_IDCarta", "3F0010001003", 0 }, 
     99        { "EF_DatiSistema", "3F0010001004", 1 }, 
     100        { "EF_DatiPersonali", "3F0011001102", 0 }, 
     101        { "EF_DatiPersonali_Annotazioni", "3F0011001103", 1 }, 
     102        { "EF_Impronte", "3F0011001104", 1 }, 
     103        { "EF_Foto", "3F0011001104", 1 }, 
     104        { "EF_DatiPersonaliAggiuntivi", "3F0012001201", 0 }, 
     105        { "EF_MemoriaResidua", "3F0012001202", 0 }, 
     106        { "EF_ServiziInstallati", "3F0012001203", 0 }, 
     107        { "EF_INST_FILE", "3F0012004142", 0 }, 
     108        { "EF_CardStatus", "3F003F02", 0 }, 
     109        { "EF_GDO", "3F002F02", 0 }, 
     110        { "EF_RootInstFile", "3F000405", 0 } 
     111}; 
     112 
     113 
     114/* 
     115 * Utility functions 
     116 */ 
     117 
     118static void set_string(char **strp, const char *value) 
     119{ 
     120        if (*strp) 
     121                free(*strp); 
     122        *strp = value ? strdup(value) : NULL; 
     123} 
     124 
     125static int loadFile(const sc_pkcs15_card_t *p15card, const sc_path_t *path, 
     126        u8 *buf, const size_t buflen) 
     127{ 
     128        SC_FUNC_CALLED(p15card->card->ctx, 1); 
     129 
     130        int sc_res; 
     131        sc_res = sc_select_file(p15card->card, path, NULL); 
     132        if(sc_res != SC_SUCCESS) 
     133                return sc_res; 
     134 
     135        sc_res = sc_read_binary(p15card->card, 0, buf, buflen, 0); 
     136        return sc_res; 
     137} 
     138 
     139/* 
     140 * The following functions add objects to the card emulator. 
     141 */ 
     142 
     143static int itacns_add_cert(sc_pkcs15_card_t *p15card, 
     144        int type, int authority, const sc_path_t *path, 
     145        const sc_pkcs15_id_t *id, const char *label, int obj_flags, 
     146        int *ext_info_ok, int *key_usage, int *x_key_usage) 
     147{ 
     148        SC_FUNC_CALLED(p15card->card->ctx, 1); 
     149        int r; 
     150        *ext_info_ok = 0; 
     151 
     152        /* const char *label = "Certificate"; */ 
     153        sc_pkcs15_cert_info_t info; 
     154        sc_pkcs15_object_t    obj; 
     155 
     156        memset(&info, 0, sizeof(info)); 
     157        memset(&obj,  0, sizeof(obj)); 
     158 
     159        info.id                = *id; 
     160        info.authority         = authority; 
     161        if (path) 
     162                info.path = *path; 
     163 
     164        strlcpy(obj.label, label, sizeof(obj.label)); 
     165        obj.flags = obj_flags; 
     166 
     167        r = sc_pkcs15emu_add_x509_cert(p15card, &obj, &info); 
     168        SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add X.509 certificate"); 
     169 
     170        /* If we have OpenSSL, read keyUsage */ 
     171#ifdef ENABLE_OPENSSL 
     172 
     173        X509 *x509; 
     174        sc_pkcs15_cert_t *cert; 
     175 
     176        r = sc_pkcs15_read_certificate(p15card, &info, &cert); 
     177        SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not read X.509 certificate"); 
     178 
     179        const u8 *throwaway = cert->data; 
     180        x509 = d2i_X509(NULL, &throwaway, cert->data_len); 
     181        sc_pkcs15_free_certificate(cert); 
     182        if (!x509) return SC_SUCCESS; 
     183        X509_check_purpose(x509, -1, 0); 
     184        if(x509->ex_flags & EXFLAG_KUSAGE) { 
     185                *ext_info_ok = 1; 
     186                *key_usage = x509->ex_kusage; 
     187                *x_key_usage = x509->ex_xkusage; 
     188        } 
     189        OPENSSL_free(x509); 
     190 
     191        return SC_SUCCESS; 
     192 
     193#else /* ENABLE_OPENSSL */ 
     194 
     195        return SC_SUCCESS; 
     196 
     197#endif /* ENABLE_OPENSSL */ 
     198 
     199} 
     200 
     201static int itacns_add_pubkey(sc_pkcs15_card_t *p15card, 
     202         const sc_path_t *path, const sc_pkcs15_id_t *id, const char *label, 
     203        int usage, int ref, int obj_flags, int *modulus_len_out) 
     204{ 
     205        SC_FUNC_CALLED(p15card->card->ctx, 1); 
     206 
     207        int r; 
     208        sc_pkcs15_pubkey_info_t info; 
     209        sc_pkcs15_object_t obj; 
     210 
     211        memset(&info, 0, sizeof(info)); 
     212        memset(&obj,  0, sizeof(obj)); 
     213 
     214        info.id                = *id; 
     215        if (path) 
     216                info.path = *path; 
     217        info.usage = usage; 
     218        info.key_reference = ref; 
     219        strlcpy(obj.label, label, sizeof(obj.label)); 
     220        obj.flags = obj_flags; 
     221 
     222        /* This is hard-coded, unless weird versions of the CNS turn up sometime. */ 
     223        info.modulus_length = 1024; 
     224 
     225        *modulus_len_out = info.modulus_length; 
     226        r = sc_pkcs15emu_add_rsa_pubkey(p15card, &obj, &info); 
     227        SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add pub key"); 
     228        return r; 
     229} 
     230 
     231static int itacns_add_prkey(sc_pkcs15_card_t *p15card, 
     232                const sc_pkcs15_id_t *id, 
     233                const char *label, 
     234                int type, unsigned int modulus_length, int usage, 
     235                                int algo_flags, const sc_path_t *path, int ref, 
     236                const sc_pkcs15_id_t *auth_id, int obj_flags) 
     237{ 
     238        SC_FUNC_CALLED(p15card->card->ctx, 1); 
     239 
     240    sc_pkcs15_prkey_info_t info; 
     241        sc_pkcs15_object_t     obj; 
     242 
     243        memset(&info, 0, sizeof(info)); 
     244        memset(&obj,  0, sizeof(obj)); 
     245 
     246        info.id                = *id; 
     247        info.modulus_length    = modulus_length; 
     248        info.usage             = usage; 
     249        info.native            = 1; 
     250        info.key_reference     = ref; 
     251        info.access_flags               = 
     252                        SC_PKCS15_PRKEY_ACCESS_SENSITIVE 
     253                        | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE 
     254                        | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE 
     255                        | SC_PKCS15_PRKEY_ACCESS_LOCAL; 
     256 
     257        if (path) 
     258                info.path = *path; 
     259 
     260        obj.flags = obj_flags; 
     261        strlcpy(obj.label, label, sizeof(obj.label)); 
     262        if (auth_id != NULL) 
     263                obj.auth_id = *auth_id; 
     264 
     265        return sc_pkcs15emu_add_rsa_prkey(p15card, &obj, &info); 
     266} 
     267 
     268static int itacns_add_pin(sc_pkcs15_card_t *p15card, 
     269        char *label, 
     270        int id, 
     271        int auth_id, 
     272        int reference, 
     273        sc_path_t *path, 
     274        int flags) 
     275{ 
     276        SC_FUNC_CALLED(p15card->card->ctx, 1); 
     277 
     278        struct sc_pkcs15_pin_info pin_info; 
     279        struct sc_pkcs15_object pin_obj; 
     280 
     281        memset(&pin_info, 0, sizeof(pin_info)); 
     282        pin_info.auth_id.len = 1; 
     283        pin_info.auth_id.value[0] = id; 
     284        pin_info.reference = reference; 
     285        pin_info.flags = flags; 
     286        pin_info.type = SC_PKCS15_PIN_TYPE_ASCII_NUMERIC; 
     287        pin_info.min_length = 5; 
     288        pin_info.stored_length = 8; 
     289        pin_info.max_length = 8; 
     290        pin_info.pad_char = 0xff; 
     291        if(path) 
     292        pin_info.path = *path; 
     293 
     294        memset(&pin_obj, 0, sizeof(pin_obj)); 
     295        strlcpy(pin_obj.label, label, sizeof(pin_obj.label)); 
     296        pin_obj.flags = SC_PKCS15_CO_FLAG_PRIVATE | (auth_id ? SC_PKCS15_CO_FLAG_MODIFIABLE : 0); 
     297        if (auth_id) { 
     298                pin_obj.auth_id.len = 1; 
     299                pin_obj.auth_id.value[0] = auth_id; 
     300        } else 
     301                pin_obj.auth_id.len = 0; 
     302 
     303        return sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info); 
     304} 
     305 
     306static int itacns_add_data_files(sc_pkcs15_card_t *p15card) 
     307{ 
     308        const size_t list_size = sizeof(itacns_data_files)/sizeof(itacns_data_files[0]); 
     309        int i; 
     310        int r; 
     311        for(i=0; i < list_size; i++) { 
     312                if(itacns_data_files[i].cie_only && 
     313                        p15card->card->type != SC_CARD_TYPE_ITACNS_CIE_V2) 
     314                        continue; 
     315 
     316                sc_path_t path; 
     317 
     318                sc_format_path(itacns_data_files[i].path, &path); 
     319                sc_pkcs15_data_info_t data; 
     320                sc_pkcs15_object_t    obj; 
     321 
     322                memset(&data, 0, sizeof(data)); 
     323                memset(&obj, 0, sizeof(obj)); 
     324                strlcpy(data.app_label, itacns_data_files[i].label, 
     325                        sizeof(data.app_label)); 
     326                strlcpy(obj.label, itacns_data_files[i].label, 
     327                        sizeof(obj.label)); 
     328                data.path = path; 
     329                r = sc_pkcs15emu_add_data_object(p15card, &obj, &data); 
     330        } 
     331        return SC_SUCCESS; 
     332} 
     333 
     334static int itacns_add_keyset(sc_pkcs15_card_t *p15card, 
     335        const char *label, int sec_env, sc_pkcs15_id_t *cert_id, 
     336        const char *pubkey_path, const char *prkey_path, 
     337        unsigned int pubkey_usage_flags, unsigned int prkey_usage_flags, 
     338        u8 pin_ref, int needs_enc) 
     339{ 
     340        int r; 
     341        sc_path_t path; 
     342 
     343        /* This is hard-coded, for the time being. */ 
     344        int modulus_length = 1024; 
     345 
     346        /* Access flags; these depend on whether the private keys use PSO_ENC 
     347           or PSO_CDS for signing. */ 
     348 
     349        const int enc_algo_flags = SC_ALGORITHM_NEED_USAGE 
     350                        | SC_ALGORITHM_RSA_RAW 
     351                        | SC_ALGORITHM_RSA_HASH_NONE; 
     352        const int cds_algo_flags = SC_ALGORITHM_NEED_USAGE 
     353                | SC_ALGORITHM_RSA_PAD_PKCS1 
     354                | SC_ALGORITHM_RSA_HASH_NONE; 
     355 
     356        /* Public key; not really needed */ 
     357        /* FIXME: set usage according to the certificate. */ 
     358        if (pubkey_path) { 
     359                sc_format_path(pubkey_path, &path); 
     360                r = itacns_add_pubkey(p15card, &path, cert_id, label, 
     361                        pubkey_usage_flags, sec_env, 0, &modulus_length); 
     362                SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add public key"); 
     363        } 
     364 
     365        /* FIXME: usage should be inferred from the X.509 certificate, and not 
     366                from whether the key needs Secure Messaging. */ 
     367        sc_path_t *private_path = NULL; 
     368        if (prkey_path) { 
     369                sc_format_path(prkey_path, &path); 
     370                private_path = &path; 
     371        } 
     372        r = itacns_add_prkey(p15card, cert_id, label, SC_PKCS15_TYPE_PRKEY_RSA, 
     373                modulus_length, 
     374                prkey_usage_flags, 
     375                (needs_enc ? enc_algo_flags : cds_algo_flags), 
     376                private_path, sec_env, cert_id, SC_PKCS15_CO_FLAG_PRIVATE); 
     377        SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add private key"); 
     378 
     379        /* PIN and PUK */ 
     380        char pinlabel[16]; 
     381        strncpy(pinlabel, "PIN ", sizeof(pinlabel)); 
     382        strncat(pinlabel, label, sizeof(pinlabel)); 
     383        /* We are making up ID 0x90+ to link the PIN and the PUK. */ 
     384        int fake_puk_authid = 0x90 + pin_ref; 
     385        int pin_flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE 
     386                | SC_PKCS15_PIN_FLAG_INITIALIZED; 
     387 
     388        r = itacns_add_pin(p15card, pinlabel, sec_env, fake_puk_authid, pin_ref, 
     389            private_path, pin_flags); 
     390        SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add PIN"); 
     391 
     392        strncpy(pinlabel, "PUK ", sizeof(pinlabel)); 
     393        strncat(pinlabel, label, sizeof(pinlabel)); 
     394        /* 
     395         * Looking at pkcs15-tcos.c and pkcs15-framework.c, it seems that the 
     396         * right thing to do here is to define a PUK as a SO PIN. Can anybody 
     397         * comment on this? 
     398         */ 
     399        pin_flags |= SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN 
     400        | SC_PKCS15_PIN_FLAG_UNBLOCK_DISABLED; 
     401        r = itacns_add_pin(p15card, pinlabel, fake_puk_authid, 0, pin_ref+1, 
     402            private_path, pin_flags); 
     403        SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add PUK"); 
     404 
     405        return 0; 
     406} 
     407 
     408/* 
     409 * itacns_check_and_add_keyset() checks for the existence and correctness 
     410 * of an X.509 certificate. If it is all right, it adds the related keys; 
     411 * otherwise it aborts. 
     412 */ 
     413 
     414static int itacns_check_and_add_keyset(sc_pkcs15_card_t *p15card, 
     415        const char *label, int sec_env, size_t cert_offset, 
     416        const char *cert_path, const char *pubkey_path, const char *prkey_path, 
     417        u8 pin_ref, int needs_enc, int *found_certificates) 
     418{ 
     419        int r; 
     420        sc_path_t path; 
     421        sc_pkcs15_id_t cert_id; 
     422 
     423        cert_id.len = 1; 
     424        cert_id.value[0] = sec_env; 
     425        *found_certificates = 0; 
     426 
     427        /* Usage flags */ 
     428        const int auth_pubkey_usage_flags = SC_PKCS15_PRKEY_USAGE_ENCRYPT 
     429                | SC_PKCS15_PRKEY_USAGE_DECRYPT 
     430                | SC_PKCS15_PRKEY_USAGE_WRAP 
     431                | SC_PKCS15_PRKEY_USAGE_VERIFY; 
     432        const int auth_prkey_usage_flags = SC_PKCS15_PRKEY_USAGE_DECRYPT 
     433                | SC_PKCS15_PRKEY_USAGE_UNWRAP 
     434                | SC_PKCS15_PRKEY_USAGE_SIGN; 
     435        const int sig_pubkey_usage_flags = SC_PKCS15_PRKEY_USAGE_VERIFY; 
     436        const int sig_prkey_usage_flags = SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; 
     437 
     438        /* Certificate */ 
     439        if (!cert_path) { 
     440                sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL,  
     441                        "We cannot use keys without a matching certificate"); 
     442                return SC_ERROR_NOT_SUPPORTED; 
     443        } 
     444 
     445        sc_format_path(cert_path, &path); 
     446        r = sc_select_file(p15card->card, &path, NULL); 
     447        if (r == SC_ERROR_FILE_NOT_FOUND) 
     448                return 0; 
     449        if (r != SC_SUCCESS) { 
     450                sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, 
     451                        "Could not find certificate for %s", label); 
     452                return r; 
     453        } 
     454 
     455        /* 
     456         * Infocamere 1204 (and others?) store a more complex structure. We 
     457         * are going to read the first bytes to guess its length, and invoke 
     458         * itacns_add_cert so that it only reads the certificate. 
     459         */ 
     460        if (cert_offset) { 
     461                u8 certlen[3]; 
     462                r = loadFile(p15card, &path, certlen, sizeof(certlen)); 
     463                SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not read certificate file"); 
     464                path.index = cert_offset; 
     465                path.count = (certlen[1] << 8) + certlen[2]; 
     466                /* If those bytes are 00, then we are probably dealign with an 
     467                 * empty file. */ 
     468                if (path.count == 0) 
     469                        return 0; 
     470        } 
     471        int ext_info_ok; 
     472        int ku, xku; 
     473        r = itacns_add_cert(p15card, SC_PKCS15_TYPE_CERT_X509, 0, 
     474                &path, &cert_id, label, 0, &ext_info_ok, &ku, &xku); 
     475        if (r == SC_ERROR_INVALID_ASN1_OBJECT) 
     476                return 0; 
     477        SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add certificate"); 
     478        (*found_certificates)++; 
     479 
     480        /* Set usage flags */ 
     481        int pubkey_usage_flags = 0, prkey_usage_flags = 0; 
     482        if(ext_info_ok) { 
     483#ifdef ENABLE_OPENSSL 
     484                if (ku & KU_DIGITAL_SIGNATURE) { 
     485                        pubkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_VERIFY; 
     486                        prkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_SIGN; 
     487                } 
     488                if (ku & KU_NON_REPUDIATION) { 
     489                        pubkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_VERIFY; 
     490                        prkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_NONREPUDIATION; 
     491                } 
     492                if (ku & KU_KEY_ENCIPHERMENT || ku & KU_KEY_AGREEMENT 
     493                        || xku & XKU_SSL_CLIENT) { 
     494                        pubkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_WRAP; 
     495                        prkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_UNWRAP; 
     496                } 
     497                if (ku & KU_DATA_ENCIPHERMENT || xku & XKU_SMIME) { 
     498                        pubkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_ENCRYPT; 
     499                        prkey_usage_flags |= SC_PKCS15_PRKEY_USAGE_DECRYPT; 
     500                } 
     501#else /* ENABLE_OPENSSL */ 
     502                sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Extended certificate " 
     503                        "info retrieved without OpenSSL. How is this possible?"); 
     504                return SC_ERROR_INTERNAL; 
     505#endif /* ENABLE_OPENSSL */ 
     506        } else { 
     507                /* Certificate info not retrieved; fall back onto defaults */ 
     508                pubkey_usage_flags = SC_PKCS15_PRKEY_USAGE_VERIFY | SC_PKCS15_PRKEY_USAGE_WRAP; 
     509                prkey_usage_flags = SC_PKCS15_PRKEY_USAGE_SIGN | SC_PKCS15_PRKEY_USAGE_UNWRAP; 
     510        } 
     511 
     512        r = itacns_add_keyset(p15card, label, sec_env, &cert_id, 
     513                pubkey_path, prkey_path, pubkey_usage_flags, prkey_usage_flags, 
     514                pin_ref, needs_enc); 
     515        SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add keys for" 
     516                " this certificate"); 
     517 
     518        return r; 
     519} 
     520 
     521/* Initialization. */ 
     522 
     523static int itacns_init(sc_pkcs15_card_t *p15card) 
     524{ 
     525        SC_FUNC_CALLED(p15card->card->ctx, 1); 
     526 
     527        int r; 
     528        sc_path_t path; 
     529        int certificate_count = 0; 
     530        int found_certs; 
     531 
     532        set_string(&p15card->label, p15card->card->name); 
     533        if(p15card->card->drv_data) { 
     534                int mask_code, ic_code; 
     535                char buffer[256]; 
     536                itacns_drv_data_t *data = (itacns_drv_data_t*) p15card->card->drv_data; 
     537                mask_code = data->mask_manufacturer_code; 
     538                if (mask_code >= sizeof(itacns_mask_manufacturers)) 
     539                        mask_code = 0; 
     540                ic_code = data->ic_manufacturer_code; 
     541                if (ic_code >= sizeof(iso7816_ic_manufacturers)) 
     542                        ic_code = 0; 
     543                snprintf(buffer, sizeof(buffer), "IC: %s; mask: %s", 
     544                        iso7816_ic_manufacturers[ic_code], 
     545                        itacns_mask_manufacturers[mask_code]); 
     546                set_string(&p15card->manufacturer_id, buffer); 
     547                p15card->version = (data->os_version_h << 8 | data->os_version_l); 
     548        } 
     549 
     550        /* Read and set serial */ 
     551        u8 serial[17]; 
     552        { 
     553                int bytes; 
     554                sc_format_path(path_serial, &path); 
     555                bytes = loadFile(p15card, &path, serial, 16); 
     556                if (bytes < 0) return bytes; 
     557                if (bytes > 16) return -1; 
     558                serial[bytes] = '\0'; 
     559                set_string(&p15card->serial_number, (char*)serial); 
     560        } 
     561 
     562        /* Is the card a CIE v1? */ 
     563        int card_is_cie_v1 = (p15card->card->type == SC_CARD_TYPE_ITACNS_CIE_V1) 
     564                || (p15card->card->type == SC_CARD_TYPE_CARDOS_CIE_V1); 
     565        int cns0_secenv = (card_is_cie_v1 ? 0x31 : 0x01); 
     566 
     567        /* If it's a Siemens CIE v1 card, set algo flags accordingly. */ 
     568        if (card_is_cie_v1) { 
     569                int i; 
     570                for (i = 0; i < p15card->card->algorithm_count; i++) { 
     571                        sc_algorithm_info_t *info = &p15card->card->algorithms[i]; 
     572 
     573                        if (info->algorithm != SC_ALGORITHM_RSA) 
     574                                continue; 
     575                        info->flags &= ~(SC_ALGORITHM_RSA_RAW 
     576                                | SC_ALGORITHM_RSA_HASH_NONE); 
     577                        info->flags |= (SC_ALGORITHM_RSA_PAD_PKCS1 
     578                                | SC_ALGORITHM_RSA_HASHES); 
     579                } 
     580        } 
     581 
     582        /*** Certificate and keys. ***/ 
     583        /* Standard CNS */ 
     584        r = itacns_check_and_add_keyset(p15card, "CNS0", cns0_secenv, 
     585                0, "3F0011001101", "3F003F01", NULL, 
     586                0x10, !card_is_cie_v1, &found_certs); 
     587        SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add CNS0"); 
     588        certificate_count += found_certs; 
     589 
     590        /* Infocamere 1204 */ 
     591        r = itacns_check_and_add_keyset(p15card, "CNS01", 0x21, 
     592                5, "3F002FFF8228", NULL, "3F002FFF0000", 
     593                0x10, 1, &found_certs); 
     594        SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add CNS01"); 
     595        certificate_count += found_certs; 
     596 
     597        /* Digital signature */ 
     598        r = itacns_check_and_add_keyset(p15card, "CNS1", 0x10, 
     599                0, "3F0014009010", "3F00140081108010", "3F0014008110", 
     600                0x1a, 0, &found_certs); 
     601        SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add CNS1"); 
     602        certificate_count += found_certs; 
     603 
     604        /* Did we find anything? */ 
     605        if (certificate_count == 0) 
     606                sc_debug(p15card->card->ctx, SC_LOG_DEBUG_VERBOSE, "Warning: no certificates found!"); 
     607 
     608        /* Data files */ 
     609        r = itacns_add_data_files(p15card); 
     610        SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not add data files"); 
     611 
     612        /* Back to Master File */ 
     613        sc_format_path("3F00", &path); 
     614        r = sc_select_file(p15card->card, &path, NULL); 
     615        SC_TEST_RET(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, r, "Could not select master file again"); 
     616 
     617        return r; 
     618} 
     619 
     620int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *p15card, 
     621                                    sc_pkcs15emu_opt_t *opts) 
     622{ 
     623        sc_card_t *card = p15card->card; 
     624        SC_FUNC_CALLED(card->ctx, 1); 
     625 
     626        /* Check card */ 
     627        if (!(opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) { 
     628                if (! ( 
     629                                (card->type > SC_CARD_TYPE_ITACNS_BASE && 
     630                                card->type < SC_CARD_TYPE_ITACNS_BASE + 1000) 
     631                        || card->type == SC_CARD_TYPE_CARDOS_CIE_V1) 
     632                        ) 
     633                        return SC_ERROR_WRONG_CARD; 
     634        } 
     635 
     636        /* Init card */ 
     637        return itacns_init(p15card); 
     638} 
  • src/libopensc/pkcs15-syn.c

    diff --git a/src/libopensc/pkcs15-syn.c b/src/libopensc/pkcs15-syn.c
    index d107cba..81bf45e 100644
    a b extern int sc_pkcs15emu_pteid_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); 
    6363 
    6464extern int sc_pkcs15emu_oberthur_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); 
    6565 
     66extern int sc_pkcs15emu_itacns_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); 
     67 
    6668static struct { 
    6769        const char *            name; 
    6870        int                     (*handler)(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *); 
    static struct { 
    7375        { "starcert",   sc_pkcs15emu_starcert_init_ex   }, 
    7476        { "tcos",       sc_pkcs15emu_tcos_init_ex       }, 
    7577        { "esteid",     sc_pkcs15emu_esteid_init_ex     }, 
     78        { "itacns",             sc_pkcs15emu_itacns_init_ex             }, 
    7679        { "postecert",  sc_pkcs15emu_postecert_init_ex  }, 
    7780        { "PIV-II",     sc_pkcs15emu_piv_init_ex        }, 
    7881        { "gemsafeGPK", sc_pkcs15emu_gemsafeGPK_init_ex },