Statistics
| Branch: | Revision:

root / libcacard / vcard.c @ 26ca8c06

History | View | Annotate | Download (7.8 kB)

1 111a38b0 Robert Relyea
/*
2 111a38b0 Robert Relyea
 * implement the Java card standard.
3 111a38b0 Robert Relyea
 *
4 111a38b0 Robert Relyea
 * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
5 111a38b0 Robert Relyea
 * See the COPYING.LIB file in the top-level directory.
6 111a38b0 Robert Relyea
 */
7 111a38b0 Robert Relyea
8 111a38b0 Robert Relyea
#include "qemu-common.h"
9 111a38b0 Robert Relyea
10 111a38b0 Robert Relyea
#include "vcard.h"
11 111a38b0 Robert Relyea
#include "vcard_emul.h"
12 111a38b0 Robert Relyea
#include "card_7816t.h"
13 111a38b0 Robert Relyea
14 111a38b0 Robert Relyea
struct VCardAppletStruct {
15 111a38b0 Robert Relyea
    VCardApplet   *next;
16 111a38b0 Robert Relyea
    VCardProcessAPDU process_apdu;
17 111a38b0 Robert Relyea
    VCardResetApplet reset_applet;
18 111a38b0 Robert Relyea
    unsigned char *aid;
19 111a38b0 Robert Relyea
    int aid_len;
20 111a38b0 Robert Relyea
    void *applet_private;
21 111a38b0 Robert Relyea
    VCardAppletPrivateFree applet_private_free;
22 111a38b0 Robert Relyea
};
23 111a38b0 Robert Relyea
24 111a38b0 Robert Relyea
struct VCardStruct {
25 111a38b0 Robert Relyea
    int reference_count;
26 111a38b0 Robert Relyea
    VCardApplet *applet_list;
27 111a38b0 Robert Relyea
    VCardApplet *current_applet[MAX_CHANNEL];
28 111a38b0 Robert Relyea
    VCardBufferResponse *vcard_buffer_response;
29 111a38b0 Robert Relyea
    VCardType type;
30 111a38b0 Robert Relyea
    VCardEmul *vcard_private;
31 111a38b0 Robert Relyea
    VCardEmulFree vcard_private_free;
32 111a38b0 Robert Relyea
    VCardGetAtr vcard_get_atr;
33 111a38b0 Robert Relyea
};
34 111a38b0 Robert Relyea
35 111a38b0 Robert Relyea
VCardBufferResponse *
36 111a38b0 Robert Relyea
vcard_buffer_response_new(unsigned char *buffer, int size)
37 111a38b0 Robert Relyea
{
38 111a38b0 Robert Relyea
    VCardBufferResponse *new_buffer;
39 111a38b0 Robert Relyea
40 7267c094 Anthony Liguori
    new_buffer = (VCardBufferResponse *)g_malloc(sizeof(VCardBufferResponse));
41 7267c094 Anthony Liguori
    new_buffer->buffer = (unsigned char *)g_malloc(size);
42 111a38b0 Robert Relyea
    memcpy(new_buffer->buffer, buffer, size);
43 111a38b0 Robert Relyea
    new_buffer->buffer_len = size;
44 111a38b0 Robert Relyea
    new_buffer->current = new_buffer->buffer;
45 111a38b0 Robert Relyea
    new_buffer->len = size;
46 111a38b0 Robert Relyea
    return new_buffer;
47 111a38b0 Robert Relyea
}
48 111a38b0 Robert Relyea
49 111a38b0 Robert Relyea
void
50 111a38b0 Robert Relyea
vcard_buffer_response_delete(VCardBufferResponse *buffer_response)
51 111a38b0 Robert Relyea
{
52 111a38b0 Robert Relyea
    if (buffer_response == NULL) {
53 111a38b0 Robert Relyea
        return;
54 111a38b0 Robert Relyea
    }
55 111a38b0 Robert Relyea
    if (buffer_response->buffer) {
56 7267c094 Anthony Liguori
        g_free(buffer_response->buffer);
57 111a38b0 Robert Relyea
    }
58 7267c094 Anthony Liguori
    g_free(buffer_response);
59 111a38b0 Robert Relyea
}
60 111a38b0 Robert Relyea
61 111a38b0 Robert Relyea
62 111a38b0 Robert Relyea
/*
63 111a38b0 Robert Relyea
 * clean up state after a reset
64 111a38b0 Robert Relyea
 */
