root/trunk/src/libopensc/card-gemsafeV1.c

Revision 3563, 16.9 kB (checked in by alonbl, 2 months ago)

Fix for two apparent C code bugs

By Stanislav Brabec

entersafe_init_pin_info() was declared as int, but defined and used as
void, resulting in a function returning an unused pseudo-random value.

card-gemsafeV1.c uses comparison 'type == "DF"', which is always false,
as it compares pointer to a string with pointer to the string "DF" in
the code.

Line 
1/*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
15*/
16
17/* Initially written by David Mattes (david.mattes@boeing.com) */
18
19#include "internal.h"
20#include "cardctl.h"
21#include "asn1.h"
22#include <stdlib.h>
23#include <string.h>
24
25static struct sc_card_operations gemsafe_ops;
26static struct sc_card_operations *iso_ops = NULL;
27
28static struct sc_card_driver gemsafe_drv = {
29        "driver for the Gemplus GemSAFE V1 applet",
30        "gemsafeV1",
31        &gemsafe_ops,
32        NULL, 0, NULL
33};
34
35static const char *gemexpresso_atrs[] = {
36        /* standard version    */
37        "3B:7B:94:00:00:80:65:B0:83:01:01:74:83:00:90:00",
38        "3B:6B:00:00:80:65:B0:83:01:01:74:83:00:90:00",
39        /* fips 140 version    */
40        "3B:6B:00:00:80:65:B0:83:01:03:74:83:00:90:00",
41        /* TODO: add more ATRs */
42        "3B:7A:94:00:00:80:65:A2:01:01:01:3D:72:D6:43",
43        "3B:7D:94:00:00:80:31:80:65:B0:83:01:01:90:83:00:90:00",
44        NULL
45};
46
47static const u8 gemsafe_def_aid[] = {0xA0, 0x00, 0x00, 0x00, 0x18, 0x0A,
48        0x00, 0x00, 0x01, 0x63, 0x42, 0x00};
49/*
50static const u8 gemsafe_def_aid[] = {0xA0, 0x00, 0x00, 0x00, 0x63, 0x50,
51        0x4B, 0x43, 0x53, 0x2D, 0x31, 0x35};
52*/
53
54typedef struct gemsafe_exdata_st {
55        u8      aid[16];
56        size_t  aid_len;
57} gemsafe_exdata;
58
59static int get_conf_aid(sc_card_t *card, u8 *aid, size_t *len)
60{
61        sc_context_t            *ctx = card->ctx;
62        scconf_block            *conf_block, **blocks;
63        int                     i;
64        const char              *str_aid;
65
66        SC_FUNC_CALLED(ctx, 1);
67
68        conf_block = NULL;
69        for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
70                blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i],
71                                                "card", "gemsafeV1");
72                if (blocks[0] != NULL)
73                        conf_block = blocks[0];
74                free(blocks);
75        }
76
77        if (!conf_block) {
78                sc_debug(ctx, "no card specific options configured, trying default AID\n");
79                return SC_ERROR_INTERNAL;
80        }
81
82        str_aid = scconf_get_str(conf_block, "aid", NULL);
83        if (!str_aid) {
84                sc_debug(ctx, "no aid configured, trying default AID\n");
85                return SC_ERROR_INTERNAL;
86        }
87        return sc_hex_to_bin(str_aid, aid, len);
88}
89
90static int gp_select_applet(sc_card_t *card, const u8 *aid, size_t aid_len)
91{
92        int     r;
93        u8      buf[SC_MAX_APDU_BUFFER_SIZE];
94        struct sc_context *ctx = card->ctx;
95        struct sc_apdu    apdu;
96
97        SC_FUNC_CALLED(ctx, 1);
98
99        sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0xa4, 0x04, 0x00);
100        apdu.lc      = aid_len;
101        apdu.data    = aid;
102        apdu.datalen = aid_len;
103        apdu.resp    = buf;
104        apdu.le      = 256;
105        apdu.resplen = sizeof(buf);
106
107        r = sc_transmit_apdu(card, &apdu);
108        SC_TEST_RET(ctx, r, "APDU transmit failed");
109        r = sc_check_sw(card, apdu.sw1, apdu.sw2);
110        if (r)
111                SC_FUNC_RETURN(ctx, 2, r);
112
113        return SC_SUCCESS;
114}
115
116static int gemsafe_match_card(struct sc_card *card)
117{
118        int i, match = -1;
119
120        SC_FUNC_CALLED(card->ctx, 1);
121
122        for (i = 0; gemexpresso_atrs[i] != NULL; i++) {
123                u8 defatr[SC_MAX_ATR_SIZE];
124                size_t len = sizeof(defatr);
125                const char *atrp = gemexpresso_atrs[i];
126
127                if (sc_hex_to_bin(atrp, defatr, &len))
128                        continue;
129                if (len != card->atr_len)
130                        continue;
131                if (memcmp(card->atr, defatr, len) != 0)
132                        continue;
133                match = i + 1;
134                break;
135        }
136        if (match == -1)
137                return 0;
138
139        return 1;
140}
141
142static int gemsafe_init(struct sc_card *card)
143{
144        int     r;
145        gemsafe_exdata *exdata = NULL;
146
147        SC_FUNC_CALLED(card->ctx, 1);
148
149        card->name = "GemSAFE V1";
150        card->cla  = 0x00;
151
152        exdata = (gemsafe_exdata *)calloc(1, sizeof(gemsafe_exdata));
153        if (!exdata)
154                return SC_ERROR_OUT_OF_MEMORY;
155        exdata->aid_len = sizeof(exdata->aid);
156        /* try to get a AID from the config file */
157        r = get_conf_aid(card, exdata->aid, &exdata->aid_len);
158        if (r < 0) {
159                /* failed, use default value */
160                memcpy(exdata->aid, gemsafe_def_aid, sizeof(gemsafe_def_aid));
161                exdata->aid_len = sizeof(gemsafe_def_aid);
162        }
163
164        /* increase lock_count here to prevent sc_unlock to select
165         * applet twice in gp_select_applet */
166        card->lock_count++;
167        /* SELECT applet */
168        r = gp_select_applet(card, exdata->aid, exdata->aid_len);
169        if (r < 0) {
170                free(exdata);
171                sc_debug(card->ctx, "applet selection failed\n");
172                return SC_ERROR_INTERNAL;
173        }
174        card->lock_count--;
175
176        /* set the supported algorithm */
177        r = gemsafe_match_card(card);
178        if (r > 0) {
179                unsigned long flags;
180
181                flags  = SC_ALGORITHM_RSA_PAD_PKCS1;
182                flags |= SC_ALGORITHM_RSA_PAD_ISO9796;
183                flags |= SC_ALGORITHM_ONBOARD_KEY_GEN;
184                flags |= SC_ALGORITHM_RSA_HASH_NONE;
185
186                _sc_card_add_rsa_alg(card,  512, flags, 0);
187                _sc_card_add_rsa_alg(card,  768, flags, 0);
188                _sc_card_add_rsa_alg(card, 1024, flags, 0);
189                _sc_card_add_rsa_alg(card, 2048, flags, 0);
190        }
191
192        card->drv_data = exdata;
193
194        return 0;
195}
196
197static int gemsafe_finish(sc_card_t *card)
198{
199        gemsafe_exdata *exdata = (gemsafe_exdata *)card->drv_data;
200
201        if (exdata)
202                free(exdata);
203        return SC_SUCCESS;
204}
205
206static int gemsafe_select_file(struct sc_card *card, const struct sc_path *path,
207           struct sc_file **file_out)
208{
209        /* so far just call the iso select file (but this will change) */
210        SC_FUNC_CALLED(card->ctx, 1);
211
212        return iso_ops->select_file(card, path, file_out);
213}
214
215static int gemsafe_sc2acl(sc_file_t *file, unsigned ops, u8 sc_byte)
216{
217        int r;
218        unsigned int meth = 0;
219
220        if (sc_byte == 0xff) {
221                r = sc_file_add_acl_entry(file, ops, SC_AC_NEVER, 0);
222                return r;
223        }
224        if (sc_byte == 0x00) {
225                r = sc_file_add_acl_entry(file, ops, SC_AC_NONE, 0);
226                return r;
227        }
228
229        /* XXX: OR combination of access rights are currently not supported
230         * hence ignored */
231        if (sc_byte & 0x40)
232                meth |= SC_AC_PRO;
233        if (sc_byte & 0x20)
234                meth |= SC_AC_AUT | SC_AC_TERM;
235        if (sc_byte & 0x10)
236                meth |= SC_AC_CHV;
237
238        return sc_file_add_acl_entry(file, ops, meth, sc_byte & 0x0f);
239}
240
241static int gemsafe_setacl(sc_card_t *card, sc_file_t *file, const u8 *data,
242        int is_df)
243{
244        int       r;
245        u8        cond;
246        const u8 *p = data + 1;
247        struct sc_context *ctx = card->ctx;
248
249        if (is_df) {
250                if (*data & 0x04)       /* CREATE DF */
251                        cond = *p++;
252                else
253                        cond = 0xff;
254                if(ctx->debug >= 3)
255                        sc_debug(ctx, "DF security byte CREATE DF: %02x\n", cond);
256                r = gemsafe_sc2acl(file, SC_AC_OP_CREATE, cond);
257                if (r < 0)
258                        return r;
259                if (*data & 0x02)       /* CREATE EF */
260                        cond = *p;
261                else
262                        cond = 0xff;
263                if(ctx->debug >= 3)
264                        sc_debug(ctx, "DF security byte CREATE EF: %02x\n", cond);
265                /* XXX: opensc doesn't currently separate access conditions for
266                 * CREATE EF and CREATE DF, this should be changed */
267                r = gemsafe_sc2acl(file, SC_AC_OP_CREATE, cond);
268                if (r < 0)
269                        return r;
270        } else {
271                /* XXX: ACTIVATE FILE and DEACTIVATE FILE ac are currently not
272                 * supported => ignore them */
273                if (*data & 0x02)       /* UPDATE BINARY, ERASE BINARY */
274                        cond = *p++;
275                else
276                        cond = 0xff;
277                if(ctx->debug >= 3)
278                        sc_debug(ctx, "EF security byte UPDATE/ERASE BINARY: %02x\n", cond);
279                r = gemsafe_sc2acl(file, SC_AC_OP_UPDATE, cond);
280                if (r < 0)
281                        return r;
282                r = gemsafe_sc2acl(file, SC_AC_OP_WRITE, cond);
283                if (r < 0)
284                        return r;
285                r = gemsafe_sc2acl(file, SC_AC_OP_ERASE, cond);
286                if (r < 0)
287                        return r;
288                if (*data & 0x01)       /* READ BINARY */
289                        cond = *p;
290                else
291                        cond = 0xff;
292                if(ctx->debug >= 3)
293                        sc_debug(ctx, "EF security byte READ BINARY: %02x\n", cond);
294                r = gemsafe_sc2acl(file, SC_AC_OP_READ, cond);
295                if (r < 0)
296                        return r;
297        }
298
299        return SC_SUCCESS;
300}
301
302static int gemsafe_process_fci(struct sc_card *card, struct sc_file *file,
303        const u8 *buf, size_t len)
304{
305        int        r;
306        size_t     tlen;
307        const u8   *tag = NULL, *p = buf;
308        const char *type;
309        struct sc_context *ctx = card->ctx;
310
311        SC_FUNC_CALLED(ctx, 1);
312
313        r = iso_ops->process_fci(card, file, buf, len);
314        if (r < 0)
315                return r;
316        if (ctx->debug >= 3)
317                sc_debug(ctx, "processing GemSAFE V1 specific FCI information\n");
318
319
320        tag = sc_asn1_find_tag(ctx, p, len, 0x82, &tlen);
321        if (!tag) {
322                /* no FDB => we have a DF */
323                type = "DF";
324                file->type = SC_FILE_TYPE_DF;
325        } else {
326                type = "EF";
327                file->type = SC_FILE_TYPE_WORKING_EF;
328        }
329
330        if (ctx->debug >= 3)
331                sc_debug(ctx, "file type: %s\n", type);
332
333        tag = sc_asn1_find_tag(ctx, p, len, 0x8C, &tlen);
334        if (tag) {
335                r = gemsafe_setacl(card, file, tag, strcmp(type, "DF") ? 0 : 1);
336                if (r < 0) {
337                        sc_debug(ctx, "unable to set ACL\n");
338                        return SC_ERROR_INTERNAL;
339                }
340        } else
341                sc_debug(ctx, "error: AM and SC bytes missing\n");
342
343        return SC_SUCCESS;
344}
345
346static u8 gemsafe_flags2algref(const struct sc_security_env *env)
347{
348        u8 ret = 0;
349
350        if (env->operation == SC_SEC_OPERATION_SIGN) {
351                if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1)
352                        ret = 0x12;
353                else if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_ISO9796)
354                        ret = 0x11;
355        } else if (env->operation == SC_SEC_OPERATION_DECIPHER) {
356                if (env->algorithm_flags & SC_ALGORITHM_RSA_PAD_PKCS1)
357                        ret = 0x12;
358        }
359
360        return ret;
361}
362
363static int gemsafe_restore_security_env(struct sc_card *card, int se_num)
364{
365        int r;
366        struct sc_apdu apdu;
367
368        SC_FUNC_CALLED(card->ctx, 1);
369
370        sc_format_apdu(card, &apdu, SC_APDU_CASE_1, 0x22, 0x73, (u8) se_num);
371
372        r = sc_transmit_apdu(card, &apdu);
373        SC_TEST_RET(card->ctx, r, "APDU transmit failed");
374
375        return sc_check_sw(card, apdu.sw1, apdu.sw2);
376}
377
378
379static int gemsafe_set_security_env(struct sc_card *card,
380                                    const struct sc_security_env *env,
381                                    int se_num)
382{
383        int r;
384        struct sc_apdu apdu;
385        u8 sbuf[SC_MAX_APDU_BUFFER_SIZE], *p = sbuf;
386        u8 alg_ref = 0;
387        struct sc_context *ctx = card->ctx;
388
389        SC_FUNC_CALLED(ctx, 1);
390
391        sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x22, 0x41, 0);
392        switch (env->operation) {
393        case SC_SEC_OPERATION_DECIPHER:
394                apdu.p2 = 0xB8;
395                break;
396        case SC_SEC_OPERATION_SIGN:
397                apdu.p2 = 0xB6;
398                break;
399        default:
400                return SC_ERROR_INVALID_ARGUMENTS;
401        }
402        apdu.le = 0;
403
404        /* first step: set the algorithm reference */
405        if (env->flags & SC_SEC_ENV_ALG_REF_PRESENT)
406                alg_ref = env->algorithm_ref & 0xFF;
407        else
408                alg_ref = gemsafe_flags2algref(env);
409        if (alg_ref) {
410                        /* set the algorithm reference */
411                *p++ = 0x80;
412                *p++ = 0x01;
413                *p++ = alg_ref;
414        } else
415                sc_debug(ctx, "unknown algorithm flags '%x'\n", env->algorithm_flags);
416        /* second step: set the key reference */
417        if (env->flags & SC_SEC_ENV_KEY_REF_PRESENT) {
418                /* set the key reference */
419                if (env->flags & SC_SEC_ENV_KEY_REF_ASYMMETRIC)
420                        *p++ = 0x83;
421                else
422                        *p++ = 0x84;
423                *p++ = env->key_ref_len;
424                memcpy(p, env->key_ref, env->key_ref_len);
425                p += env->key_ref_len;
426        }
427
428
429        r = p - sbuf;
430        apdu.lc = r;
431        apdu.datalen = r;
432        apdu.data = sbuf;
433        apdu.resplen = 0;
434
435        r = sc_transmit_apdu(card, &apdu);
436        SC_TEST_RET(card->ctx, r, "APDU transmit failed");
437        return sc_check_sw(card, apdu.sw1, apdu.sw2);
438}
439
440static int gemsafe_compute_signature(struct sc_card *card, const u8 * data,
441        size_t data_len, u8 * out, size_t outlen)
442{
443        int r;
444        struct sc_apdu apdu;
445        u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
446        u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
447        sc_context_t *ctx = card->ctx;
448
449        SC_FUNC_CALLED(ctx, 1);
450
451        if (data_len > 36) {
452                sc_debug(ctx, "error: input data too long: %lu bytes\n", data_len);
453                return SC_ERROR_INVALID_ARGUMENTS;
454        }
455
456        sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x9E, 0xAC);
457        apdu.cla |= 0x80;
458        apdu.resp = rbuf;
459        apdu.resplen = sizeof(rbuf);
460        apdu.le      = 256;
461        /* we sign a digestInfo object => tag 0x90 */
462        sbuf[0] = 0x90;
463        sbuf[1] = (u8)data_len;
464        memcpy(sbuf + 2, data, data_len);
465        apdu.data = sbuf;
466        apdu.lc   = data_len + 2;
467        apdu.datalen = data_len + 2;
468        apdu.sensitive = 1;
469
470        r = sc_transmit_apdu(card, &apdu);
471        SC_TEST_RET(card->ctx, r, "APDU transmit failed");
472        if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
473                int len = apdu.resplen > outlen ? outlen : apdu.resplen;
474
475                memcpy(out, apdu.resp, len);
476                SC_FUNC_RETURN(card->ctx, 4, len);
477        }
478        SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2));
479}
480
481static int gemsafe_decipher(struct sc_card *card, const u8 * crgram,
482        size_t crgram_len, u8 *out, size_t outlen)
483{
484        int r;
485        struct sc_apdu apdu;
486        u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
487        sc_context_t *ctx = card->ctx;
488
489        SC_FUNC_CALLED(ctx, 1);
490        if (crgram_len > 255)
491                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_INVALID_ARGUMENTS);
492
493        sc_format_apdu(card, &apdu, SC_APDU_CASE_4_SHORT, 0x2A, 0x80, 0x84);
494        apdu.cla |= 0x80;
495        apdu.resp = rbuf;
496        apdu.resplen = sizeof(rbuf);
497        apdu.le      = crgram_len;
498        apdu.sensitive = 1;
499
500        apdu.data = crgram;
501        apdu.lc   = crgram_len;
502        apdu.datalen = crgram_len;
503        r = sc_transmit_apdu(card, &apdu);
504        SC_TEST_RET(card->ctx, r, "APDU transmit failed");
505        if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00) {
506                int len = apdu.resplen > outlen ? outlen : apdu.resplen;
507
508                memcpy(out, apdu.resp, len);
509                SC_FUNC_RETURN(card->ctx, 2, len);
510        }
511        SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2));
512}
513
514static int gemsafe_build_pin_apdu(struct sc_card *card,
515                struct sc_apdu *apdu,
516                struct sc_pin_cmd_data *data)
517{
518        static u8 sbuf[SC_MAX_APDU_BUFFER_SIZE];
519        int r, len = 0, pad = 0, use_pin_pad = 0, ins, p1 = 0;
520
521        switch (data->pin_type) {
522        case SC_AC_CHV:
523                break;
524        default:
525                return SC_ERROR_INVALID_ARGUMENTS;
526        }
527
528        if (data->flags & SC_PIN_CMD_NEED_PADDING)
529                pad = 1;
530        if (data->flags & SC_PIN_CMD_USE_PINPAD)
531                use_pin_pad = 1;
532
533        data->pin1.offset = 5;
534
535        switch (data->cmd) {
536        case SC_PIN_CMD_VERIFY:
537                ins = 0x20;
538                if ((r = sc_build_pin(sbuf, sizeof(sbuf), &data->pin1, pad)) < 0)
539                        return r;
540                len = r;
541                break;
542        case SC_PIN_CMD_CHANGE:
543                ins = 0x24;
544                if (data->pin1.len != 0 || use_pin_pad) {
545                        if ((r = sc_build_pin(sbuf, sizeof(sbuf), &data->pin1, pad)) < 0)
546                                return r;
547                        len += r;
548                } else {
549                        /* implicit test */
550                        p1 = 1;
551                }
552
553                data->pin2.offset = data->pin1.offset + len;
554                if ((r = sc_build_pin(sbuf+len, sizeof(sbuf)-len, &data->pin2, pad)) < 0)
555                        return r;
556                len += r;
557                break;
558        case SC_PIN_CMD_UNBLOCK:
559                ins = 0x2C;
560                if (data->pin1.len != 0 || use_pin_pad) {
561                        if ((r = sc_build_pin(sbuf, sizeof(sbuf), &data->pin1, pad)) < 0)
562                                return r;
563                        len += r;
564                } else {
565                        p1 |= 0x02;
566                }
567
568                if (data->pin2.len != 0 || use_pin_pad) {
569                        data->pin2.offset = data->pin1.offset + len;
570                        if ((r = sc_build_pin(sbuf+len, sizeof(sbuf)-len, &data->pin2, pad)) < 0)
571                                return r;
572                        len += r;
573                } else {
574                        p1 |= 0x01;
575                }
576                break;
577        default:
578                return SC_ERROR_NOT_SUPPORTED;
579        }
580
581        sc_format_apdu(card, apdu, SC_APDU_CASE_3_SHORT,
582                                ins, p1, data->pin_reference);
583
584        apdu->lc = len;
585        apdu->datalen = len;
586        apdu->data = sbuf;
587        apdu->resplen = 0;
588        apdu->sensitive = 1;
589
590        return 0;
591}
592
593static int gemsafe_pin_cmd(struct sc_card *card, struct sc_pin_cmd_data *data,
594                           int *tries_left)
595{
596        struct sc_apdu local_apdu, *apdu;
597        int r;
598
599        if (tries_left)
600                *tries_left = -1;
601
602        /* See if we've been called from another card driver, which is
603         * passing an APDU to us (this allows to write card drivers
604         * whose PIN functions behave "mostly like ISO" except in some
605         * special circumstances.
606         */
607        if (data->apdu == NULL) {
608                r = gemsafe_build_pin_apdu(card, &local_apdu, data);
609                if (r < 0)
610                        return r;
611                data->apdu = &local_apdu;
612        }
613        apdu = data->apdu;
614
615        if (!(data->flags & SC_PIN_CMD_USE_PINPAD)) {
616                /* Transmit the APDU to the card */
617                r = sc_transmit_apdu(card, apdu);
618
619                /* Clear the buffer - it may contain pins */
620                memset((void *) apdu->data, 0, apdu->datalen);
621        } else {
622                /* Call the reader driver to collect
623                 * the PIN and pass on the APDU to the card */
624                if (data->pin1.offset == 0) {
625                        sc_error(card->ctx,
626                                "Card driver didn't set PIN offset");
627                        return SC_ERROR_INVALID_ARGUMENTS;
628                }
629                if (card->reader
630                 && card->reader->ops
631                 && card->reader->ops->perform_verify) {
632                        r = card->reader->ops->perform_verify(card->reader,
633                                        card->slot,
634                                        data);
635                        /* sw1/sw2 filled in by reader driver */
636                } else {
637                        sc_error(card->ctx,
638                                "Card reader driver does not support "
639                                "PIN entry through reader key pad");
640                        r = SC_ERROR_NOT_SUPPORTED;
641                }
642        }
643
644        /* Don't pass references to local variables up to the caller. */
645        if (data->apdu == &local_apdu)
646                data->apdu = NULL;
647
648        SC_TEST_RET(card->ctx, r, "APDU transmit failed");
649        if (apdu->sw1 == 0x63) {
650                if ((apdu->sw2 & 0xF0) == 0xC0 && tries_left != NULL)
651                        *tries_left = apdu->sw2 & 0x0F;
652                return SC_ERROR_PIN_CODE_INCORRECT;
653        }
654        return sc_check_sw(card, apdu->sw1, apdu->sw2);
655}
656
657static struct sc_card_driver *sc_get_driver(void)
658{
659        struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
660        if (!iso_ops)
661                iso_ops = iso_drv->ops;
662        /* use the standard iso operations as default */
663        gemsafe_ops = *iso_drv->ops;
664        /* gemsafe specfic functions */
665        gemsafe_ops.match_card  = gemsafe_match_card;
666        gemsafe_ops.init        = gemsafe_init;
667        gemsafe_ops.finish      = gemsafe_finish;
668        gemsafe_ops.select_file = gemsafe_select_file;
669        gemsafe_ops.restore_security_env = gemsafe_restore_security_env;
670        gemsafe_ops.set_security_env     = gemsafe_set_security_env;
671        gemsafe_ops.decipher             = gemsafe_decipher;
672        gemsafe_ops.compute_signature    = gemsafe_compute_signature;
673        gemsafe_ops.process_fci = gemsafe_process_fci;
674        gemsafe_ops.pin_cmd              = gemsafe_pin_cmd;
675
676        return &gemsafe_drv;
677}
678
679struct sc_card_driver *sc_get_gemsafeV1_driver(void)
680{
681        return sc_get_driver();
682}
Note: See TracBrowser for help on using the browser.