2 * implement the Java card standard.
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.
8 #include "qemu-common.h"
11 #include "vcard_emul.h"
12 #include "card_7816t.h"
14 struct VCardAppletStruct
{
16 VCardProcessAPDU process_apdu
;
17 VCardResetApplet reset_applet
;
21 VCardAppletPrivateFree applet_private_free
;
26 VCardApplet
*applet_list
;
27 VCardApplet
*current_applet
[MAX_CHANNEL
];
28 VCardBufferResponse
*vcard_buffer_response
;
30 VCardEmul
*vcard_private
;
31 VCardEmulFree vcard_private_free
;
32 VCardGetAtr vcard_get_atr
;
36 vcard_buffer_response_new(unsigned char *buffer
, int size
)
38 VCardBufferResponse
*new_buffer
;
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
;
49 vcard_buffer_response_delete(VCardBufferResponse
*buffer_response
)
51 if (buffer_response
== NULL
) {
54 g_free(buffer_response
->buffer
);
55 g_free(buffer_response
);
60 * clean up state after a reset
63 vcard_reset(VCard
*card
, VCardPower power
)
66 VCardApplet
*applet
= NULL
;
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
;
76 for (i
= 0; i
< MAX_CHANNEL
; i
++) {
77 card
->current_applet
[i
] = applet
;
79 if (card
->vcard_buffer_response
) {
80 vcard_buffer_response_delete(card
->vcard_buffer_response
);
81 card
->vcard_buffer_response
= NULL
;
83 vcard_emul_reset(card
, power
);
85 applet
->reset_applet(card
, 0);
89 /* applet utilities */
96 vcard_new_applet(VCardProcessAPDU applet_process_function
,
97 VCardResetApplet applet_reset_function
,
98 unsigned char *aid
, int aid_len
)
102 applet
= g_new0(VCardApplet
, 1);
103 applet
->process_apdu
= applet_process_function
;
104 applet
->reset_applet
= applet_reset_function
;
106 applet
->aid
= g_memdup(aid
, aid_len
);
107 applet
->aid_len
= aid_len
;
113 vcard_delete_applet(VCardApplet
*applet
)
115 if (applet
== NULL
) {
118 if (applet
->applet_private_free
) {
119 applet
->applet_private_free(applet
->applet_private
);
127 vcard_set_applet_private(VCardApplet
*applet
, VCardAppletPrivate
*private,
128 VCardAppletPrivateFree private_free
)
130 if (applet
->applet_private_free
) {
131 applet
->applet_private_free(applet
->applet_private
);
133 applet
->applet_private
= private;
134 applet
->applet_private_free
= private_free
;
138 vcard_new(VCardEmul
*private, VCardEmulFree private_free
)
142 new_card
= g_new0(VCard
, 1);
143 new_card
->type
= VCARD_VM
;
144 new_card
->vcard_private
= private;
145 new_card
->vcard_private_free
= private_free
;
146 new_card
->reference_count
= 1;
151 vcard_reference(VCard
*vcard
)
156 vcard
->reference_count
++;
161 vcard_free(VCard
*vcard
)
163 VCardApplet
*current_applet
;
164 VCardApplet
*next_applet
;
169 vcard
->reference_count
--;
170 if (vcard
->reference_count
!= 0) {
173 if (vcard
->vcard_private_free
) {
174 (*vcard
->vcard_private_free
)(vcard
->vcard_private
);
176 for (current_applet
= vcard
->applet_list
; current_applet
;
177 current_applet
= next_applet
) {
178 next_applet
= current_applet
->next
;
179 vcard_delete_applet(current_applet
);
181 vcard_buffer_response_delete(vcard
->vcard_buffer_response
);
186 vcard_get_atr(VCard
*vcard
, unsigned char *atr
, int *atr_len
)
188 if (vcard
->vcard_get_atr
) {
189 (*vcard
->vcard_get_atr
)(vcard
, atr
, atr_len
);
192 vcard_emul_get_atr(vcard
, atr
, atr_len
);
196 vcard_set_atr_func(VCard
*card
, VCardGetAtr vcard_get_atr
)
198 card
->vcard_get_atr
= vcard_get_atr
;
203 vcard_add_applet(VCard
*card
, VCardApplet
*applet
)
205 applet
->next
= card
->applet_list
;
206 card
->applet_list
= applet
;
207 /* if our card-type is direct, always call the applet */
208 if (card
->type
== VCARD_DIRECT
) {
211 for (i
= 0; i
< MAX_CHANNEL
; i
++) {
212 card
->current_applet
[i
] = applet
;
222 vcard_find_applet(VCard
*card
, unsigned char *aid
, int aid_len
)
224 VCardApplet
*current_applet
;
226 for (current_applet
= card
->applet_list
; current_applet
;
227 current_applet
= current_applet
->next
) {
228 if (current_applet
->aid_len
!= aid_len
) {
231 if (memcmp(current_applet
->aid
, aid
, aid_len
) == 0) {
235 return current_applet
;
239 vcard_applet_get_aid(VCardApplet
*applet
, int *aid_len
)
241 if (applet
== NULL
) {
244 *aid_len
= applet
->aid_len
;
250 vcard_select_applet(VCard
*card
, int channel
, VCardApplet
*applet
)
252 assert(channel
< MAX_CHANNEL
);
253 card
->current_applet
[channel
] = applet
;
254 /* reset the applet */
255 if (applet
&& applet
->reset_applet
) {
256 applet
->reset_applet(card
, channel
);
261 vcard_get_current_applet_private(VCard
*card
, int channel
)
263 VCardApplet
*applet
= card
->current_applet
[channel
];
265 if (applet
== NULL
) {
268 return applet
->applet_private
;
272 vcard_process_applet_apdu(VCard
*card
, VCardAPDU
*apdu
,
273 VCardResponse
**response
)
275 if (card
->current_applet
[apdu
->a_channel
]) {
276 return card
->current_applet
[apdu
->a_channel
]->process_apdu(
277 card
, apdu
, response
);
285 /* accessor functions for the response buffer */
286 VCardBufferResponse
*
287 vcard_get_buffer_response(VCard
*card
)
289 return card
->vcard_buffer_response
;
293 vcard_set_buffer_response(VCard
*card
, VCardBufferResponse
*buffer
)
295 card
->vcard_buffer_response
= buffer
;
299 /* accessor functions for the type */
301 vcard_get_type(VCard
*card
)
307 vcard_set_type(VCard
*card
, VCardType type
)
312 /* accessor for private data */
314 vcard_get_private(VCard
*vcard
)
316 return vcard
->vcard_private
;