]> Git Repo - qemu.git/blob - libcacard/vcard.c
rbd: Fix leaks in rbd_start_aio() error path
[qemu.git] / libcacard / vcard.c
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 = g_new(VCardBufferResponse, 1);
41     new_buffer->buffer = (unsigned char *)g_memdup(buffer, size);
42     new_buffer->buffer_len = size;
43     new_buffer->current = new_buffer->buffer;
44     new_buffer->len = size;
45     return new_buffer;
46 }
47
48 void
49 vcard_buffer_response_delete(VCardBufferResponse *buffer_response)
50 {
51     if (buffer_response == NULL) {
52         return;
53     }
54     if (buffer_response->buffer) {
55         g_free(buffer_response->buffer);
56     }
57     g_free(buffer_response);
58 }
59
60
61 /*
62  * clean up state after a reset
63  */
64 void
65 vcard_reset(VCard *card, VCardPower power)
66 {
67     int i;
68     VCardApplet *applet = NULL;
69
70     if (card->type ==  VCARD_DIRECT) {
71         /* select the last applet */
72         VCardApplet *current_applet = NULL;
73         for (current_applet = card->applet_list; current_applet;
74                                        current_applet = current_applet->next) {
75             applet = current_applet;
76         }
77     }
78     for (i = 0; i < MAX_CHANNEL; i++) {
79         card->current_applet[i] = applet;
80     }
81     if (card->vcard_buffer_response) {
82         vcard_buffer_response_delete(card->vcard_buffer_response);
83         card->vcard_buffer_response = NULL;
84     }
85     vcard_emul_reset(card, power);
86     if (applet) {
87         applet->reset_applet(card, 0);
88     }
89 }
90
91 /* applet utilities */
92
93 /*
94  * applet utilities
95  */
96 /* constructor */
97 VCardApplet *
98 vcard_new_applet(VCardProcessAPDU applet_process_function,
99                  VCardResetApplet applet_reset_function,
100                  unsigned char *aid, int aid_len)
101 {
102     VCardApplet *applet;
103
104     applet = g_new0(VCardApplet, 1);
105     applet->process_apdu = applet_process_function;
106     applet->reset_applet = applet_reset_function;
107
108     applet->aid = g_memdup(aid, aid_len);
109     applet->aid_len = aid_len;
110     return applet;
111 }
112
113 /* destructor */
114 void
115 vcard_delete_applet(VCardApplet *applet)
116 {
117     if (applet == NULL) {
118         return;
119     }
120     if (applet->applet_private_free) {
121         applet->applet_private_free(applet->applet_private);
122         applet->applet_private = NULL;
123     }
124     if (applet->aid) {
125         g_free(applet->aid);
126         applet->aid = NULL;
127     }
128     g_free(applet);
129 }
130
131 /* accessor */
132 void
133 vcard_set_applet_private(VCardApplet *applet, VCardAppletPrivate *private,
134                          VCardAppletPrivateFree private_free)
135 {
136     if (applet->applet_private_free) {
137         applet->applet_private_free(applet->applet_private);
138     }
139     applet->applet_private = private;
140     applet->applet_private_free = private_free;
141 }
142
143 VCard *
144 vcard_new(VCardEmul *private, VCardEmulFree private_free)
145 {
146     VCard *new_card;
147
148     new_card = g_new0(VCard, 1);
149     new_card->type = VCARD_VM;
150     new_card->vcard_private = private;
151     new_card->vcard_private_free = private_free;
152     new_card->reference_count = 1;
153     return new_card;
154 }
155
156 VCard *
157 vcard_reference(VCard *vcard)
158 {
159     if (vcard == NULL) {
160         return NULL;
161     }
162     vcard->reference_count++;
163     return vcard;
164 }
165
166 void
167 vcard_free(VCard *vcard)
168 {
169     VCardApplet *current_applet;
170     VCardApplet *next_applet;
171
172     if (vcard == NULL) {
173         return;
174     }
175     vcard->reference_count--;
176     if (vcard->reference_count != 0) {
177         return;
178     }
179     if (vcard->vcard_private_free) {
180         (*vcard->vcard_private_free)(vcard->vcard_private);
181         vcard->vcard_private_free = 0;
182         vcard->vcard_private = 0;
183     }
184     for (current_applet = vcard->applet_list; current_applet;
185                                         current_applet = next_applet) {
186         next_applet = current_applet->next;
187         vcard_delete_applet(current_applet);
188     }
189     vcard_buffer_response_delete(vcard->vcard_buffer_response);
190     g_free(vcard);
191 }
192
193 void
194 vcard_get_atr(VCard *vcard, unsigned char *atr, int *atr_len)
195 {
196     if (vcard->vcard_get_atr) {
197         (*vcard->vcard_get_atr)(vcard, atr, atr_len);
198         return;
199     }
200     vcard_emul_get_atr(vcard, atr, atr_len);
201 }
202
203 void
204 vcard_set_atr_func(VCard *card, VCardGetAtr vcard_get_atr)
205 {
206     card->vcard_get_atr = vcard_get_atr;
207 }
208
209
210 VCardStatus
211 vcard_add_applet(VCard *card, VCardApplet *applet)
212 {
213     applet->next = card->applet_list;
214     card->applet_list = applet;
215     /* if our card-type is direct, always call the applet */
216     if (card->type ==  VCARD_DIRECT) {
217         int i;
218
219         for (i = 0; i < MAX_CHANNEL; i++) {
220             card->current_applet[i] = applet;
221         }
222     }
223     return VCARD_DONE;
224 }
225
226 /*
227  * manage applets
228  */
229 VCardApplet *
230 vcard_find_applet(VCard *card, unsigned char *aid, int aid_len)
231 {
232     VCardApplet *current_applet;
233
234     for (current_applet = card->applet_list; current_applet;
235                                         current_applet = current_applet->next) {
236         if (current_applet->aid_len != aid_len) {
237             continue;
238         }
239         if (memcmp(current_applet->aid, aid, aid_len) == 0) {
240             break;
241         }
242     }
243     return current_applet;
244 }
245
246 unsigned char *
247 vcard_applet_get_aid(VCardApplet *applet, int *aid_len)
248 {
249     if (applet == NULL) {
250         return NULL;
251     }
252     *aid_len = applet->aid_len;
253     return applet->aid;
254 }
255
256
257 void
258 vcard_select_applet(VCard *card, int channel, VCardApplet *applet)
259 {
260     assert(channel < MAX_CHANNEL);
261     card->current_applet[channel] = applet;
262     /* reset the applet */
263     if (applet && applet->reset_applet) {
264         applet->reset_applet(card, channel);
265     }
266 }
267
268 VCardAppletPrivate *
269 vcard_get_current_applet_private(VCard *card, int channel)
270 {
271     VCardApplet *applet = card->current_applet[channel];
272
273     if (applet == NULL) {
274         return NULL;
275     }
276     return applet->applet_private;
277 }
278
279 VCardStatus
280 vcard_process_applet_apdu(VCard *card, VCardAPDU *apdu,
281                           VCardResponse **response)
282 {
283     if (card->current_applet[apdu->a_channel]) {
284         return card->current_applet[apdu->a_channel]->process_apdu(
285                                                         card, apdu, response);
286     }
287     return VCARD_NEXT;
288 }
289
290 /*
291  * Accessor functions
292  */
293 /* accessor functions for the response buffer */
294 VCardBufferResponse *
295 vcard_get_buffer_response(VCard *card)
296 {
297     return card->vcard_buffer_response;
298 }
299
300 void
301 vcard_set_buffer_response(VCard *card, VCardBufferResponse *buffer)
302 {
303     card->vcard_buffer_response = buffer;
304 }
305
306
307 /* accessor functions for the type */
308 VCardType
309 vcard_get_type(VCard *card)
310 {
311     return card->type;
312 }
313
314 void
315 vcard_set_type(VCard *card, VCardType type)
316 {
317     card->type = type;
318 }
319
320 /* accessor for private data */
321 VCardEmul *
322 vcard_get_private(VCard *vcard)
323 {
324     return vcard->vcard_private;
325 }
326
This page took 0.041036 seconds and 4 git commands to generate.