65 111a38b0 Robert Relyea
void
66 111a38b0 Robert Relyea
vcard_reset(VCard *card, VCardPower power)
67 111a38b0 Robert Relyea
{
68 111a38b0 Robert Relyea
    int i;
69 111a38b0 Robert Relyea
    VCardApplet *applet = NULL;
70 111a38b0 Robert Relyea
71 111a38b0 Robert Relyea
    if (card->type ==  VCARD_DIRECT) {
72 111a38b0 Robert Relyea
        /* select the last applet */
73 111a38b0 Robert Relyea
        VCardApplet *current_applet = NULL;
74 111a38b0 Robert Relyea
        for (current_applet = card->applet_list; current_applet;
75 111a38b0 Robert Relyea
                                       current_applet = current_applet->next) {
76 111a38b0 Robert Relyea
            applet = current_applet;
77 111a38b0 Robert Relyea
        }
78 111a38b0 Robert Relyea
    }
79 111a38b0 Robert Relyea
    for (i = 0; i < MAX_CHANNEL; i++) {
80 111a38b0 Robert Relyea
        card->current_applet[i] = applet;
81 111a38b0 Robert Relyea
    }
82 111a38b0 Robert Relyea
    if (card->vcard_buffer_response) {
83 111a38b0 Robert Relyea
        vcard_buffer_response_delete(card->vcard_buffer_response);
84 111a38b0 Robert Relyea
        card->vcard_buffer_response = NULL;
85 111a38b0 Robert Relyea
    }
86 111a38b0 Robert Relyea
    vcard_emul_reset(card, power);
87 111a38b0 Robert Relyea
    if (applet) {
88 111a38b0 Robert Relyea
        applet->reset_applet(card, 0);
89 111a38b0 Robert Relyea
    }
90 111a38b0 Robert Relyea
}
91 111a38b0 Robert Relyea
92 111a38b0 Robert Relyea
/* applet utilities */
93 111a38b0 Robert Relyea
94 111a38b0 Robert Relyea
/*
95 111a38b0 Robert Relyea
 * applet utilities
96 111a38b0 Robert Relyea
 */
97 111a38b0 Robert Relyea
/* constructor */
98 111a38b0 Robert Relyea
VCardApplet *
99 111a38b0 Robert Relyea
vcard_new_applet(VCardProcessAPDU applet_process_function,
100 111a38b0 Robert Relyea
                 VCardResetApplet applet_reset_function,
101 111a38b0 Robert Relyea
                 unsigned char *aid, int aid_len)
102 111a38b0 Robert Relyea
{
103 111a38b0 Robert Relyea
    VCardApplet *applet;
104 111a38b0 Robert Relyea
105 7267c094 Anthony Liguori
    applet = (VCardApplet *)g_malloc(sizeof(VCardApplet));
106 111a38b0 Robert Relyea
    applet->next = NULL;
107 111a38b0 Robert Relyea
    applet->applet_private = NULL;
108 111a38b0 Robert Relyea
    applet->applet_private_free = NULL;
109 111a38b0 Robert Relyea
    applet->process_apdu = applet_process_function;
110 111a38b0 Robert Relyea
    applet->reset_applet = applet_reset_function;
111 111a38b0 Robert Relyea
112 7267c094 Anthony Liguori
    applet->aid = g_malloc(aid_len);
113 111a38b0 Robert Relyea
    memcpy(applet->aid, aid, aid_len);
114 111a38b0 Robert Relyea
    applet->aid_len = aid_len;
115 111a38b0 Robert Relyea
    return applet;
116 111a38b0 Robert Relyea
}
117 111a38b0 Robert Relyea
118 111a38b0 Robert Relyea
/* destructor */
119 111a38b0 Robert Relyea
void
120 111a38b0 Robert Relyea
vcard_delete_applet(VCardApplet *applet)
121 111a38b0 Robert Relyea
{
122 111a38b0 Robert Relyea
    if (applet == NULL) {
123 111a38b0 Robert Relyea
        return;
124 111a38b0 Robert Relyea
    }
125 111a38b0 Robert Relyea
    if (applet->applet_private_free) {
126 111a38b0 Robert Relyea
        applet->applet_private_free(applet->applet_private);
127 111a38b0 Robert Relyea
        applet->applet_private = NULL;
128 111a38b0 Robert Relyea
    }
129 111a38b0 Robert Relyea
    if (applet->aid) {
130 7267c094 Anthony Liguori
        g_free(applet->aid);
131 111a38b0 Robert Relyea
        applet->aid = NULL;
132 111a38b0 Robert Relyea
    }
133 7267c094 Anthony Liguori
    g_free(applet);
134 111a38b0 Robert Relyea
}
135 111a38b0 Robert Relyea
136 111a38b0 Robert Relyea
/* accessor */
137 111a38b0 Robert Relyea
void
138 111a38b0 Robert Relyea
vcard_set_applet_private(VCardApplet *applet, VCardAppletPrivate *private,
139 111a38b0 Robert Relyea
                         VCardAppletPrivateFree private_free)
