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

Revision 3405, 14.7 KB (checked in by alonbl, 9 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

Line 
1/*
2 * partial PKCS15 emulation for gemsafe GPK cards
3 *
4 * Copyright (C) 2005, Douglas E. Engert <deengert@anl.gov>
5 *               2004, Nils Larsch <larsch@trustcenter.de>
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 */
21
22#include "internal.h"
23#include <opensc/pkcs15.h>
24#include <opensc/log.h>
25#include <opensc/cardctl.h>
26#include <stdlib.h>
27#include <string.h>
28#include <stdio.h>
29#include <compat_strlcpy.h>
30
31#define MANU_ID         "GemSAFE on GPK16000"
32
33int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *, sc_pkcs15emu_opt_t *);
34
35static int (*pin_cmd_save)(struct sc_card *, struct sc_pin_cmd_data *,
36                int *tries_left);
37
38typedef struct cdata_st {
39        const char *label;
40        int         authority;
41        const char *path;
42        const char *id;
43        int         obj_flags;
44} cdata;
45
46typedef struct pdata_st {
47        const char *id;
48        const char *label;
49        const char *path;
50        int         ref;
51        int         type;
52        unsigned int maxlen;
53        unsigned int minlen;
54        unsigned int storedlen;
55        int         flags;     
56        int         tries_left;
57        const char  pad_char;
58        int         obj_flags;
59} pindata;
60
61typedef struct prdata_st {
62        const char *id;
63        const char *label;
64        unsigned int modulus_len;
65        int         usage;
66        const char *path;
67        int         ref;
68        const char *auth_id;
69        int         obj_flags;
70} prdata;
71
72typedef struct keyinfo_st {
73        int fileid;
74        sc_pkcs15_id_t id;
75        unsigned int modulus_len;
76        u8 modulus[1024/8];
77} keyinfo;
78
79#define USAGE_NONREP    SC_PKCS15_PRKEY_USAGE_NONREPUDIATION
80#define USAGE_KE        SC_PKCS15_PRKEY_USAGE_ENCRYPT | \
81                        SC_PKCS15_PRKEY_USAGE_DECRYPT | \
82                        SC_PKCS15_PRKEY_USAGE_WRAP    | \
83                        SC_PKCS15_PRKEY_USAGE_UNWRAP
84#define USAGE_AUT       SC_PKCS15_PRKEY_USAGE_ENCRYPT | \
85                        SC_PKCS15_PRKEY_USAGE_DECRYPT | \
86                        SC_PKCS15_PRKEY_USAGE_WRAP    | \
87                        SC_PKCS15_PRKEY_USAGE_UNWRAP  | \
88                        SC_PKCS15_PRKEY_USAGE_SIGN
89
90static const u8 gemsafe_aid[] = {0xA0, 0x00, 0x00, 0x00, 0x18,
91                0x0F, 0x00, 0x00, 0x01, 0x63, 0x00, 0x01};
92
93static int my_pin_cmd(sc_card_t * card, struct sc_pin_cmd_data * data,
94                        int *tries_left)
95{
96        /* GemSAFE pin uses a null terminated string with 0xFF */
97        /* so we need to add the 0x00 to the pin  then pad with 0xFF */
98       
99        int r;
100        const u8 *saved_data = NULL;
101        int saved_len = 0;
102        u8  newpin[8];
103       
104        SC_FUNC_CALLED(card->ctx, 2);
105
106        memset(newpin, 0xff, sizeof(newpin));
107
108        if (data->pin1.data && data->pin1.len < 8 && data->pin1.len > 0) {
109                memcpy(newpin,data->pin1.data, (size_t)data->pin1.len);
110                newpin[data->pin1.len] = 0x00;
111               
112                sc_debug(card->ctx, "pin len=%d", data->pin1.len);
113
114                saved_data = data->pin1.data;
115                saved_len = data->pin1.len;
116                data->pin1.data = newpin;
117                data->pin1.len = sizeof(newpin);
118        }
119
120        r = pin_cmd_save(card, data, tries_left);
121
122        if (saved_data) {
123                data->pin1.data = saved_data;
124                data->pin1.len = saved_len;
125        }
126
127        SC_FUNC_RETURN(card->ctx, 2, r);
128}
129
130
131static int is_seq(unsigned char * seq, unsigned int *seq_size, unsigned int *seq_len)
132{
133        int i,j,k;
134
135        if (seq[0] != 0x30)
136                return 0;   /* not a sequence */
137        if (seq[1] & 0x80) {
138                i = seq[1] & 0x7f;
139                if (i > 2 || i == 0)
140                        return 0; /* cert would be bigger then 65k or zero */
141                if (seq[2] == 0)
142                        return 0; /* DER would not have extra zero */           
143                k = 0;
144                for (j = 0; j < i; j++) {
145                        k = (k << 8) + seq[j + 2];
146                }
147                if (k < 128)
148                        return 0; /* DER would have used single byte for len */
149        } else {
150                  i = 0;
151                  k = seq[1];
152        }
153       
154        *seq_size = i + 2;
155        *seq_len = k;
156        return 1;
157}
158
159static int gemsafe_detect_card(sc_pkcs15_card_t *p15card)
160{
161        sc_card_t *card = p15card->card;
162
163        SC_FUNC_CALLED(card->ctx, 1);
164
165
166        if (strcmp(card->name, "Gemplus GPK"))
167                return SC_ERROR_WRONG_CARD;
168       
169        return SC_SUCCESS;
170}
171
172static int sc_pkcs15emu_gemsafeGPK_init(sc_pkcs15_card_t *p15card)
173{
174        const cdata certs[] = {
175                {"User certificate",0, "","1", 0},
176                {NULL, 0, NULL, NULL, 0}
177        };
178
179        const pindata pins[] = {
180                { "1", "pin", "3F000200", 0x00,
181                  SC_PKCS15_PIN_TYPE_ASCII_NUMERIC,
182                  8, 4, 8, SC_PKCS15_PIN_FLAG_NEEDS_PADDING |
183                  SC_PKCS15_PIN_FLAG_LOCAL, -1, 0x00,
184                  SC_PKCS15_CO_FLAG_PRIVATE },
185                { NULL, NULL, NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0}
186        };
187
188        const prdata prkeys[] = {
189                { "1", "AUTH key", 1024, USAGE_AUT, "I0009",
190                  0x00, "1", 0},
191                { NULL, NULL, 0, 0, NULL, 0, NULL, 0}
192        };
193
194        int    r, i, j;
195        int dfpath;
196        sc_path_t path;
197        sc_file_t *file = NULL;
198        sc_card_t *card = p15card->card;
199        unsigned char *gsdata = NULL;
200        unsigned int idxlen, idx1, idx2, seq_len1, seq_len2, seq_size1, seq_size2;
201        sc_serial_number_t serial;
202
203        u8 sysrec[7];
204        int num_keyinfo = 0;
205        keyinfo kinfo[8]; /* will loook for 8 keys */
206        u8 modulus_buf[ 1 + 1024 / 8]; /* tag+modulus */
207        u8 *cp;
208        char buf[256];
209
210        SC_FUNC_CALLED(card->ctx, 1);
211
212        /* need to limit to 248 */
213        if (card->max_send_size > 248)
214                card->max_send_size = 248;
215        if (card->max_recv_size > 248)
216                card->max_recv_size = 248;
217
218
219        /* could read this off card if needed */
220
221        p15card->label = strdup("GemSAFE");
222        p15card->manufacturer_id = strdup(MANU_ID);
223        /* get serial number */
224        r = sc_card_ctl(card, SC_CARDCTL_GET_SERIALNR, &serial);
225        r = sc_bin_to_hex(serial.value, serial.len, buf, sizeof(buf), 0);
226        if (r != SC_SUCCESS)
227                return SC_ERROR_INTERNAL;
228        p15card->serial_number = strdup(buf);
229
230        /* test if we have a gemsafe app df */
231        memset(&path, 0, sizeof(path));
232        memcpy(path.value, gemsafe_aid, sizeof(gemsafe_aid));
233        path.len = sizeof(gemsafe_aid);
234        path.type = SC_PATH_TYPE_DF_NAME;
235        r = sc_select_file(card, &path, &file);
236        if (r < 0) {
237                /* OK, then lets try for 3f000200 */
238                sc_format_path("3F000200",&path);
239                path.type = SC_PATH_TYPE_PATH;
240                r = sc_select_file(card, &path, &file);
241        }
242
243        if (r < 0)
244                return SC_ERROR_WRONG_CARD;
245
246        /* we will use dfpath in all other references */
247        dfpath = file->id;
248        free(file);
249        file = NULL;
250
251        sc_debug(card->ctx, "GemSafe file found, id=%d",dfpath);
252
253        /* There may be more then one key in the directory. */
254        /* we need to find them so we can associate them with the */
255        /* the certificate.  The files are 0007 to 000f */
256
257        for (i = 7; i < 16; i++) {
258                path.value[0] = 0x00;
259                path.value[1] = i;
260                path.len = 2;   
261                path.type = SC_PATH_TYPE_FILE_ID;
262                sc_ctx_suppress_errors_on(card->ctx); /* file may not exist, and not an error */
263                r = sc_select_file(card, &path, NULL);
264                sc_ctx_suppress_errors_off(card->ctx);
265                if (r < 0)
266                        continue;
267                sc_ctx_suppress_errors_on(card->ctx);
268                r = sc_read_record(card, 1, sysrec, sizeof(sysrec), SC_RECORD_BY_REC_NR);
269                sc_ctx_suppress_errors_off(card->ctx);
270                if (r != 7 || sysrec[0] != 0) {
271                        continue;
272                }
273                if (sysrec[5] != 0x00) {
274                        continue;
275                }
276
277                switch (sysrec[1]) {
278                        case 0x00: kinfo[num_keyinfo].modulus_len =  512 / 8; break;
279                        case 0x10: kinfo[num_keyinfo].modulus_len =  768 / 8; break;
280                        case 0x11: kinfo[num_keyinfo].modulus_len = 1024 / 8; break;
281                        default:
282                                sc_error(card->ctx, "Unsupported modulus length");
283                                continue;
284                }
285
286                kinfo[num_keyinfo].fileid = i;
287                sc_pkcs15_format_id("NONE", &kinfo[num_keyinfo].id);
288
289                sc_debug(card->ctx,"reading modulus");
290                r = sc_read_record(card, 2, modulus_buf,
291                                kinfo[num_keyinfo].modulus_len+1, SC_RECORD_BY_REC_NR);
292                if (r < 0)
293                        continue;
294                       
295                /* need to reverse the modulus skiping the tag */
296                j = kinfo[num_keyinfo].modulus_len;
297                cp = kinfo[num_keyinfo].modulus;
298                while (j--)
299                        *cp++ =  modulus_buf[j + 1];
300                num_keyinfo++;
301        }
302
303        /* Get the gemsafe data with the cert */
304         sc_format_path("3F000200004", &path);
305
306        /* file.id has the real DF of the GemSAFE file from above*/
307         path.value[2] = dfpath >> 8;
308         path.value[3] = dfpath & 0xff;
309       
310        if (sc_select_file(card, &path, &file) < 0) {
311                return SC_ERROR_WRONG_CARD;
312        }
313
314        /* the GemSAFE file has our cert, but we do not know the format */
315        /* of the file. But we do know a cert has SEQ SEQ SEQOF INT 2   */
316        /* so we will look for that. We assume cert is larger then 127 bytes */
317        /* and less then 65K, and must be fit in the file->size */
318        /* There is a chance that we might find something that is not */
319        /* a cert, but the chances are low. If GemPlus ever publishes */
320        /* the format of the file, we can used that instead. */ 
321
322        /* For performance reasons we will only */
323        /* read part of the file , as it is about 6100 bytes */
324
325        gsdata = (unsigned char *) malloc(file->size);
326
327        if (!gsdata)
328                return SC_ERROR_OUT_OF_MEMORY;
329
330        /* set indcies of data in gsdata  */
331        idx1 = 0; /* start point */
332        idx2 = 0; /* index of last data read so far */
333
334
335        /* set certs  We only have one we are interested in */
336        /* but the read loop is set up to allow for more in future */
337
338        for (i = 0; certs[i].label; i++) {
339                struct sc_pkcs15_cert_info cert_info;
340                struct sc_pkcs15_object    cert_obj;
341                sc_pkcs15_cert_t                *cert_out;
342
343                memset(&cert_info, 0, sizeof(cert_info));
344                memset(&cert_obj,  0, sizeof(cert_obj));
345
346                sc_pkcs15_format_id(certs[i].id, &cert_info.id);
347                cert_info.authority = certs[i].authority;
348
349                strlcpy(cert_obj.label, certs[i].label, sizeof(cert_obj.label));
350                cert_obj.flags = certs[i].obj_flags;
351
352                while (idx1 < file->size - 16) { /* actually 13 for all these tests */
353                        if (idx1 + 16 > idx2 ) {        /* need more data in buff */
354                                idxlen = 248;           /* read in next 248 bytes */
355                                if (idxlen > file->size - idx2)
356                                        idxlen = file->size - idx2;
357                                r = sc_read_binary(card, idx2, gsdata + idx2, idxlen, 0);
358                                if (r < 0)
359                                        break;
360                                idx2 = idx2 + idxlen;
361                        }
362
363                        if ( gsdata[idx1] == 0x30 &&
364                                is_seq(gsdata + idx1, &seq_size1, &seq_len1) &&
365                                is_seq(gsdata + idx1 + seq_size1, &seq_size2, &seq_len2) &&
366                            gsdata[idx1 + seq_size1 + seq_size2 + 0] == 0xa0 &&
367                                gsdata[idx1 + seq_size1 + seq_size2 + 1] == 0x03 &&
368                                gsdata[idx1 + seq_size1 + seq_size2 + 2] == 0x02 &&
369                                gsdata[idx1 + seq_size1 + seq_size2 + 3] == 0x01 &&
370                                gsdata[idx1 + seq_size1 + seq_size2 + 4] == 0x02 &&
371                                idx1 + 4 + seq_len1 < file->size) {
372                                /* we have a cert (I hope) */
373                                /* read in rest if needed */
374                                idxlen = idx1 + seq_len1 + 4 - idx2;
375                                if (idxlen > 0) {
376                                        idxlen = (idxlen + 3) & 0xfffffffc; 
377                                        r = sc_read_binary(card, idx2, gsdata + idx2, idxlen, 0);
378                                        if (r < 0)
379                                                break; /* can not read cert */
380                                        idx2 = idx2 + idxlen;
381                                }
382                                cert_info.value.len = seq_len1 + 4;
383                                sc_debug(card->ctx, "Found cert at offset %d", idx1);
384                                cert_info.value.value = (unsigned char *)
385                                                malloc(cert_info.value.len);
386                                if (!cert_info.value.value)
387                                        return SC_ERROR_OUT_OF_MEMORY;
388
389                                memcpy(cert_info.value.value, gsdata + idx1, cert_info.value.len);
390                        idx1 = idx1 + cert_info.value.len;
391                                break;
392                        }
393                        idx1++;
394                }
395               
396                if (cert_info.value.value == NULL)
397                        break; /* cert not found, no more certs */
398
399                r = sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
400                if (r < 0) {
401                        free(gsdata);
402                        return SC_ERROR_INTERNAL;
403                }
404
405                /* now lets see if we have a matching key for this cert */
406               
407                r = sc_pkcs15_read_certificate(p15card, &cert_info, &cert_out);
408                if (r < 0) {
409                        free(gsdata);
410                        return SC_ERROR_INTERNAL;
411                }
412
413                for (j = 0; j < num_keyinfo; j++) {
414                        if (cert_out->key.u.rsa.modulus.len == kinfo[j].modulus_len && 
415                                        memcmp(cert_out->key.u.rsa.modulus.data,
416                                        &kinfo[j].modulus, cert_out->key.u.rsa.modulus.len) == 0) {
417                        memcpy(&kinfo[j].id, &cert_info.id, sizeof(sc_pkcs15_id_t));
418                        sc_debug(card->ctx, "found match");
419                        }
420                }
421                sc_pkcs15_free_certificate(cert_out);
422        }
423
424        if (gsdata)
425                free(gsdata);
426
427        /* set pins */
428
429        /* GemSAFE uses different padding, so need to trap */
430        /* the pin_cmd and reset the padding */
431
432        pin_cmd_save = card->ops->pin_cmd;
433        card->ops->pin_cmd = my_pin_cmd;
434
435        for (i = 0; pins[i].label; i++) {
436                struct sc_pkcs15_pin_info pin_info;
437                struct sc_pkcs15_object   pin_obj;
438
439                memset(&pin_info, 0, sizeof(pin_info));
440                memset(&pin_obj,  0, sizeof(pin_obj));
441
442                sc_pkcs15_format_id(pins[i].id, &pin_info.auth_id);
443                pin_info.reference     = pins[i].ref;
444                pin_info.flags         = pins[i].flags;
445                pin_info.type          = pins[i].type;
446                pin_info.min_length    = pins[i].minlen;
447                pin_info.stored_length = pins[i].storedlen;
448                pin_info.max_length    = pins[i].maxlen;
449                pin_info.pad_char      = pins[i].pad_char;
450                sc_format_path(pins[i].path, &pin_info.path);
451                pin_info.path.value[2] = dfpath >> 8;
452                pin_info.path.value[3] = dfpath & 0xff;
453                pin_info.tries_left    = -1;
454
455                strlcpy(pin_obj.label, pins[i].label, sizeof(pin_obj.label));
456                pin_obj.flags = pins[i].obj_flags;
457
458                r = sc_pkcs15emu_add_pin_obj(p15card, &pin_obj, &pin_info);
459                if (r < 0)
460                        return SC_ERROR_INTERNAL;
461        }
462
463        /* needs work, as we may want to add more then one key */
464        /* but not sure what the other keys do */
465
466        /* set private keys */
467        for (i = 0; prkeys[i].label; i++) {
468                struct sc_pkcs15_prkey_info prkey_info;
469                struct sc_pkcs15_object     prkey_obj;
470
471                memset(&prkey_info, 0, sizeof(prkey_info));
472                memset(&prkey_obj,  0, sizeof(prkey_obj));
473
474                sc_pkcs15_format_id(prkeys[i].id, &prkey_info.id);
475                prkey_info.usage         = prkeys[i].usage;
476                prkey_info.native        = 1;
477                prkey_info.key_reference = prkeys[i].ref;
478                prkey_info.modulus_length= prkeys[i].modulus_len;
479                sc_format_path(prkeys[i].path, &prkey_info.path);
480
481                /*DEE need to look for them by reading and checking mudulus vs cert */
482
483                /* will use the default path, unless we found a key with */
484                /* the same modulus as the cert(s) we already added */
485                /* This allows us to have a card with a key but no cert */
486       
487                for (j = 0; j < num_keyinfo; j++) {
488                        if (sc_pkcs15_compare_id(&kinfo[j].id, &prkey_info.id))  {
489                                sc_debug(card->ctx, "found key in file %d for id %d",
490                                                kinfo[j].fileid, prkey_info.id);
491                                prkey_info.path.value[0] = kinfo[j].fileid >> 8;
492                                prkey_info.path.value[1] = kinfo[j].fileid & 0xff;
493                                break;
494                        }
495                }
496
497                strlcpy(prkey_obj.label, prkeys[i].label, sizeof(prkey_obj.label));
498                prkey_obj.flags = prkeys[i].obj_flags;
499                if (prkeys[i].auth_id)
500                        sc_pkcs15_format_id(prkeys[i].auth_id, &prkey_obj.auth_id);
501
502                r = sc_pkcs15emu_add_rsa_prkey(p15card, &prkey_obj, &prkey_info);
503                if (r < 0)
504                        return SC_ERROR_INTERNAL;
505        }
506        return SC_SUCCESS;
507}
508
509int sc_pkcs15emu_gemsafeGPK_init_ex(sc_pkcs15_card_t *p15card,
510                                  sc_pkcs15emu_opt_t *opts)
511{
512        sc_card_t   *card = p15card->card;
513        sc_context_t    *ctx = card->ctx;
514
515        sc_debug(ctx, "Entering %s", __FUNCTION__);
516
517        if (opts && opts->flags & SC_PKCS15EMU_FLAGS_NO_CHECK)
518                return sc_pkcs15emu_gemsafeGPK_init(p15card);
519        else {
520                int r = gemsafe_detect_card(p15card);
521                if (r)
522                        return SC_ERROR_WRONG_CARD;
523                return sc_pkcs15emu_gemsafeGPK_init(p15card);
524        }
525}
Note: See TracBrowser for help on using the browser.