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