Ticket #177: itacns2.patch

File itacns2.patch, 42.9 KB (added by martin, 19 months ago)
  • etc/opensc.conf.in

    commit c2609d3d934ffa4057f4fb310b61872702340610
    Author: Martin Paljak <martin@paljak.pri.ee>
    Date:   Wed Jul 21 14:38:25 2010 +0300
    
        Trac #177: Improved patch
    
    diff --git a/etc/opensc.conf.in b/etc/opensc.conf.in
    index d9771f9..6b710ce 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..d144065
    - +  
     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/site/_files/CNS%20Functional%20Specification%201.1.3_06042006_.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/* Developer guide talks about using small payloads? */ 
     37#define ITACNS_MAX_PAYLOAD              0x50 
     38 
     39#define MAX_LE 240 
     40 
     41static const struct sc_card_operations *default_ops = NULL; 
     42 
     43static struct sc_card_operations itacns_ops; 
     44static struct sc_card_driver itacns_drv = { 
     45        "Carta Nazionale dei Servizi", 
     46        "itacns", 
     47        &itacns_ops, 
     48        NULL, 0, NULL 
     49}; 
     50 
     51/* 
     52 * Card matching 
     53 */ 
     54 
     55 
     56/* List of ATR's for "hard" matching. */ 
     57static struct sc_atr_table itacns_atrs[] = { 
     58        { "3b:f4:18:00:ff:81:31:80:55:00:31:80:00:c7", NULL, NULL, SC_CARD_TYPE_ITACNS_CIE_V1, 0, NULL}, 
     59        { NULL, NULL, NULL, 0, 0, NULL} 
     60}; 
     61 
     62/* Output debug info */ 
     63#define matchdebug(idx, c) do { \ 
     64                sc_debug(ctx, SC_LOG_DEBUG_VERBOSE, "Matching %x against atr[%d] == %x", c, idx, atr[idx]); \ 
     65        } while(0); 
     66 
     67/* Check that we are not looking at values beyond the ATR's length. 
     68 * If we are, then the card does not match. */ 
     69#define itacns_atr_l(idx) do {if (idx >= card->atr_len) return 0;} while(0); 
     70 
     71/* Match byte exactly and increment index. */ 
     72#define itacns_atr_match(idx, c) do { \ 
     73                itacns_atr_l(idx); \ 
     74                matchdebug(idx, c); \ 
     75                if (((u8)atr[idx]) != c) return 0; \ 
     76                idx++; \ 
     77        } while(0); 
     78 
     79/* Match masked bits and increment index. */ 
     80#define itacns_atr_mmatch(idx, c, mask) do { \ 
     81                itacns_atr_l(idx); \ 
     82                if ((((u8)atr[idx]) & mask) != c) return 0; \ 
     83                idx ++; \ 
     84        } while(0); 
     85         
     86/* Macro to access private driver data. */ 
     87#define DRVDATA(card) ((itacns_drv_data_t *) card->drv_data) 
     88 
     89 
     90int itacns_match_cns_card(sc_card_t *card, int i) 
     91{ 
     92        unsigned char *atr = card->atr; 
     93        sc_context_t *ctx; 
     94        ctx = card->ctx; 
     95 
     96 
     97        itacns_atr_match(i, 0x01); /* H7 */ 
     98        i += 2; /* H8, H9 */ 
     99        itacns_atr_match(i, 'C'); /* H10 */ 
     100        itacns_atr_match(i, 'N'); /* H11 */ 
     101        itacns_atr_match(i, 'S'); /* H12 */ 
     102 
     103        /* H13 */ 
     104        /* Version byte: h.l, h in the high nibble, l in the low nibble. */ 
     105        if(card->driver) { 
     106                DRVDATA(card)->cns_version = atr[i]; 
     107        } 
     108        /* Warn if the version is not 1.0. */ 
     109        if(atr[i] != 0x10) { 
     110                char version[8]; 
     111                snprintf(version, sizeof(version), "%d.%d", (atr[i] >> 4) & 0x0f, atr[i] & 0x0f); 
     112                sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "CNS card version %s; no official specifications " 
     113                        "are published. Proceeding anyway.\n", version); 
     114        } 
     115        i++; 
     116 
     117        itacns_atr_match(i, 0x31); /* H14 */ 
     118        itacns_atr_match(i, 0x80); /* H15 */ 
     119 
     120        card->type = SC_CARD_TYPE_ITACNS_CNS; 
     121 
     122        return 1; 
     123} 
     124 
     125int itacns_match_cie_card(sc_card_t *card, int i) 
     126{ 
     127        unsigned char *atr = card->atr; 
     128        sc_context_t *ctx; 
     129        ctx = card->ctx; 
     130 
     131        itacns_atr_match(i, 0x02); /* H7 */ 
     132        itacns_atr_match(i, 'I'); /* H8 */ 
     133        itacns_atr_match(i, 'T'); /* H9 */ 
     134        itacns_atr_match(i, 'I'); /* H10 */ 
     135        itacns_atr_match(i, 'D'); /* H11 */ 
     136        itacns_atr_match(i, 0x20); /* H12 */ 
     137        itacns_atr_match(i, 0x20); /* H13 */ 
     138        itacns_atr_match(i, 0x31); /* H14 */ 
     139        itacns_atr_match(i, 0x80); /* H15 */ 
     140 
     141        card->type = SC_CARD_TYPE_ITACNS_CIE_V2; 
     142 
     143        return 1; 
     144} 
     145 
     146int itacns_match_card(sc_card_t *card) 
     147{ 
     148        int i = 0, r; 
     149        unsigned char *atr = card->atr; 
     150        sc_context_t *ctx; 
     151        ctx = card->ctx; 
     152         
     153        /* Try table first */ 
     154        r = _sc_match_atr(card, itacns_atrs, &card->type); 
     155        if(r >= 0) return 1; 
     156 
     157        /* The ATR was not recognized; try to match it 
     158           according to the official specs. */ 
     159         
     160        /* Check ATR up to byte H6 */ 
     161        itacns_atr_match(i, 0x3b); /* TS */ 
     162        itacns_atr_mmatch(i, 0x8f, 0x8f); /* T0 */ 
     163        /* TA1, TB1, TC1 */ 
     164        if(atr[1] & 0x40) i++; 
     165        if(atr[1] & 0x20) i++; 
     166        if(atr[1] & 0x10) i++; 
     167        /* TD1 */ 
     168        int td1_idx = i; 
     169        itacns_atr_mmatch(i, 0x81, 0x8f); 
     170        /* TA2, TB2, TC2 */ 
     171        if(atr[td1_idx] & 0x40) i++; 
     172        if(atr[td1_idx] & 0x20) i++; 
     173        if(atr[td1_idx] & 0x10) i++; 
     174        /* TD2 */ 
     175        itacns_atr_match(i, 0x31); 
     176        i += 2; /* TA3, TB3 */ 
     177        itacns_atr_match(i, 0x00); /* H1 */ 
     178        itacns_atr_match(i, 0x6b); /* H2 */ 
     179        /* Store interesting data */ 
     180        if(card->driver) { 
     181                DRVDATA(card)->ic_manufacturer_code = card->atr[i]; 
     182                DRVDATA(card)->mask_manufacturer_code = card->atr[i+1]; 
     183                DRVDATA(card)->os_version_h = card->atr[i+2]; 
     184                DRVDATA(card)->os_version_l = card->atr[i+3]; 
     185        } 
     186        i += 4; /* H3, H4, H5, H6 */ 
     187 
     188        /* Check final part. */ 
     189        if (itacns_match_cns_card(card, i)) return 1; 
     190        if (itacns_match_cie_card(card, i)) return 1; 
     191 
     192        /* No card type was matched. */ 
     193        return 0; 
     194} 
     195 
     196/* 
     197 * Hex conversion table. A lookup into this table with a single character returns 
     198 * the nibble value, or 0xff in case of error. 
     199 */ 
     200 
     201static u8 hex_conversion[] = { 
     202    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
     203    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
     204    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
     205    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
     206    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
     207    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
     208    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 
     209    0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
     210    0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 
     211    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
     212    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
     213    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 
     214    0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, 
     215}; 
     216 
     217#define NIBBLE(c) (((u8)c) < sizeof(hex_conversion) ? hex_conversion[((u8)c)] : 0xff) 
     218 
     219/* 
     220 * Initialization and termination 
     221 */ 
     222 
     223static int itacns_init(sc_card_t *card) 
     224{ 
     225        SC_FUNC_CALLED(card->ctx, 1); 
     226 
     227        unsigned long   flags; 
     228 
     229        card->name = "CNS card"; 
     230        card->cla = 0x00; 
     231 
     232        card->drv_data = calloc(1, sizeof(itacns_drv_data_t)); 
     233 
     234        /* Match ATR again to find the card data. */ 
     235        itacns_match_card(card); 
     236 
     237        /* Set up algorithm info. */ 
     238        flags = SC_ALGORITHM_NEED_USAGE 
     239                | SC_ALGORITHM_RSA_RAW 
     240                | SC_ALGORITHM_RSA_PAD_PKCS1 
     241                | SC_ALGORITHM_RSA_HASHES 
     242                | SC_ALGORITHM_ONBOARD_KEY_GEN 
     243                ; 
     244        _sc_card_add_rsa_alg(card, 1024, flags, 0); 
     245         
     246        /* Load SM key. */ 
     247        scconf_block *drv_block, **blocks; 
     248        drv_block = NULL; 
     249        int i; 
     250        for (i = 0; card->ctx->conf_blocks[i] != NULL; i++) { 
     251                blocks = scconf_find_blocks(card->ctx->conf, card->ctx->conf_blocks[i], 
     252                                                "card_driver", "itacns"); 
     253                if (blocks[0] != NULL) 
     254                        drv_block = blocks[0]; 
     255                free(blocks); 
     256        } 
     257        if(!drv_block) 
     258                return 0; 
     259        return 0; 
     260} 
     261 
     262static int itacns_finish(struct sc_card *card) 
     263{ 
     264        if(card->drv_data) { 
     265                free(card->drv_data); 
     266        } 
     267        return 0; 
     268} 
     269 
     270 
     271 
     272/* 
     273 * Restore the indicated SE 
     274 */ 
     275static int itacns_restore_security_env(sc_card_t *card, int se_num) 
     276{ 
     277        sc_apdu_t apdu; 
     278        int     r; 
     279 
     280        SC_FUNC_CALLED(card->ctx, 1); 
     281 
     282        /* 
     283         * The Italian CNS seems to want a 0 byte at the end of the command, 
     284         * (a TLV structure with implicit tag, 0 length?) 
     285         * This requires patching apdu.c as well. 
     286         */ 
     287 
     288        sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 0xF3, se_num); 
     289         
     290        r = sc_transmit_apdu(card, &apdu); 
     291        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); 
     292 
     293        r = sc_check_sw(card, apdu.sw1, apdu.sw2); 
     294        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); 
     295 
     296        SC_FUNC_RETURN(card->ctx, 1, r); 
     297} 
     298 
     299/* 
     300 * Set the security context 
     301 * Things get a little messy here. It seems you cannot do any 
     302 * crypto without a security environment - but there isn't really 
     303 * a way to specify the security environment in PKCS15. 
     304 * What I'm doing here (for now) is to assume that for a key 
     305 * object with ID 0xNN there is always a corresponding SE object 
     306 * with the same ID. 
     307 * XXX Need to find out how the Aladdin drivers do it. 
     308 */ 
     309static int itacns_set_security_env(sc_card_t *card, 
     310                    const sc_security_env_t *env, int se_num) 
     311{ 
     312        sc_apdu_t apdu; 
     313        u8      data[3]; 
     314        int     key_id, r; 
     315 
     316        assert(card != NULL && env != NULL); 
     317 
     318        if (!(env->flags & SC_SEC_ENV_KEY_REF_PRESENT) 
     319         || env->key_ref_len != 1) { 
     320                sc_debug(card->ctx, SC_LOG_DEBUG_NORMAL, "No or invalid key reference\n"); 
     321                return SC_ERROR_INVALID_ARGUMENTS; 
     322        } 
     323        key_id = env->key_ref[0]; 
     324 
     325        /* CIE v1 cards need to restore security environment 0x30; all the others 
     326           so far want 0x03. */ 
     327        r = itacns_restore_security_env(card, (card->type == SC_CARD_TYPE_ITACNS_CIE_V1 
     328                ? 0x30 : 0x03)); 
     329        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); 
     330 
     331        sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0xF1, 0); 
     332        switch (env->operation) { 
     333        case SC_SEC_OPERATION_DECIPHER: 
     334                apdu.p2 = 0xB8; 
     335                break; 
     336        case SC_SEC_OPERATION_SIGN: 
     337                apdu.p2 = 0xB6; 
     338                break; 
     339        case SC_SEC_OPERATION_AUTHENTICATE: 
     340                apdu.p2 = 0xA4; 
     341                break; 
     342        default: 
     343                return SC_ERROR_INVALID_ARGUMENTS; 
     344        } 
     345 
     346        sc_debug(card->ctx, SC_LOG_DEBUG_VERBOSE, "Setting sec env for key_id=%d\n", key_id); 
     347 
     348        data[0] = 0x83; 
     349        data[1] = 0x01; 
     350        data[2] = key_id; 
     351        apdu.lc = apdu.datalen = 3; 
     352        apdu.data = data; 
     353 
     354        r = sc_transmit_apdu(card, &apdu); 
     355        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); 
     356 
     357        r = sc_check_sw(card, apdu.sw1, apdu.sw2); 
     358        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "Card returned error"); 
     359 
     360        SC_FUNC_RETURN(card->ctx, 1, r); 
     361} 
     362 
     363/* 
     364 * Compute digital signature 
     365 */ 
     366 
     367/* internal function to do the actual signature computation */ 
     368static int do_compute_signature(sc_card_t *card, 
     369                const u8 *data, size_t datalen, u8 *out, size_t outlen) 
     370{ 
     371        int r; 
     372        sc_apdu_t apdu; 
     373        u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; 
     374        u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; 
     375 
     376        if (datalen > SC_MAX_APDU_BUFFER_SIZE) 
     377                return SC_ERROR_INTERNAL; 
     378         
     379        if (outlen > 255) 
     380                outlen = 255; 
     381 
     382        /* INS: 0x2A  PERFORM SECURITY OPERATION 
     383         * P1:  0x9E  Resp: Digital Signature 
     384         * P2:  0x9A  Cmd: Input for Digital Signature */ 
     385        sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0x9A); 
     386        apdu.resp = rbuf; 
     387        apdu.le = outlen; 
     388        apdu.resplen = sizeof(rbuf); 
     389 
     390        memcpy(sbuf, data, datalen); 
     391        apdu.data = sbuf; 
     392        apdu.lc = datalen; 
     393        apdu.datalen = datalen; 
     394        r = sc_transmit_apdu(card, &apdu); 
     395        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); 
     396 
     397        if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { 
     398                memcpy(out, rbuf, outlen); 
     399                SC_FUNC_RETURN(card->ctx, 4, apdu.resplen); 
     400        } 
     401        SC_FUNC_RETURN(card->ctx, 4, sc_check_sw(card, apdu.sw1, apdu.sw2)); 
     402} 
     403 
     404static int 
     405itacns_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, 
     406                         u8 *out, size_t outlen) 
     407{ 
     408        /* This implementation does not try multiple operations. */ 
     409        sc_context_t *ctx; 
     410 
     411        assert(card != NULL && data != NULL && out != NULL); 
     412        ctx = card->ctx; 
     413        SC_FUNC_CALLED(ctx, 1); 
     414 
     415        if (datalen > 255) 
     416                SC_FUNC_RETURN(card->ctx, 4, SC_ERROR_INVALID_ARGUMENTS); 
     417        if (outlen < datalen) 
     418                SC_FUNC_RETURN(card->ctx, 4, SC_ERROR_BUFFER_TOO_SMALL); 
     419 
     420        if (outlen > MAX_LE) outlen = MAX_LE; 
     421 
     422        /* XXX As we don't know what operations are allowed with a 
     423         * certain key, let's try RSA_PURE etc. and see which operation 
     424         * succeeds (this is not really beautiful, but currently the 
     425         * only way I see) -- Nils 
     426         */ 
     427        return do_compute_signature(card, data, datalen, out, outlen);   
     428} 
     429 
     430 
     431/* internal function to do the actual decipher computation */ 
     432static int do_decipher(sc_card_t *card, 
     433                const u8 *data, size_t datalen, u8 *out, size_t outlen) 
     434{ 
     435        int r; 
     436        sc_apdu_t apdu; 
     437        u8 rbuf[SC_MAX_APDU_BUFFER_SIZE]; 
     438        u8 sbuf[SC_MAX_APDU_BUFFER_SIZE]; 
     439 
     440        if (datalen > SC_MAX_APDU_BUFFER_SIZE || 
     441            outlen > SC_MAX_APDU_BUFFER_SIZE) 
     442                return SC_ERROR_INTERNAL; 
     443 
     444        /* INS: 0x2A  PERFORM SECURITY OPERATION 
     445         * P1:  0x80 
     446         * P2:  0x86 */ 
     447        sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x86); 
     448        apdu.resp = rbuf; 
     449        apdu.le = outlen; 
     450        apdu.resplen = sizeof(rbuf); 
     451 
     452        /* Add extra padding, as per Functional Specification, 13.16 */ 
     453        sbuf[0] = 0; 
     454        memcpy(&sbuf[1], data, datalen); 
     455        apdu.data = sbuf; 
     456        apdu.lc = datalen + 1; 
     457        apdu.datalen = datalen +1; 
     458        r = sc_transmit_apdu(card, &apdu); 
     459        SC_TEST_RET(card->ctx, SC_LOG_DEBUG_NORMAL, r, "APDU transmit failed"); 
     460 
     461        if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) { 
     462                memcpy(out, rbuf, outlen); 
     463                SC_FUNC_RETURN(card->ctx, 4, apdu.resplen); 
     464        } 
     465        SC_FUNC_RETURN(card->ctx, 4, sc_check_sw(card, apdu.sw1, apdu.sw2)); 
     466} 
     467 
     468static int 
     469itacns_decipher(sc_card_t *card, const u8 * crgram, 
     470                size_t crgram_len, u8 * out, size_t outlen) 
     471{ 
     472        int r; 
     473        sc_context_t *ctx; 
     474 
     475        assert(card != NULL && crgram != NULL && out != NULL); 
     476        ctx = card->ctx; 
     477        SC_FUNC_CALLED(ctx, 1); 
     478 
     479        if (crgram_len > 255) 
     480                SC_FUNC_RETURN(card->ctx, 4, SC_ERROR_INVALID_ARGUMENTS); 
     481        if (outlen < crgram_len) 
     482                SC_FUNC_RETURN(card->ctx, 4, SC_ERROR_BUFFER_TOO_SMALL); 
     483        outlen = crgram_len; 
     484 
     485        /* XXX As we don't know what operations are allowed with a 
     486         * certain key, let's try RSA_PURE etc. and see which operation 
     487         * succeeds (this is not really beautiful, but currently the 
     488         * only way I see) -- Nils 
     489         */ 
     490        if (ctx->debug >= 3) 
     491                sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "trying RSA_PURE_SIG (padded DigestInfo)\n"); 
     492        r = do_decipher(card, crgram, crgram_len, out, outlen); 
     493        SC_FUNC_RETURN(ctx, 4, r); 
     494} 
     495 
     496/* 
     497 * The 0x80 thing tells the card it's okay to search parent 
     498 * directories as well for the referenced object. 
     499 * This is necessary for some Italian CNS cards, and to be avoided 
     500 * for others. Right now it seems that it is only needed with 
     501 * cards by STIncard. 
     502 */ 
     503static int 
     504itacns_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, 
     505                 int *tries_left) 
     506{ 
     507        data->flags |= SC_PIN_CMD_NEED_PADDING; 
     508        /* Enable backtracking for STIncard cards. */ 
     509        if(DRVDATA(card)->mask_manufacturer_code == ITACNS_MASKMAN_STINCARD) { 
     510                data->pin_reference |= 0x80; 
     511        } 
     512 
     513        /* FIXME: the following values depend on what pin length was 
     514         * used when creating the BS objects */ 
     515        if (data->pin1.max_length == 0) 
     516                data->pin1.max_length = 8; 
     517        if (data->pin2.max_length == 0) 
     518                data->pin2.max_length = 8; 
     519        return default_ops->pin_cmd(card, data, tries_left); 
     520} 
     521 
     522static int itacns_read_binary(sc_card_t *card, 
     523                               unsigned int idx, u8 *buf, size_t count, 
     524                               unsigned long flags) 
     525{ 
     526        size_t already_read = 0; 
     527        size_t requested; 
     528        int r; 
     529        while(1) { 
     530                requested = count - already_read; 
     531                if(requested > ITACNS_MAX_PAYLOAD) requested = ITACNS_MAX_PAYLOAD; 
     532                r = default_ops->read_binary(card, idx+already_read, &buf[already_read], 
     533                        requested, flags); 
     534                if(r < 0) return r; 
     535                already_read += r; 
     536                if (r == 0 || r < requested || already_read == count) { 
     537                        /* We have finished */ 
     538                        return already_read; 
     539                } 
     540        } 
     541} 
     542 
     543static int itacns_list_files(sc_card_t *card, u8 *buf, size_t buflen) { 
     544        struct sc_card_operations *list_ops; 
     545 
     546        if (DRVDATA(card) && DRVDATA(card)->mask_manufacturer_code == ITACNS_MASKMAN_SIEMENS) { 
     547                list_ops = sc_get_cardos_driver()->ops; 
     548        } else { 
     549                list_ops = sc_get_incrypto34_driver()->ops; 
     550        } 
     551        return list_ops->list_files(card, buf, buflen); 
     552} 
     553 
     554static struct sc_card_driver * sc_get_driver(void) 
     555{ 
     556        if (!default_ops) 
     557                default_ops = sc_get_iso7816_driver()->ops; 
     558        itacns_ops = *(sc_get_incrypto34_driver()->ops); 
     559        itacns_ops.match_card = itacns_match_card; 
     560        itacns_ops.init = itacns_init; 
     561        itacns_ops.finish = itacns_finish; 
     562        itacns_ops.set_security_env = itacns_set_security_env; 
     563        itacns_ops.restore_security_env = itacns_restore_security_env; 
     564        itacns_ops.decipher = itacns_decipher; 
     565        itacns_ops.compute_signature = itacns_compute_signature; 
     566        itacns_ops.pin_cmd = itacns_pin_cmd; 
     567        itacns_ops.read_binary = itacns_read_binary; 
     568        itacns_ops.list_files = itacns_list_files; 
     569        return &itacns_drv; 
     570} 
     571 
     572struct sc_card_driver * sc_get_itacns_driver(void) 
     573{ 
     574        return sc_get_driver(); 
     575} 
  • src/libopensc/cards.h

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