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

Revision 3085, 3.7 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-emv.c: Functions specified by the EMV standard
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 emv_ops;
25static struct sc_card_driver emv_drv = {
26        "EMV compatible cards",
27        "emv",
28        &emv_ops,
29        NULL, 0, NULL
30};
31
32static int emv_finish(sc_card_t *card)
33{
34        return 0;
35}
36
37static int parse_atr(const u8 *atr, size_t atr_len, int *t0_out, int *tx1, int *tx2,
38                     u8 *hist_bytes, int *hbcount)
39{
40        const u8 *p = atr;
41        int len = atr_len;
42        int nr_hist_bytes, tx, i;
43       
44        if (len < 2)
45                return -1;
46        p++;
47        len--;
48        *t0_out = *p;
49        nr_hist_bytes = *p & 0x0F;
50        tx = *p >> 4;
51        p++;
52        for (i = 0; i < 4; i++)
53                tx1[i] = tx2[i] = -1;
54        for (i = 0; i < 4; i++)
55                if (tx & (1 << i)) {
56                        if (len <= 0)
57                                return -1;
58                        tx1[i] = *p++;
59                        len--;
60                }
61        if (tx1[3] != -1) {
62                tx = tx1[3] >> 4;
63                for (i = 0; i < 4; i++)
64                        if (tx & (1 << i)) {
65                                if (len <= 0)
66                                        return -1;
67                                tx2[i] = *p++;
68                                len--;
69                        }
70        }
71        /* FIXME: possibly check TD2 */
72        if (hist_bytes == NULL || nr_hist_bytes == 0)
73                return 0;
74        if (len < nr_hist_bytes)
75                return -1;
76        memcpy(hist_bytes, p, nr_hist_bytes);
77        *hbcount = nr_hist_bytes;
78       
79        return 0;
80}
81
82static int emv_match_card(sc_card_t *card)
83{
84        int i, r, hbcount = 0, match = 1;
85        int tx1[4], tx2[4], t0;
86        char line[200], *linep = line;
87        u8 hist_bytes[32];
88
89        r = parse_atr(card->atr, card->atr_len, &t0, tx1, tx2, hist_bytes, &hbcount);
90        if (r)
91                return 0;
92        for (i = 0; i < 4; i++)
93                if (tx1[i] != -1)
94                        linep += sprintf(linep, "T%c1 = 0x%02X ", 'A' + i, tx1[i]);
95        for (i = 0; i < 4; i++)
96                if (tx2[i] != -1)
97                        linep += sprintf(linep, "T%c2 = 0x%02X ", 'A' + i, tx2[i]);
98        if (card->ctx->debug >= 4) {
99                sc_debug(card->ctx, "ATR parse: %s\n", line);
100                if (hbcount) {
101                        sc_hex_dump(card->ctx, hist_bytes, hbcount, line, sizeof(line));
102                        sc_debug(card->ctx, "historic bytes:\n%s", line);
103                }
104        }
105        if ((t0 & 0xF0) != 0x60)
106                match = 0;
107        if (match && tx1[1] != 0x00)
108                match = 0;
109        if (match && tx1[2] == -1)
110                match = 0;
111        if (match)
112                for (i = 0; i < 4; i++)
113                        if (tx2[i] != -1)
114                                match = 0;
115        return match;
116}
117
118static int emv_init(sc_card_t *card)
119{
120        card->drv_data = NULL;
121        card->cla = 0x00;
122
123        return 0;
124}
125
126static int emv_select_file(sc_card_t *card, const sc_path_t *path,
127                           sc_file_t **file)
128{
129        int r;
130        struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
131        const struct sc_card_operations *ops = iso_drv->ops;
132
133        r = ops->select_file(card, path, file);
134        if (r)
135                return r;
136        if (file != NULL && path->len == 2 && memcmp(path->value, "\x3F\x00", 2) == 0)
137                (*file)->type = SC_FILE_TYPE_DF;
138        if (file != NULL && (*file)->namelen)
139                (*file)->type = SC_FILE_TYPE_DF;
140        return 0;
141}
142
143static struct sc_card_driver * sc_get_driver(void)
144{
145        struct sc_card_driver *iso_drv = sc_get_iso7816_driver();
146
147        emv_ops = *iso_drv->ops;
148        emv_ops.match_card = emv_match_card;
149        emv_ops.init = emv_init;
150        emv_ops.finish = emv_finish;
151        emv_ops.select_file = emv_select_file;
152
153        return &emv_drv;
154}
155
156#if 1
157struct sc_card_driver * sc_get_emv_driver(void)
158{
159        return sc_get_driver();
160}
161#endif
Note: See TracBrowser for help on using the browser.