140 111a38b0 Robert Relyea
{
141 111a38b0 Robert Relyea
    if (applet->applet_private_free) {
142 111a38b0 Robert Relyea
        applet->applet_private_free(applet->applet_private);
143 111a38b0 Robert Relyea
    }
144 111a38b0 Robert Relyea
    applet->applet_private = private;
145 111a38b0 Robert Relyea
    applet->applet_private_free = private_free;
146 111a38b0 Robert Relyea
}
147 111a38b0 Robert Relyea
148 111a38b0 Robert Relyea
VCard *
149 111a38b0 Robert Relyea
vcard_new(VCardEmul *private, VCardEmulFree private_free)
150 111a38b0 Robert Relyea
{
151 111a38b0 Robert Relyea
    VCard *new_card;
152 111a38b0 Robert Relyea
    int i;
153 111a38b0 Robert Relyea
154 7267c094 Anthony Liguori
    new_card = (VCard *)g_malloc(sizeof(VCard));
155 111a38b0 Robert Relyea
    new_card->applet_list = NULL;
156 111a38b0 Robert Relyea
    for (i = 0; i < MAX_CHANNEL; i++) {
157 111a38b0 Robert Relyea
        new_card->current_applet[i] = NULL;
158 111a38b0 Robert Relyea
    }
159 111a38b0 Robert Relyea
    new_card->vcard_buffer_response = NULL;
160 111a38b0 Robert Relyea
    new_card->type = VCARD_VM;
161 111a38b0 Robert Relyea
    new_card->vcard_private = private;
162 111a38b0 Robert Relyea
    new_card->vcard_private_free = private_free;
163 111a38b0 Robert Relyea
    new_card->vcard_get_atr = NULL;
164 111a38b0 Robert Relyea
    new_card->reference_count = 1;
165 111a38b0 Robert Relyea
    return new_card;
166 111a38b0 Robert Relyea
}
167 111a38b0 Robert Relyea
168 111a38b0 Robert Relyea
VCard *
169 111a38b0 Robert Relyea
vcard_reference(VCard *vcard)
170 111a38b0 Robert Relyea
{
171 111a38b0 Robert Relyea
    if (vcard == NULL) {
172 111a38b0 Robert Relyea
        return NULL;
173 111a38b0 Robert Relyea
    }
174 111a38b0 Robert Relyea
    vcard->reference_count++;
175 111a38b0 Robert Relyea
    return vcard;
176 111a38b0 Robert Relyea
}
177 111a38b0 Robert Relyea
178 111a38b0 Robert Relyea
void
179 111a38b0 Robert Relyea
vcard_free(VCard *vcard)
180 111a38b0 Robert Relyea
{
181 111a38b0 Robert Relyea
    VCardApplet *current_applet = NULL;
182 111a38b0 Robert Relyea
    VCardApplet *next_applet = NULL;
183 111a38b0 Robert Relyea
184 111a38b0 Robert Relyea
    if (vcard == NULL) {
185 111a38b0 Robert Relyea
        return;
186 111a38b0 Robert Relyea
    }
187 111a38b0 Robert Relyea
    vcard->reference_count--;
188 111a38b0 Robert Relyea
    if (vcard->reference_count != 0) {
189 111a38b0 Robert Relyea
        return;
190 111a38b0 Robert Relyea
    }
191 111a38b0 Robert Relyea
    if (vcard->vcard_private_free) {
192 111a38b0 Robert Relyea
        (*vcard->vcard_private_free)(vcard->vcard_private);
193 111a38b0 Robert Relyea
        vcard->vcard_private_free = 0;
194 111a38b0 Robert Relyea
        vcard->vcard_private = 0;
195 111a38b0 Robert Relyea
    }
196 111a38b0 Robert Relyea
    for (current_applet = vcard->applet_list; current_applet;
197 111a38b0 Robert Relyea
                                        current_applet = next_applet) {
198 111a38b0 Robert Relyea
        next_applet = current_applet->next;
199 111a38b0 Robert Relyea
        vcard_delete_applet(current_applet);
200 111a38b0 Robert Relyea
    }
201 111a38b0 Robert Relyea
    vcard_buffer_response_delete(vcard->vcard_buffer_response);
202 7267c094 Anthony Liguori
    g_free(vcard);
203 111a38b0 Robert Relyea
}
204 111a38b0 Robert Relyea
205 111a38b0 Robert Relyea
void
206 111a38b0 Robert Relyea
vcard_get_atr(VCard *vcard, unsigned char *atr, int *atr_len)
207 111a38b0 Robert Relyea
{
208 111a38b0 Robert Relyea
    if (vcard->vcard_get_atr) {
209 111a38b0 Robert Relyea
        (*vcard->vcard_get_atr)(vcard, atr, atr_len);
210 111a38b0 Robert Relyea
        return;
211 111a38b0 Robert Relyea
    }
212 111a38b0 Robert Relyea
    vcard_emul_get_atr(vcard, atr, atr_len);
213 111a38b0 Robert Relyea
}
214 111a38b0 Robert Relyea
215 111a38b0 Robert Relyea
void
216 111a38b0 Robert Relyea
vcard_set_atr_func(VCard *card, VCardGetAtr vcard_get_atr)
217 111a38b0 Robert Relyea
{
218 111a38b0 Robert Relyea
    card->vcard_get_atr = vcard_get_atr;
219 111a38b0 Robert Relyea
}
220 111a38b0 Robert Relyea
221 111a38b0 Robert Relyea
222 111a38b0 Robert Relyea
VCardStatus
223 111a38b0 Robert Relyea
vcard_add_applet(VCard *card, VCardApplet *applet)
224 111a38b0 Robert Relyea
{
225 111a38b0 Robert Relyea
    applet->next = card->applet_list;
226 111a38b0 Robert Relyea
    card->applet_list = applet;
227 111a38b0 Robert Relyea
    /* if our card-type is direct, always call the applet */
228 111a38b0 Robert Relyea
    if (card->type ==  VCARD_DIRECT) {
229 111a38b0 Robert Relyea
        int i;
230 111a38b0 Robert Relyea
231 111a38b0 Robert Relyea
        for (i = 0; i < MAX_CHANNEL; i++) {
232 111a38b0 Robert Relyea
            card->current_applet[i] = applet;
233 111a38b0 Robert Relyea
        }
234 111a38b0 Robert Relyea
    }
235 111a38b0 Robert Relyea
    return VCARD_DONE;
236 111a38b0 Robert Relyea
}
237 111a38b0 Robert Relyea
238 111a38b0 Robert Relyea
/*
239 111a38b0 Robert Relyea
 * manage applets
240 111a38b0 Robert Relyea
 */
