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

Revision 3085, 3.5 KB (checked in by aj, 2 years ago)

convert to utf-8.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * card-default.c: Support for cards with no driver
3 *
4 * Copyright (C) 2001, 2002  Juha YrjölÀ <juha.yrjola@iki.fi>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21#include "internal.h"
22#include <string.h>
23
24static struct sc_card_operations default_ops;
25static struct sc_card_driver default_drv = {
26        "Default driver for unknown cards",
27        "default",
28        &default_ops,
29        NULL, 0, NULL
30};
31
32static int default_finish(sc_card_t *card)
33{
34        return 0;
35}
36
37static int default_match_card(sc_card_t *card)
38{
39        return 1;               /* always match */
40}
41
42static int autodetect_class(sc_card_t *card)
43{
44        int classes[] = { 0x00, 0xC0, 0xB0, 0xA0 };
45        int class_count = sizeof(classes)/sizeof(int);
46        u8 rbuf[SC_MAX_APDU_BUFFER_SIZE];
47        sc_apdu_t apdu;
48        int i, r;
49
50        if (card->ctx->debug >= 2)
51                sc_debug(card->ctx, "autodetecting CLA byte\n");
52        for (i = 0; i < class_count; i++) {
53                if (card->ctx->debug >= 2)
54                        sc_debug(card->ctx, "trying with 0x%02X\n", classes[i]);
55                memset(&apdu, 0, sizeof(apdu));
56                apdu.cla = classes[i];
57                apdu.cse = SC_APDU_CASE_2_SHORT;
58                apdu.ins = 0xC0;
59                apdu.p1 = apdu.p2 = 0;
60                apdu.datalen = 0;
61                apdu.lc = 0;
62                apdu.le = 256;
63                apdu.resp = rbuf;
64                apdu.resplen = sizeof(rbuf);
65                r = sc_transmit_apdu(card, &apdu);
66                SC_TEST_RET(card->ctx, r, "APDU transmit failed");
67                if (apdu.sw1 == 0x6E)
68                        continue;
69                if (apdu.sw1 == 0x90 && apdu.sw2 == 0x00)
70                        break;
71                if (apdu.sw1 == 0x61)
72                        break;
73                if (card->ctx->debug >= 2)
74                        sc_debug(card->ctx, "got strange SWs: 0x%02X 0x%02X\n",
75                              apdu.sw1, apdu.sw2);
76                break;
77        }
78        if (i == class_count)
79                return -1;
80        card->cla = classes[i];
81        if (card->ctx->debug >= 2)
82                sc_debug(card->ctx, "detected CLA byte as 0x%02X\n", card->cla);
83        if (apdu.resplen < 2) {
84                if (card->ctx->debug >= 2)
85                        sc_debug(card->ctx, "SELECT FILE returned %d bytes\n",
86                              apdu.resplen);
87                return 0;
88        }
89        if (rbuf[0] == 0x6F) {
90                if (card->ctx->debug >= 2)
91                        sc_debug(card->ctx, "SELECT FILE seems to behave according to ISO 7816-4\n");
92                return 0;
93        }
94        if (rbuf[0] == 0x00 && rbuf[1] == 0x00) {
95                struct sc_card_driver *drv;
96                if (card->ctx->debug >= 2)
97                        sc_debug(card->ctx, "SELECT FILE seems to return Schlumberger 'flex stuff\n");
98                drv = sc_get_cryptoflex_driver();
99                card->ops->select_file = drv->ops->select_file;
100                return 0;
101        }
102        return 0;
103}
104
105static int default_init(sc_card_t *card)
106{
107        int r;
108       
109        card->name = "Unidentified card";
110        card->drv_data = NULL;
111        r = autodetect_class(card);
112        if (r) {
113                sc_error(card->ctx, "unable to determine the right class byte\n");
114                return SC_ERROR_INVALID_CARD;
115        }
116
117        return 0;
118}
119
120static struct sc_card_driver * sc_get_driver(void)
121{
122        struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
123
124        default_ops = *iso_drv->ops;
125        default_ops.match_card = default_match_card;
126        default_ops.init = default_init;
127        default_ops.finish = default_finish;
128
129        return &default_drv;
130}
131
132#if 1
133struct sc_card_driver * sc_get_default_driver(void)
134{
135        return sc_get_driver();
136}
137#endif
Note: See TracBrowser for help on using the browser.