Branch data Line data Source code
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 file in the top-level directory.
6 : : */
7 : :
8 : : #include <glib.h>
9 : :
10 : : #include <string.h>
11 : :
12 : : #include "vcard.h"
13 : : #include "vcard_emul.h"
14 : : #include "card_7816t.h"
15 : : #include "common.h"
16 : :
17 : : struct VCardAppletStruct {
18 : : VCardApplet *next;
19 : : VCardProcessAPDU process_apdu;
20 : : VCardResetApplet reset_applet;
21 : : unsigned char *aid;
22 : : int aid_len;
23 : : void *applet_private;
24 : : VCardAppletPrivateFree applet_private_free;
25 : : };
26 : :
27 : : struct VCardStruct {
28 : : int reference_count;
29 : : VCardApplet *applet_list;
30 : : VCardApplet *current_applet[MAX_CHANNEL];
31 : : VCardBufferResponse *vcard_buffer_response;
32 : : VCardType type;
33 : : VCardEmul *vcard_private;
34 : : VCardEmulFree vcard_private_free;
35 : : VCardGetAtr vcard_get_atr;
36 : : unsigned int compat;
37 : : unsigned char serial[32]; /* SHA256 of the first certificate */
38 : : int serial_len;
39 : : };
40 : :
41 : : VCardBufferResponse *
42 : 227 : vcard_buffer_response_new(const unsigned char *buffer, int size)
43 : : {
44 : : VCardBufferResponse *new_buffer;
45 : :
46 : 227 : new_buffer = g_new(VCardBufferResponse, 1);
47 : 227 : new_buffer->buffer = (unsigned char *)g_memdup2(buffer, size);
48 : 227 : new_buffer->buffer_len = size;
49 : 227 : new_buffer->current = new_buffer->buffer;
50 : 227 : new_buffer->len = size;
51 : 227 : return new_buffer;
52 : : }
53 : :
54 : : void
55 : 231 : vcard_buffer_response_delete(VCardBufferResponse *buffer_response)
56 : : {
57 [ + + ]: 231 : if (buffer_response == NULL) {
58 : : return;
59 : : }
60 : 227 : g_free(buffer_response->buffer);
61 : 227 : g_free(buffer_response);
62 : : }
63 : :
64 : :
65 : : /*
66 : : * clean up state after a reset
67 : : */
68 : : void
69 : 16 : vcard_reset(VCard *card, VCardPower power)
70 : : {
71 : : int i;
72 : : VCardApplet *applet = NULL;
73 : :
74 [ - + ]: 16 : if (card->type == VCARD_DIRECT) {
75 : : /* select the last applet */
76 : : VCardApplet *current_applet = NULL;
77 [ # # ]: 0 : for (current_applet = card->applet_list; current_applet;
78 : 0 : current_applet = current_applet->next) {
79 : : applet = current_applet;
80 : : }
81 : : }
82 [ + + ]: 80 : for (i = 0; i < MAX_CHANNEL; i++) {
83 : 64 : card->current_applet[i] = applet;
84 : : }
85 [ - + ]: 16 : if (card->vcard_buffer_response) {
86 : 0 : vcard_buffer_response_delete(card->vcard_buffer_response);
87 : 0 : card->vcard_buffer_response = NULL;
88 : : }
89 : 16 : vcard_emul_reset(card, power);
90 [ - + ]: 16 : if (applet) {
91 : 0 : applet->reset_applet(card, 0);
92 : : }
93 : 16 : }
94 : :
95 : : /* applet utilities */
96 : :
97 : : /*
98 : : * applet utilities
99 : : */
100 : : /* constructor */
101 : : VCardApplet *
102 : 106 : vcard_new_applet(VCardProcessAPDU applet_process_function,
103 : : VCardResetApplet applet_reset_function,
104 : : const unsigned char *aid, int aid_len)
105 : : {
106 : : VCardApplet *applet;
107 : :
108 : 106 : applet = g_new0(VCardApplet, 1);
109 : 106 : applet->process_apdu = applet_process_function;
110 : 106 : applet->reset_applet = applet_reset_function;
111 : :
112 : 106 : applet->aid = g_memdup2(aid, aid_len);
113 : 106 : applet->aid_len = aid_len;
114 : 106 : return applet;
115 : : }
116 : :
117 : : /* destructor */
118 : : void
119 : 88 : vcard_delete_applet(VCardApplet *applet)
120 : : {
121 [ + - ]: 88 : if (applet == NULL) {
122 : : return;
123 : : }
124 [ + + ]: 88 : if (applet->applet_private_free) {
125 : 78 : applet->applet_private_free(applet->applet_private);
126 : : }
127 : 88 : g_free(applet->aid);
128 : 88 : g_free(applet);
129 : : }
130 : :
131 : : /* accessor */
132 : : void
133 : 94 : vcard_set_applet_private(VCardApplet *applet, VCardAppletPrivate *private,
134 : : VCardAppletPrivateFree private_free)
135 : : {
136 [ - + ]: 94 : if (applet->applet_private_free) {
137 : 0 : applet->applet_private_free(applet->applet_private);
138 : : }
139 : 94 : applet->applet_private = private;
140 : 94 : applet->applet_private_free = private_free;
141 : 94 : }
142 : :
143 : : VCard *
144 : 6 : vcard_new(VCardEmul *private, VCardEmulFree private_free)
145 : : {
146 : : VCard *new_card;
147 : :
148 : 6 : g_debug("%s: called", __func__);
149 : :
150 : 6 : new_card = g_new0(VCard, 1);
151 : 6 : new_card->type = VCARD_VM;
152 : 6 : new_card->vcard_private = private;
153 : 6 : new_card->vcard_private_free = private_free;
154 : 6 : new_card->reference_count = 1;
155 : 6 : return new_card;
156 : : }
157 : :
158 : : VCard *
159 : 856 : vcard_reference(VCard *vcard)
160 : : {
161 [ + + ]: 856 : if (vcard == NULL) {
162 : : return NULL;
163 : : }
164 : 824 : vcard->reference_count++;
165 : 824 : return vcard;
166 : : }
167 : :
168 : : void
169 : 851 : vcard_free(VCard *vcard)
170 : : {
171 : : VCardApplet *current_applet;
172 : : VCardApplet *next_applet;
173 : :
174 [ + + ]: 851 : if (vcard == NULL) {
175 : : return;
176 : : }
177 : 827 : vcard->reference_count--;
178 [ + + ]: 827 : if (vcard->reference_count != 0) {
179 : : return;
180 : : }
181 [ + - ]: 5 : if (vcard->vcard_private_free) {
182 : 5 : (*vcard->vcard_private_free)(vcard->vcard_private);
183 : : }
184 [ + + ]: 93 : for (current_applet = vcard->applet_list; current_applet;
185 : : current_applet = next_applet) {
186 : 88 : next_applet = current_applet->next;
187 : 88 : vcard_delete_applet(current_applet);
188 : : }
189 : 5 : vcard_buffer_response_delete(vcard->vcard_buffer_response);
190 : 5 : g_free(vcard);
191 : : }
192 : :
193 : : void
194 : 2 : vcard_get_atr(VCard *vcard, unsigned char *atr, int *atr_len)
195 : : {
196 [ + + ]: 2 : if (vcard->vcard_get_atr) {
197 : 1 : (*vcard->vcard_get_atr)(vcard, atr, atr_len);
198 : 1 : return;
199 : : }
200 : 1 : vcard_emul_get_atr(vcard, atr, atr_len);
201 : : }
202 : :
203 : : void
204 : 7 : vcard_set_atr_func(VCard *card, VCardGetAtr get_atr)
205 : : {
206 : 7 : card->vcard_get_atr = get_atr;
207 : 7 : }
208 : :
209 : :
210 : : VCardStatus
211 : 106 : vcard_add_applet(VCard *card, VCardApplet *applet)
212 : : {
213 : 106 : g_debug("%s: called", __func__);
214 : :
215 : 106 : applet->next = card->applet_list;
216 : 106 : card->applet_list = applet;
217 : : /* if our card-type is direct, always call the applet */
218 [ - + ]: 106 : if (card->type == VCARD_DIRECT) {
219 : : int i;
220 : :
221 [ # # ]: 0 : for (i = 0; i < MAX_CHANNEL; i++) {
222 : 0 : card->current_applet[i] = applet;
223 : : }
224 : : }
225 : 106 : return VCARD_DONE;
226 : : }
227 : :
228 : : /*
229 : : * manage applets
230 : : */
231 : : VCardApplet *
232 : 193 : vcard_find_applet(VCard *card, const unsigned char *aid, int aid_len)
233 : : {
234 : : VCardApplet *current_applet;
235 : :
236 [ + + ]: 1398 : for (current_applet = card->applet_list; current_applet;
237 : 1205 : current_applet = current_applet->next) {
238 [ + + ]: 1397 : if (current_applet->aid_len != aid_len) {
239 : 190 : continue;
240 : : }
241 [ + + ]: 1207 : if (memcmp(current_applet->aid, aid, aid_len) == 0) {
242 : : break;
243 : : }
244 : : }
245 : 193 : return current_applet;
246 : : }
247 : :
248 : : unsigned char *
249 : 0 : vcard_applet_get_aid(VCardApplet *applet, int *aid_len)
250 : : {
251 [ # # ]: 0 : if (applet == NULL) {
252 : : return NULL;
253 : : }
254 : 0 : *aid_len = applet->aid_len;
255 : 0 : return applet->aid;
256 : : }
257 : :
258 : :
259 : : void
260 : 97 : vcard_select_applet(VCard *card, int channel, VCardApplet *applet)
261 : : {
262 [ + - ]: 97 : g_assert(channel >= 0 && channel < MAX_CHANNEL);
263 : :
264 : 97 : card->current_applet[channel] = applet;
265 : : /* reset the applet */
266 [ + + + + ]: 97 : if (applet && applet->reset_applet) {
267 : 36 : applet->reset_applet(card, channel);
268 : : }
269 : 97 : }
270 : :
271 : : VCardAppletPrivate *
272 : 1441 : vcard_get_current_applet_private(VCard *card, int channel)
273 : : {
274 : 1441 : VCardApplet *applet = card->current_applet[channel];
275 : :
276 [ + - ]: 1441 : if (applet == NULL) {
277 : : return NULL;
278 : : }
279 : 1441 : return applet->applet_private;
280 : : }
281 : :
282 : : VCardStatus
283 : 750 : vcard_process_applet_apdu(VCard *card, VCardAPDU *apdu,
284 : : VCardResponse **response)
285 : : {
286 [ + + ]: 750 : if (card->current_applet[apdu->a_channel]) {
287 : 733 : return card->current_applet[apdu->a_channel]->process_apdu(
288 : : card, apdu, response);
289 : : }
290 : : return VCARD_NEXT;
291 : : }
292 : :
293 : : /*
294 : : * Accessor functions
295 : : */
296 : : /* accessor functions for the response buffer */
297 : : VCardBufferResponse *
298 : 1030 : vcard_get_buffer_response(VCard *card)
299 : : {
300 : 1030 : return card->vcard_buffer_response;
301 : : }
302 : :
303 : : void
304 : 453 : vcard_set_buffer_response(VCard *card, VCardBufferResponse *buffer)
305 : : {
306 : 453 : card->vcard_buffer_response = buffer;
307 : 453 : }
308 : :
309 : :
310 : : /* accessor functions for the type */
311 : : VCardType
312 : 204 : vcard_get_type(VCard *card)
313 : : {
314 : 204 : return card->type;
315 : : }
316 : :
317 : : void
318 : 6 : vcard_set_type(VCard *card, VCardType type)
319 : : {
320 : 6 : card->type = type;
321 : 6 : }
322 : :
323 : : /* accessor for private data */
324 : : VCardEmul *
325 : 124 : vcard_get_private(VCard *vcard)
326 : : {
327 : 124 : return vcard->vcard_private;
328 : : }
329 : :
330 : : /* Get remaining login count for the current card */
331 : : int
332 : 4 : vcard_get_login_count(VCard *card)
333 : : {
334 : 4 : int rv = vcard_emul_get_login_count(card);
335 : :
336 : : /* Windows drivers are not very happy with the answer we can give here
337 : : * so lets assume the card still have all the attempts unlocked here */
338 [ + - + + ]: 4 : if (rv == -1 && card->compat & VCARD_COMPAT_WINDOWS) {
339 : 2 : return 3;
340 : : }
341 : : return rv;
342 : : }
343 : :
344 : : /* Set compat bits for the given cards. See VCARD_COMPAT_* options */
345 : : void
346 : 3 : vcard_set_compat(VCard *card, unsigned int set)
347 : : {
348 : 3 : card->compat |= set;
349 : 3 : }
350 : :
351 : : /* Set card serial number */
352 : : void
353 : 6 : vcard_set_serial(VCard *card, unsigned char *serial, size_t len)
354 : : {
355 : 6 : len = MIN(sizeof(card->serial), len);
356 : 6 : memcpy(card->serial, serial, len);
357 : 6 : card->serial_len = len;
358 : 6 : }
359 : :
360 : : unsigned char *
361 : 3 : vcard_get_serial(VCard *card, int *len)
362 : : {
363 [ + - ]: 3 : if (len != NULL)
364 : 3 : *len = card->serial_len;
365 : 3 : return card->serial;
366 : : }
|