241 111a38b0 Robert Relyea
VCardApplet *
242 111a38b0 Robert Relyea
vcard_find_applet(VCard *card, unsigned char *aid, int aid_len)
243 111a38b0 Robert Relyea
{
244 111a38b0 Robert Relyea
    VCardApplet *current_applet;
245 111a38b0 Robert Relyea
246 111a38b0 Robert Relyea
    for (current_applet = card->applet_list; current_applet;
247 111a38b0 Robert Relyea
                                        current_applet = current_applet->next) {
248 111a38b0 Robert Relyea
        if (current_applet->aid_len != aid_len) {
249 111a38b0 Robert Relyea
            continue;
250 111a38b0 Robert Relyea
        }
251 111a38b0 Robert Relyea
        if (memcmp(current_applet->aid, aid, aid_len) == 0) {
252 111a38b0 Robert Relyea
            break;
253 111a38b0 Robert Relyea
        }
254 111a38b0 Robert Relyea
    }
255 111a38b0 Robert Relyea
    return current_applet;
256 111a38b0 Robert Relyea
}
257 111a38b0 Robert Relyea
258 111a38b0 Robert Relyea
unsigned char *
259 111a38b0 Robert Relyea
vcard_applet_get_aid(VCardApplet *applet, int *aid_len)
260 111a38b0 Robert Relyea
{
261 111a38b0 Robert Relyea
    if (applet == NULL) {
262 111a38b0 Robert Relyea
        return NULL;
263 111a38b0 Robert Relyea
    }
264 111a38b0 Robert Relyea
    *aid_len = applet->aid_len;
265 111a38b0 Robert Relyea
    return applet->aid;
266 111a38b0 Robert Relyea
}
267 111a38b0 Robert Relyea
268 111a38b0 Robert Relyea
269 111a38b0 Robert Relyea
void
270 111a38b0 Robert Relyea
vcard_select_applet(VCard *card, int channel, VCardApplet *applet)
271 111a38b0 Robert Relyea
{
272 111a38b0 Robert Relyea
    assert(channel < MAX_CHANNEL);
273 111a38b0 Robert Relyea
    card->current_applet[channel] = applet;
274 111a38b0 Robert Relyea
    /* reset the applet */
275 111a38b0 Robert Relyea
    if (applet && applet->reset_applet) {
276 111a38b0 Robert Relyea
        applet->reset_applet(card, channel);
277 111a38b0 Robert Relyea
    }
278 111a38b0 Robert Relyea
}
279 111a38b0 Robert Relyea
280 111a38b0 Robert Relyea
VCardAppletPrivate *
281 111a38b0 Robert Relyea
vcard_get_current_applet_private(VCard *card, int channel)
282 111a38b0 Robert Relyea
{
283 111a38b0 Robert Relyea
    VCardApplet *applet = card->current_applet[channel];
284 111a38b0 Robert Relyea
285 111a38b0 Robert Relyea
    if (applet == NULL) {
286 111a38b0 Robert Relyea
        return NULL;
287 111a38b0 Robert Relyea
    }
288 111a38b0 Robert Relyea
    return applet->applet_private;
289 111a38b0 Robert Relyea
}
290 111a38b0 Robert Relyea
291 111a38b0 Robert Relyea
VCardStatus
292 111a38b0 Robert Relyea
vcard_process_applet_apdu(VCard *card, VCardAPDU *apdu,
293 111a38b0 Robert Relyea
                          VCardResponse **response)
