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