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 if (buffer_response
->buffer
) {
55 g_free(buffer_response
->buffer
);
57 g_free(buffer_response
);
62 * clean up state after a reset
65 vcard_reset(VCard
*card
, VCardPower power
)
68 VCardApplet
*applet
= NULL
;
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
;
78 for (i
= 0; i
< MAX_CHANNEL
; i
++) {
79 card
->current_applet
[i
] = applet
;
81 if (card
->vcard_buffer_response
) {
82 vcard_buffer_response_delete(card
->vcard_buffer_response
);
83 card
->vcard_buffer_response
= NULL
;
85 vcard_emul_reset(card
, power
);
87 applet
->reset_applet(card
, 0);
91 /* applet utilities */
98 vcard_new_applet(VCardProcessAPDU applet_process_function
,
99 VCardResetApplet applet_reset_function
,
100 unsigned char *aid
, int aid_len
)
104 applet
= g_new0(VCardApplet
, 1);
105 applet
->process_apdu
= applet_process_function
;
106 applet
->reset_applet
= applet_reset_function
;
108 applet
->aid
= g_memdup(aid
, aid_len
);
109 applet
->aid_len
= aid_len
;
115 vcard_delete_applet(VCardApplet
*applet
)
117 if (applet
== NULL
) {
120 if (applet
->applet_private_free
) {
121 applet
->applet_private_free(applet
->applet_private
);
122 applet
->applet_private
= NULL
;
133 vcard_set_applet_private(VCardApplet
*applet
, VCardAppletPrivate
*private,
134 VCardAppletPrivateFree private_free
)
136 if (applet
->applet_private_free
) {
137 applet
->applet_private_free(applet
->applet_private
);
139 applet
->applet_private
= private;
140 applet
->applet_private_free
= private_free
;
144 vcard_new(VCardEmul
*private, VCardEmulFree private_free
)
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;
157 vcard_reference(VCard
*vcard
)
162 vcard
->reference_count
++;
167 vcard_free(VCard
*vcard
)
169 VCardApplet
*current_applet
= NULL
;
170 VCardApplet
*next_applet
= NULL
;
175 vcard
->reference_count
--;
176 if (vcard
->reference_count
!= 0) {
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;
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
);
189 vcard_buffer_response_delete(vcard
->vcard_buffer_response
);
194 vcard_get_atr(VCard
*vcard
, unsigned char *atr
, int *atr_len
)
196 if (vcard
->vcard_get_atr
) {
197 (*vcard
->vcard_get_atr
)(vcard
, atr
, atr_len
);
200 vcard_emul_get_atr(vcard
, atr
, atr_len
);
204 vcard_set_atr_func(VCard
*card
, VCardGetAtr vcard_get_atr
)
206 card
->vcard_get_atr
= vcard_get_atr
;
211 vcard_add_applet(VCard
*card
, VCardApplet
*applet
)
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
) {
219 for (i
= 0; i
< MAX_CHANNEL
; i
++) {
220 card
->current_applet
[i
] = applet
;
230 vcard_find_applet(VCard
*card
, unsigned char *aid
, int aid_len
)
232 VCardApplet
*current_applet
;
234 for (current_applet
= card
->applet_list
; current_applet
;
235 current_applet
= current_applet
->next
) {
236 if (current_applet
->aid_len
!= aid_len
) {
239 if (memcmp(current_applet
->aid
, aid
, aid_len
) == 0) {
243 return current_applet
;
247 vcard_applet_get_aid(VCardApplet
*applet
, int *aid_len
)
249 if (applet
== NULL
) {
252 *aid_len
= applet
->aid_len
;
258 vcard_select_applet(VCard
*card
, int channel
, VCardApplet
*applet
)
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
);
269 vcard_get_current_applet_private(VCard
*card
, int channel
)
271 VCardApplet
*applet
= card
->current_applet
[channel
];
273 if (applet
== NULL
) {
276 return applet
->applet_private
;
280 vcard_process_applet_apdu(VCard
*card
, VCardAPDU
*apdu
,
281 VCardResponse
**response
)
283 if (card
->current_applet
[apdu
->a_channel
]) {
284 return card
->current_applet
[apdu
->a_channel
]->process_apdu(
285 card
, apdu
, response
);
293 /* accessor functions for the response buffer */
294 VCardBufferResponse
*
295 vcard_get_buffer_response(VCard
*card
)
297 return card
->vcard_buffer_response
;
301 vcard_set_buffer_response(VCard
*card
, VCardBufferResponse
*buffer
)
303 card
->vcard_buffer_response
= buffer
;
307 /* accessor functions for the type */
309 vcard_get_type(VCard
*card
)
315 vcard_set_type(VCard
*card
, VCardType type
)
320 /* accessor for private data */
322 vcard_get_private(VCard
*vcard
)
324 return vcard
->vcard_private
;