root/trunk/src/libopensc/pkcs15-infocamere.c

Revision 4118, 22.2 KB (checked in by aj, 3 days ago)

cleanup of the debug code:
* reduce to a few, supported functions.
* change all functions to take the debug level as parameter.
* use symbolic names for the debug levels.
* fix tools to pass "verbose"/"opt_debug" as ctx->debug.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * PKCS15 emulation layer for 1202, 1203 and 1400 Infocamere card.
3 * To see how this works, run p15dump on your Infocamere card.
4 *
5 * Copyright (C) 2005, Sirio Capizzi <graaf@virgilio.it>
6 * Copyright (C) 2004, Antonino Iacono <ant_iacono@tin.it>
7 * Copyright (C) 2003, Olaf Kirch <okir@suse.de>
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#include "config.h"
25
26#include <stdlib.h>
27#include <string.h>
28#include <stdio.h>
29#ifdef ENABLE_ZLIB
30#include <zlib.h>
31#endif
32
33#include "common/compat_strlcpy.h"
34#include "pkcs15.h"
35#include "log.h"
36
37int sc_pkcs15emu_infocamere_init_ex(sc_pkcs15_card_t *,
38                                    sc_pkcs15emu_opt_t *);
39
40static int (*set_security_env) (sc_card_t *, const sc_security_env_t *,
41                                int);
42
43static int set_sec_env(sc_card_t * card, const sc_security_env_t * env,
44                       int se_num)
45{
46        sc_security_env_t tenv = *env;
47        if (tenv.operation == SC_SEC_OPERATION_SIGN)
48                tenv.operation = SC_SEC_OPERATION_DECIPHER;
49        return set_security_env(card, &tenv, se_num);
50}
51
52static int do_sign(sc_card_t * card, const u8 * in, size_t inlen, u8 * out,
53                   size_t outlen)
54{
55        return card->ops->decipher(card, in, inlen, out, outlen);
56}
57
58static void set_string(char **strp, const char *value)
59{
60        if (*strp)
61                free(*strp);
62        *strp = value ? strdup(value) : NULL;
63}
64
65#if 1
66/* XXX: temporary copy of the old pkcs15emu functions,
67 *      to be removed */
68static int sc_pkcs15emu_add_pin(sc_pkcs15_card_t *p15card,
69                const sc_pkcs15_id_t *id, const char *label,
70                const sc_path_t *path, int ref, int type,
71                unsigned int min_length,
72                unsigned int max_length,
73                int flags, int tries_left, const char pad_char, int obj_flags)
74{
75        sc_pkcs15_pin_info_t info;
76        sc_pkcs15_object_t   obj;
77
78        memset(&info, 0, sizeof(info));
79        memset(&obj,  0, sizeof(obj));
80
81        info.auth_id           = *id;
82        info.min_length        = min_length;
83        info.max_length        = max_length;
84        info.stored_length     = max_length;
85        info.type              = type;
86        info.reference         = ref;
87        info.flags             = flags;
88        info.tries_left        = tries_left;
89        info.magic             = SC_PKCS15_PIN_MAGIC;
90        info.pad_char          = pad_char;
91
92        if (path)
93                info.path = *path;
94        if (type == SC_PKCS15_PIN_TYPE_BCD)
95                info.stored_length /= 2;
96
97        strlcpy(obj.label, label, sizeof(obj.label));
98        obj.flags = obj_flags;
99
100        return sc_pkcs15emu_add_pin_obj(p15card, &obj, &info);
101}
102
103static int sc_pkcs15emu_add_prkey(sc_pkcs15_card_t *p15card,
104                const sc_pkcs15_id_t *id,
105                const char *label,
106                int type, unsigned int modulus_length, int usage,
107                const sc_path_t *path, int ref,
108                const sc_pkcs15_id_t *auth_id, int obj_flags)
109{
110        sc_pkcs15_prkey_info_t info;
111        sc_pkcs15_object_t     obj;
112
113        memset(&info, 0, sizeof(info));
114        memset(&obj,  0, sizeof(obj));
115
116        info.id                = *id;
117        info.modulus_length    = modulus_length;
118        info.usage             = usage;
119        info.native            = 1;
120        info.access_flags      = SC_PKCS15_PRKEY_ACCESS_SENSITIVE
121                                | SC_PKCS15_PRKEY_ACCESS_ALWAYSSENSITIVE
122                                | SC_PKCS15_PRKEY_ACCESS_NEVEREXTRACTABLE
123                                | SC_PKCS15_PRKEY_ACCESS_LOCAL;
124        info.key_reference     = ref;
125
126        if (path)
127                info.path = *path;
128
129        obj.flags = obj_flags;
130        strlcpy(obj.label, label, sizeof(obj.label));
131        if (auth_id != NULL)
132                obj.auth_id = *auth_id;
133
134        return sc_pkcs15emu_add_rsa_prkey(p15card, &obj, &info);
135}
136
137static int sc_pkcs15emu_add_cert(sc_pkcs15_card_t *p15card,
138        int type, int authority, const sc_path_t *path,
139        const sc_pkcs15_id_t *id, const char *label, int obj_flags)
140{
141        /* const char *label = "Certificate"; */
142        sc_pkcs15_cert_info_t info;
143        sc_pkcs15_object_t    obj;
144
145        memset(&info, 0, sizeof(info));
146        memset(&obj,  0, sizeof(obj));
147
148        info.id                = *id;
149        info.authority         = authority;
150        if (path)
151                info.path = *path;
152
153        strlcpy(obj.label, label, sizeof(obj.label));
154        obj.flags = obj_flags;
155
156        return sc_pkcs15emu_add_x509_cert(p15card, &obj, &info);
157}
158#endif
159
160static int infocamere_1200_init(sc_pkcs15_card_t * p15card)
161{
162        const int prkey_usage = SC_PKCS15_PRKEY_USAGE_NONREPUDIATION;
163        const int authprkey_usage = SC_PKCS15_PRKEY_USAGE_SIGN
164            | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
165            | SC_PKCS15_PRKEY_USAGE_ENCRYPT
166            | SC_PKCS15_PRKEY_USAGE_DECRYPT;
167
168        sc_card_t *card = p15card->card;
169        sc_path_t path;
170        sc_file_t *file;
171        sc_pkcs15_id_t id, auth_id;
172        unsigned char buffer[256];
173        unsigned char ef_gdo[256];
174        char serial[256];
175        unsigned char certlen[2];
176        int authority, change_sign = 0;
177        struct sc_pkcs15_cert_info cert_info;
178        struct sc_pkcs15_object    cert_obj;
179
180        const char *label = "User Non-repudiation Certificate";
181        const char *calabel = "CA Certificate";
182        const char *authlabel = "User Authentication Certificate";
183
184        const char *infocamere_cert_path[2] = {
185                "DF01C000",
186                "3F00000011111A02"
187        };
188
189        const char *infocamere_auth_certpath[2] = {
190                "11111A02",
191                "000011111B02"
192        };
193
194        const char *infocamere_cacert_path[2] = {
195                "DF01C008",
196                "000011114101"
197        };
198
199        const char *infocamere_auth_path[2] = {
200                "3F001111",
201                "3F0000001111"
202        };
203
204        const char *infocamere_nrepud_path[2] = {
205                "3F00DF01",
206                "3F0000001111"
207        };
208
209        const int infocamere_idpin_auth_obj[2] = {
210                0x95,
211                0x81
212        };
213
214        const int infocamere_idpin_nrepud_obj[2] = {
215                0x99,
216                0x81
217        };
218
219        const int infocamere_idprkey_auth_obj[2] = {
220                0x9B,
221                0x01
222        };
223
224        const int infocamere_idprkey_nrepud_obj[2] = {
225                0x84,
226                0x01
227        };
228
229        const char *authPIN = "Authentication PIN";
230        const char *nonrepPIN = "Non-repudiation PIN";
231
232        const char *authPRKEY = "Authentication Key";
233        const char *nonrepPRKEY = "Non repudiation Key";
234
235        const int flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE |
236            SC_PKCS15_PIN_FLAG_INITIALIZED |
237            SC_PKCS15_PIN_FLAG_NEEDS_PADDING;
238
239        int r, len_iccsn, len_chn;
240
241        sc_format_path("3F002F02", &path);
242
243        r = sc_select_file(card, &path, &file);
244       
245        if (r != SC_SUCCESS || file->size > 255) {
246                /* Not EF.GDO */
247                return SC_ERROR_WRONG_CARD;
248        }
249
250        sc_read_binary(card, 0, ef_gdo, file->size, 0);
251
252        if (ef_gdo[0] != 0x5A || file->size < 3) {
253                /* Not EF.GDO */
254                return SC_ERROR_WRONG_CARD;
255        }
256
257        len_iccsn = ef_gdo[1];
258
259        memcpy(buffer, ef_gdo + 2, len_iccsn);
260
261        sc_bin_to_hex(buffer, len_iccsn, serial, sizeof(serial), 0);
262
263        if (file->size < (size_t) (len_iccsn + 5)) {
264                /* Not CHN */
265                return SC_ERROR_WRONG_CARD;
266        }
267
268        if (!
269            (ef_gdo[len_iccsn + 2] == 0x5F
270             && ef_gdo[len_iccsn + 3] == 0x20)) {
271                /* Not CHN */
272                return SC_ERROR_WRONG_CARD;
273        }
274
275        len_chn = ef_gdo[len_iccsn + 4];
276
277        if (len_chn < 2 || len_chn > 8) {
278                /* Length CHN incorrect */
279                return SC_ERROR_WRONG_CARD;
280        }
281
282        if (!
283            (ef_gdo[len_iccsn + 5] == 0x12
284             && (ef_gdo[len_iccsn + 6] == 0x02
285                 || ef_gdo[len_iccsn + 6] == 0x03))) {
286                /* Not Infocamere Card */
287                return SC_ERROR_WRONG_CARD;
288        }
289
290        set_string(&p15card->serial_number, serial);
291
292        if (ef_gdo[len_iccsn + 6] == 0x02)
293                set_string(&p15card->label, "Infocamere 1202 Card");
294        else {
295                set_string(&p15card->label, "Infocamere 1203 Card");
296                change_sign = 1;
297        }
298
299        set_string(&p15card->manufacturer_id, "Infocamere");
300
301        authority = 0;
302
303        /* Get the authentication certificate length */
304
305        sc_format_path(infocamere_auth_certpath[ef_gdo[len_iccsn+6]-2], &path);
306
307        r = sc_select_file(card, &path, NULL);
308
309        if (r >= 0) {
310
311                sc_read_binary(card, 0, certlen, 2, 0);
312
313                /* Now set the certificate offset/len */
314
315                path.index = 2;
316                path.count = (certlen[1] << 8) + certlen[0];
317
318                memset(&cert_info, 0, sizeof(cert_info));
319                memset(&cert_obj,  0, sizeof(cert_obj));
320
321                sc_pkcs15_format_id("1", &cert_info.id);
322                cert_info.authority = authority;
323                cert_info.path = path;
324                strlcpy(cert_obj.label, authlabel, sizeof(cert_obj.label));
325                cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE;
326
327                r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
328                if (r < 0)
329                        return SC_ERROR_INTERNAL;
330
331                /* XXX: the IDs for the key/pin in case of the 1203 type
332                 * are wrong, therefore I disable them for now -- Nils */
333                if (!change_sign) {   
334                /* add authentication PIN */
335
336                sc_format_path(infocamere_auth_path[ef_gdo[len_iccsn+6]-2], &path);
337               
338                sc_pkcs15_format_id("1", &id);
339                sc_pkcs15emu_add_pin(p15card, &id,
340                                authPIN, &path, infocamere_idpin_auth_obj[ef_gdo[len_iccsn+6]-2],
341                                SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
342                                5, 8, flags, 3, 0,
343                                SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE);
344
345                /* add authentication private key */
346
347                auth_id.value[0] = 1;
348                auth_id.len = 1;
349
350                sc_pkcs15emu_add_prkey(p15card, &id,
351                                authPRKEY,
352                                SC_PKCS15_TYPE_PRKEY_RSA,
353                                1024, authprkey_usage,
354                                &path, infocamere_idprkey_auth_obj[ef_gdo[len_iccsn+6]-2],
355                                &auth_id, SC_PKCS15_CO_FLAG_PRIVATE);
356                }
357
358        }
359
360        /* Get the non-repudiation certificate length */
361
362        sc_format_path(infocamere_cert_path[ef_gdo[len_iccsn+6]-2], &path);
363
364        if (sc_select_file(card, &path, NULL) < 0)
365                {
366                return SC_ERROR_INTERNAL;
367                }
368
369        sc_read_binary(card, 0, certlen, 2, 0);
370
371        /* Now set the certificate offset/len */
372        path.index = 2;
373        path.count = (certlen[1] << 8) + certlen[0];
374       
375        memset(&cert_info, 0, sizeof(cert_info));
376        memset(&cert_obj,  0, sizeof(cert_obj));
377
378        sc_pkcs15_format_id("2", &cert_info.id);
379
380        cert_info.authority = authority;
381        cert_info.path = path;
382        strlcpy(cert_obj.label, label, sizeof(cert_obj.label));
383        cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE;
384
385        r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
386        if (r < 0)
387                return SC_ERROR_INTERNAL;
388
389        /* Get the CA certificate length */
390
391        authority = 1;
392
393        sc_format_path(infocamere_cacert_path[ef_gdo[len_iccsn+6]-2], &path);
394
395        r = sc_select_file(card, &path, NULL);
396
397        if (r >= 0) {
398                size_t len;
399
400                sc_read_binary(card, 0, certlen, 2, 0);
401
402                len = (certlen[1] << 8) + certlen[0];
403
404                if (len != 0) {
405                        /* Now set the certificate offset/len */
406                        path.index = 2;
407                        path.count = len;
408
409                        memset(&cert_info, 0, sizeof(cert_info));
410                        memset(&cert_obj,  0, sizeof(cert_obj));
411
412                        sc_pkcs15_format_id("3", &cert_info.id);
413                        cert_info.authority = authority;
414                        cert_info.path = path;
415                        strlcpy(cert_obj.label, calabel, sizeof(cert_obj.label));
416                        cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE;
417
418                        r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
419                        if (r < 0)
420                        return SC_ERROR_INTERNAL;
421                }
422        }
423
424        /* add non repudiation PIN */
425
426        sc_format_path(infocamere_nrepud_path[ef_gdo[len_iccsn+6]-2], &path);
427
428        sc_pkcs15_format_id("2", &id);
429        sc_pkcs15emu_add_pin(p15card, &id,
430                nonrepPIN, &path, infocamere_idpin_nrepud_obj[ef_gdo[len_iccsn+6]-2],
431                SC_PKCS15_PIN_TYPE_ASCII_NUMERIC, 5, 8, flags, 3, 0,
432                SC_PKCS15_CO_FLAG_MODIFIABLE | SC_PKCS15_CO_FLAG_PRIVATE);
433
434
435        /* add non repudiation private key */
436
437        auth_id.value[0] = 2;
438        auth_id.len = 1;
439
440        sc_pkcs15emu_add_prkey(p15card, &id, nonrepPRKEY,
441                               SC_PKCS15_TYPE_PRKEY_RSA,
442                               1024, prkey_usage,
443                               &path, infocamere_idprkey_nrepud_obj[ef_gdo[len_iccsn+6]-2],
444                               &auth_id, SC_PKCS15_CO_FLAG_PRIVATE);
445
446
447        /* return to MF */
448        sc_format_path("3F00", &path);
449        r = sc_select_file(card, &path, NULL);
450        if (r != SC_SUCCESS)
451                return r;
452
453        if (change_sign) {
454                /* save old signature funcs */
455                set_security_env = card->ops->set_security_env;
456                /* set new one */
457                card->ops->set_security_env = set_sec_env;
458                card->ops->compute_signature = do_sign;
459        }
460
461        return SC_SUCCESS;
462}
463
464static int infocamere_1400_set_sec_env(struct sc_card *card,
465                                       const struct sc_security_env *env,
466                                       int se_num)
467{
468        int r;
469
470        struct sc_security_env tenv = *env;
471        if (tenv.operation == SC_SEC_OPERATION_SIGN)
472                tenv.operation = SC_SEC_OPERATION_DECIPHER;
473
474        if ((r =
475             card->ops->restore_security_env(card, 0x40)) == SC_SUCCESS)
476                return set_security_env(card, &tenv, se_num);
477        else
478                return r;
479}
480
481#ifdef ENABLE_ZLIB
482
483static const u8 ATR_1400[] =
484    { 0x3b, 0xfc, 0x98, 0x00, 0xff, 0xc1, 0x10, 0x31, 0xfe, 0x55, 0xc8,
485        0x03, 0x49, 0x6e, 0x66, 0x6f, 0x63, 0x61, 0x6d, 0x65, 0x72, 0x65,
486        0x28
487};
488
489/* Loads certificates.
490* Certificates are stored in a ZLib compressed form with
491* a 4 byte header, so we extract, decompress and cache
492* them.
493*/
494static int loadCertificate(sc_pkcs15_card_t * p15card, int i,
495                           const char *certPath, const char *certLabel)
496{
497        unsigned char *compCert = NULL, *cert = NULL, size[2];
498        unsigned long int compLen, len;
499        sc_pkcs15_cert_info_t cert_info;
500        sc_pkcs15_object_t cert_obj;
501        sc_path_t cpath;
502        sc_card_t *card = p15card->card;
503        sc_pkcs15_id_t id;
504        int r;
505
506        memset(&cert_info, 0, sizeof(cert_info));
507        memset(&cert_obj, 0, sizeof(cert_obj));
508
509        sc_format_path(certPath, &cpath);
510
511        if (sc_select_file(card, &cpath, NULL) != SC_SUCCESS)
512                return SC_ERROR_WRONG_CARD;
513
514        sc_read_binary(card, 2, size, 2, 0);
515
516        compLen = (size[0] << 8) + size[1];
517        compCert =
518            (unsigned char *) malloc(compLen * sizeof(unsigned char));
519        len = 4 * compLen;      /*Approximation of the uncompressed size */
520        cert = (unsigned char *) malloc(len * sizeof(unsigned char));
521
522        sc_read_binary(card, 4, compCert, compLen, 0);
523
524        if ((r = uncompress(cert, &len, compCert, compLen)) != Z_OK) {
525                sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "Zlib error: %d", r);
526                return SC_ERROR_INTERNAL;
527        }
528
529        cpath.index = 0;
530        cpath.count = len;
531
532        sc_pkcs15_cache_file(p15card, &cpath, cert, len);
533
534        id.len=1;
535        id.value[0] = i + 1;
536
537        cert_info.id = id;
538        cert_info.path = cpath;
539        cert_info.authority = (i == 2);
540
541        strlcpy(cert_obj.label, certLabel, sizeof(cert_obj.label));
542        cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE;
543
544        sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
545
546        return SC_SUCCESS;
547}
548
549
550static int infocamere_1400_init(sc_pkcs15_card_t * p15card)
551{
552        sc_card_t *card = p15card->card;
553        sc_path_t path;
554        sc_pkcs15_id_t id, auth_id;
555        unsigned char serial[16];
556        int flags;
557        int r;
558        int hasAuthCert = 0;
559
560        const char *certLabel[] = { "User Non-repudiation Certificate",
561                "User Authentication Certificate",
562                "CA Certificate"
563        };
564
565        const char *certPath[] =
566            { "300060000000", "300060000001", "300060000002" };
567
568        const char *pinLabel[] =
569            { "Non-repudiation PIN", "Authentication PIN" };
570        int retries[] = { 3, -1 };
571
572        const char *keyPath[] = { "30004000001", "30004000002" };
573        const char *keyLabel[] =
574            { "Non repudiation Key", "Authentication Key" };
575        static int usage[] = { SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
576                SC_PKCS15_PRKEY_USAGE_SIGN
577                    | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
578                    | SC_PKCS15_PRKEY_USAGE_ENCRYPT
579                    | SC_PKCS15_PRKEY_USAGE_DECRYPT
580        };
581
582        auth_id.len = 1;
583        id.len = 1;
584
585        /* OpenSC doesn't define constants to identify BSOs for
586         * restoring security environment, so we overload
587         * the set_security_env function to support restore_sec_env */
588        set_security_env = card->ops->set_security_env;
589        card->ops->set_security_env = infocamere_1400_set_sec_env;
590        card->ops->compute_signature = do_sign;
591        p15card->opts.use_file_cache = 1;
592
593        sc_format_path("30000001", &path);
594
595        r = sc_select_file(card, &path, NULL);
596       
597        if (r != SC_SUCCESS)
598                return SC_ERROR_WRONG_CARD;
599
600        sc_read_binary(card, 15, serial, 15, 0);
601        serial[15] = '\0';
602
603        set_string(&p15card->serial_number, (char *)serial);
604        set_string(&p15card->label, "Infocamere 1400 Card");
605        set_string(&p15card->manufacturer_id, "Infocamere");
606
607        if ((r = loadCertificate(p15card, 0, certPath[0], certLabel[0])) !=
608            SC_SUCCESS) {
609                sc_debug(p15card->card->ctx, SC_LOG_DEBUG_NORMAL, "%s", sc_strerror(r));
610                return SC_ERROR_WRONG_CARD;
611        }
612
613        hasAuthCert =
614            loadCertificate(p15card, 1, certPath[1],
615                            certLabel[1]) == SC_SUCCESS;
616        loadCertificate(p15card, 2, certPath[2], certLabel[2]);
617
618        flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE |
619            SC_PKCS15_PIN_FLAG_INITIALIZED |
620            SC_PKCS15_PIN_FLAG_NEEDS_PADDING;
621
622        /* adding PINs & private keys */
623
624        sc_format_path("30004000", &path);
625        id.value[0] = 1;
626
627        sc_pkcs15emu_add_pin(p15card, &id,
628                             pinLabel[0], &path, 1,
629                             SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
630                             5, 8, flags, retries[0], 0,
631                             SC_PKCS15_CO_FLAG_MODIFIABLE |
632                             SC_PKCS15_CO_FLAG_PRIVATE);
633
634        sc_format_path(keyPath[0], &path);
635        auth_id.value[0] = 1;
636        sc_pkcs15emu_add_prkey(p15card, &id,
637                               keyLabel[0],
638                               SC_PKCS15_TYPE_PRKEY_RSA,
639                               1024, usage[0],
640                               &path, 1,
641                               &auth_id, SC_PKCS15_CO_FLAG_PRIVATE);
642
643
644        if (hasAuthCert) {
645                sc_format_path("30004000", &path);
646                id.value[0] = 2;
647
648                sc_pkcs15emu_add_pin(p15card, &id,
649                                     pinLabel[1], &path, 2,
650                                     SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
651                                     5, 8, flags, retries[1], 0,
652                                     SC_PKCS15_CO_FLAG_MODIFIABLE |
653                                     SC_PKCS15_CO_FLAG_PRIVATE);
654
655                sc_format_path(keyPath[1], &path);
656                auth_id.value[0] = 2;
657                sc_pkcs15emu_add_prkey(p15card, &id,
658                                       keyLabel[1],
659                                       SC_PKCS15_TYPE_PRKEY_RSA,
660                                       1024, usage[1],
661                                       &path, 2,
662                                       &auth_id,
663                                       SC_PKCS15_CO_FLAG_PRIVATE);
664        }
665
666        /* return to MF */
667        sc_format_path("3F00", &path);
668        r = sc_select_file(card, &path, NULL);
669        return r;
670        }
671
672#endif
673
674static const u8 ATR_1600[] = { 0x3B, 0xF4, 0x98, 0x00, 0xFF, 0xC1, 0x10,
675        0x31, 0xFE, 0x55, 0x4D, 0x34, 0x63, 0x76, 0xB4
676};
677
678static int infocamere_1600_init(sc_pkcs15_card_t * p15card)
679{
680        sc_card_t *card = p15card->card;
681        sc_path_t path;
682        sc_pkcs15_id_t id, auth_id;
683        unsigned char serial[17];
684        int flags;
685        int r;
686        int hasAuthCert = 0;
687
688        const char *certLabel[] = { "User Non-repudiation Certificate",
689                "User Authentication Certificate"
690        };
691
692        const char *certPath[] = { "200020010008", "20002001000E" };
693
694        const char *pinLabel[] =
695            { "Non-repudiation PIN", "Authentication PIN" };
696        int retries[] = { 3, -1 };
697
698        const char *keyPath[] = { "200020010004", "20002001000A" };
699        const char *keyLabel[] =
700            { "Non repudiation Key", "Authentication Key" };
701        static int usage[] = { SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,
702                SC_PKCS15_PRKEY_USAGE_SIGN
703                    | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER
704                    | SC_PKCS15_PRKEY_USAGE_ENCRYPT
705                    | SC_PKCS15_PRKEY_USAGE_DECRYPT
706        };
707
708        auth_id.len = 1;
709        id.len = 1;
710
711        /* OpenSC doesn't define constants to identify BSOs for
712         * restoring security environment, so we overload
713         * the set_security_env function to support restore_sec_env */
714        set_security_env = card->ops->set_security_env;
715        card->ops->set_security_env = infocamere_1400_set_sec_env;
716        card->ops->compute_signature = do_sign;
717
718        sc_format_path("200020012002", &path);
719
720        r = sc_select_file(card, &path, NULL);
721
722        if (r != SC_SUCCESS)
723                return SC_ERROR_WRONG_CARD;
724
725        sc_read_binary(card, 30, serial, 16, 0);
726        serial[16] = '\0';
727
728        set_string(&p15card->serial_number, (char *) serial);
729        set_string(&p15card->label, "Infocamere 1600 Card");
730        set_string(&p15card->manufacturer_id, "Infocamere");
731
732        /* Adding certificates.
733         * Certificates are stored in a ZLib compressed form with
734         * a 4 byte header, so we extract, decompress and cache
735         * them.
736         */
737        sc_format_path(certPath[0], &path);
738        if (sc_select_file(card, &path, NULL) != SC_SUCCESS)
739                return SC_ERROR_WRONG_CARD;
740
741        id.value[0] = 1;
742
743        sc_pkcs15emu_add_cert(p15card,
744                              SC_PKCS15_TYPE_CERT_X509, 0,
745                              &path, &id, certLabel[0],
746                              SC_PKCS15_CO_FLAG_MODIFIABLE);
747
748        sc_format_path(certPath[1], &path);
749        if (sc_select_file(card, &path, NULL) == SC_SUCCESS) {
750                hasAuthCert = 1;
751
752                id.value[0] = 2;
753
754                sc_pkcs15emu_add_cert(p15card,
755                                      SC_PKCS15_TYPE_CERT_X509, 1,
756                                      &path, &id, certLabel[1],
757                                      SC_PKCS15_CO_FLAG_MODIFIABLE);
758        }
759
760        flags = SC_PKCS15_PIN_FLAG_CASE_SENSITIVE |
761            SC_PKCS15_PIN_FLAG_INITIALIZED |
762            SC_PKCS15_PIN_FLAG_NEEDS_PADDING;
763
764        /* adding PINs & private keys */
765        sc_format_path("2000", &path);
766        id.value[0] = 1;
767
768        sc_pkcs15emu_add_pin(p15card, &id,
769                             pinLabel[0], &path, 1,
770                             SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
771                             5, 8, flags, retries[0], 0,
772                             SC_PKCS15_CO_FLAG_MODIFIABLE |
773                             SC_PKCS15_CO_FLAG_PRIVATE);
774
775        sc_format_path(keyPath[0], &path);
776        auth_id.value[0] = 1;
777        sc_pkcs15emu_add_prkey(p15card, &id,
778                               keyLabel[0],
779                               SC_PKCS15_TYPE_PRKEY_RSA,
780                               1024, usage[0],
781                               &path, 1,
782                               &auth_id, SC_PKCS15_CO_FLAG_PRIVATE);
783
784        if (hasAuthCert) {
785                id.value[0] = 2;
786
787                sc_pkcs15emu_add_pin(p15card, &id,
788                                     pinLabel[1], &path, 2,
789                                     SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
790                                     5, 8, flags, retries[1], 0,
791                                     SC_PKCS15_CO_FLAG_MODIFIABLE |
792                                     SC_PKCS15_CO_FLAG_PRIVATE);
793
794                sc_format_path(keyPath[1], &path);
795                auth_id.value[0] = 2;
796                sc_pkcs15emu_add_prkey(p15card, &id,
797                                       keyLabel[1],
798                                       SC_PKCS15_TYPE_PRKEY_RSA,
799                                       1024, usage[1],
800                                       &path, 2,
801                                       &auth_id,
802                                       SC_PKCS15_CO_FLAG_PRIVATE);
803        }
804
805        /* return to MF */
806        sc_format_path("3F00", &path);
807        r = sc_select_file(card, &path, NULL);
808
809        return SC_SUCCESS;
810}
811
812static int infocamere_detect_card(sc_pkcs15_card_t * p15card)
813{
814        sc_card_t *card = p15card->card;
815
816        /* check if we have the correct card OS */
817        if (strcmp(card->name, "STARCOS SPK 2.3")
818            && strcmp(card->name, "CardOS M4"))
819                return SC_ERROR_WRONG_CARD;
820        return SC_SUCCESS;
821}
822
823int sc_pkcs15emu_infocamere_init_ex(sc_pkcs15_card_t * p15card,
824                                    sc_pkcs15emu_opt_t * opts)
825{
826
827        if (!(opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)) {
828                if (infocamere_detect_card(p15card))
829                        return SC_ERROR_WRONG_CARD;
830        }
831
832        if (memcmp(p15card->card->atr, ATR_1600, sizeof(ATR_1600)) == 0)
833                return infocamere_1600_init(p15card);
834#ifdef ENABLE_ZLIB
835        else if (memcmp(p15card->card->atr, ATR_1400, sizeof(ATR_1400)) ==
836                 0)
837                return infocamere_1400_init(p15card);
838#endif
839        else
840                return infocamere_1200_init(p15card);
841
842}
Note: See TracBrowser for help on using the browser.