294 111a38b0 Robert Relyea
{
295 111a38b0 Robert Relyea
    if (card->current_applet[apdu->a_channel]) {
296 111a38b0 Robert Relyea
        return card->current_applet[apdu->a_channel]->process_apdu(
297 111a38b0 Robert Relyea
                                                        card, apdu, response);
298 111a38b0 Robert Relyea
    }
299 111a38b0 Robert Relyea
    return VCARD_NEXT;
300 111a38b0 Robert Relyea
}
301 111a38b0 Robert Relyea
302 111a38b0 Robert Relyea
/*
303 111a38b0 Robert Relyea
 * Accessor functions
304 111a38b0 Robert Relyea
 */
305 111a38b0 Robert Relyea
/* accessor functions for the response buffer */
306 111a38b0 Robert Relyea
VCardBufferResponse *
307 111a38b0 Robert Relyea
vcard_get_buffer_response(VCard *card)
308 111a38b0 Robert Relyea
{
309 111a38b0 Robert Relyea
    return card->vcard_buffer_response;
310 111a38b0 Robert Relyea
}
311 111a38b0 Robert Relyea
312 111a38b0 Robert Relyea
void
313 111a38b0 Robert Relyea
vcard_set_buffer_response(VCard *card, VCardBufferResponse *buffer)
314 111a38b0 Robert Relyea
{
315 111a38b0 Robert Relyea
    card->vcard_buffer_response = buffer;
316 111a38b0 Robert Relyea
}
317 111a38b0 Robert Relyea
318 111a38b0 Robert Relyea
319 111a38b0 Robert Relyea
/* accessor functions for the type */
320 111a38b0 Robert Relyea
VCardType
321 111a38b0 Robert Relyea
vcard_get_type(VCard *card)
322 111a38b0 Robert Relyea
{
323 111a38b0 Robert Relyea
    return card->type;
324 111a38b0 Robert Relyea
}
325 111a38b0 Robert Relyea
326 111a38b0 Robert Relyea
void
327 111a38b0 Robert Relyea
vcard_set_type(VCard *card, VCardType type)
328 111a38b0 Robert Relyea
{
329 111a38b0 Robert Relyea
    card->type = type;
330 111a38b0 Robert Relyea
}
331 111a38b0 Robert Relyea
332 111a38b0 Robert Relyea
/* accessor for private data */
333 111a38b0 Robert Relyea
VCardEmul *
334 111a38b0 Robert Relyea
vcard_get_private(VCard *vcard)
335 111a38b0 Robert Relyea
{
336 111a38b0 Robert Relyea
    return vcard->vcard_private;
337 111a38b0 Robert Relyea
}