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

Revision 3405, 22.4 kB (checked in by alonbl, 7 months ago)

Complete rewrite of OpenSC build system.

1. Build system now supports MinGW (Windows) compilation using msys and cross compilation.
2. Ability to explicitly disable and enable dependencies of the package.
3. openct, pcsc and nsplugins features are disabled by default.
4. Modified pcsc driver to use pcsc dynamically, no compile time dependency is required.
5. --enable-pcsc-lite configuration option renamed to --enable-pcsc.
6. Install opensc.conf file (as opensc.conf.new if opensc.conf exists).
7. Add--enable-doc configuration option, allow installing documentation into target.
8. Add --disable-man configuration option, allow msys mingw32 users to

build from svn without extra dependencies.

9. Add export files to each library in order to export only required symbols.

Windows native build may use these files instead of scanning objects' symbols.

10. Add opensc-tool --info to display some general information about the build.
11. Create compatibility library to be linked against library instread of recompiling the

same source files in different places.

12. Add different win32 version resource to each class of outputs.
13. Make xsl-stylesheets location selectable.
14. Some win32 fixups.
15. Some warning fixups.
16. Many other autoconf/automake cleanups.

Alon Bar-Lev

svn diff -r 3315:3399 https://www.opensc-project.org/svn/opensc/branches/alonbl/mingw

_M .
D configure.in
_M src
_M src/openssh
M src/openssh/Makefile.am
_M src/tools
M src/tools/rutoken-tool.c
M src/tools/opensc-tool.c
M src/tools/cardos-info.c
M src/tools/pkcs15-crypt.c
M src/tools/pkcs15-init.c
M src/tools/piv-tool.c
M src/tools/netkey-tool.c
M src/tools/eidenv.c
M src/tools/cryptoflex-tool.c
M src/tools/util.c
M src/tools/pkcs11-tool.c
M src/tools/pkcs15-tool.c
M src/tools/util.h
M src/tools/opensc-explorer.c
M src/tools/Makefile.am
_M src/pkcs11
M src/pkcs11/pkcs11-global.c
M src/pkcs11/framework-pkcs15.c
M src/pkcs11/mechanism.c
M src/pkcs11/pkcs11-display.c
M src/pkcs11/pkcs11-object.c
A src/pkcs11/opensc-pkcs11.exports
M src/pkcs11/sc-pkcs11.h
M src/pkcs11/pkcs11-spy.c
M src/pkcs11/openssl.c
M src/pkcs11/Makefile.am
A src/pkcs11/pkcs11-spy.exports
_M src/tests
_M src/tests/regression
M src/tests/regression/Makefile.am
M src/tests/sc-test.c
M src/tests/pintest.c
M src/tests/Makefile.am
_M src/include
_M src/include/opensc
M src/include/opensc/Makefile.am
A src/include/opensc/svnignore
M src/include/Makefile.am
_M src/signer
_M src/signer/npinclude
M src/signer/npinclude/Makefile.am
M src/signer/Makefile.am
A src/signer/signer.exports
_M src/common
A src/common/compat_dummy.c
D src/common/getopt.txt
D src/common/strlcpy.c
D src/common/LICENSE
A src/common/compat_getopt.txt
A src/common/compat_strlcpy.c
A src/common/LICENSE.compat_getopt
A src/common/compat_getopt.c
D src/common/strlcpy.h
D src/common/ChangeLog
D src/common/getpass.c
D src/common/my_getopt.c
A src/common/compat_strlcpy.h
A src/common/compat_getpass.c
A src/common/compat_getopt.h
A src/common/ChangeLog.compat_getopt
D src/common/README.strlcpy
D src/common/my_getopt.h
A src/common/compat_getpass.h
A src/common/README.compat_strlcpy
D src/common/strlcpy.3
A src/common/README.compat_getopt
D src/common/getopt.3
D src/common/README.my_getopt
A src/common/compat_strlcpy.3
A src/common/compat_getopt.3
M src/common/Makefile.am
M src/Makefile.am
_M src/pkcs15init
M src/pkcs15init/pkcs15-oberthur.c
M src/pkcs15init/profile.c
M src/pkcs15init/pkcs15-lib.c
M src/pkcs15init/pkcs15-rutoken.c
A src/pkcs15init/pkcs15init.exports
M src/pkcs15init/pkcs15-gpk.c
M src/pkcs15init/Makefile.am
_M src/scconf
M src/scconf/Makefile.am
M src/scconf/parse.c
A src/scconf/scconf.exports
_M src/libopensc
M src/libopensc/card-rutoken.c
M src/libopensc/compression.c
M src/libopensc/sc.c
M src/libopensc/card-piv.c
M src/libopensc/pkcs15-openpgp.c
M src/libopensc/pkcs15-postecert.c
M src/libopensc/pkcs15-tcos.c
M src/libopensc/opensc-config.in
M src/libopensc/reader-pcsc.c
A src/libopensc/internal-winscard.h
M src/libopensc/ctx.c
A src/libopensc/libopensc.exports
M src/libopensc/pkcs15-piv.c
M src/libopensc/pkcs15-infocamere.c
M src/libopensc/internal.h
M src/libopensc/pkcs15-actalis.c
M src/libopensc/pkcs15-starcert.c
M src/libopensc/card-oberthur.c
M src/libopensc/pkcs15-atrust-acos.c
M src/libopensc/p15card-helper.c
D src/libopensc/part10.h
M src/libopensc/ui.c
M src/libopensc/card-gpk.c
M src/libopensc/pkcs15-wrap.c
M src/libopensc/pkcs15-gemsafeGPK.c
M src/libopensc/log.c
M src/libopensc/pkcs15-esteid.c
M src/libopensc/pkcs15-prkey-rutoken.c
M src/libopensc/log.h
M src/libopensc/Makefile.am
M src/libopensc/reader-openct.c
_M aclocal
M aclocal/Makefile.am
_M win32
M win32/Makefile.am
A win32/versioninfo.rc.in
A win32/ltrc.inc
A configure.ac
_M doc
_M doc/tools
M doc/tools/pkcs15-profile.xml
D doc/changelog.sh
D doc/export-wiki.xsl
_M doc/api
_M doc/api/file
M doc/api/man.xsl
_M doc/api/asn1
_M doc/api/apps
_M doc/api/init
_M doc/api/types
_M doc/api/card
M doc/api/html.xsl
_M doc/api/misc
_M doc/api/util
M doc/Makefile.am
D doc/export-wiki.sh
AM doc/nonpersistent
A doc/nonpersistent/export-wiki.xsl
A doc/nonpersistent/Makefile.am
A doc/nonpersistent/export-wiki.sh
A doc/nonpersistent/svn2cl.xsl
D doc/generate-man.sh
D doc/svn2cl.xsl
M Makefile.am
A svnignore
_M etc
M etc/opensc.conf.in
M etc/Makefile.am
D man
_M solaris
M solaris/Makefile

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