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 "glib-compat.h"
13 #include "vcard_emul.h"
14 #include "card_7816t.h"
16 struct VCardAppletStruct
{
18 VCardProcessAPDU process_apdu
;
19 VCardResetApplet reset_applet
;
23 VCardAppletPrivateFree applet_private_free
;
28 VCardApplet
*applet_list
;
29 VCardApplet
*current_applet
[MAX_CHANNEL
];
30 VCardBufferResponse
*vcard_buffer_response
;
32 VCardEmul
*vcard_private
;
33 VCardEmulFree vcard_private_free
;
34 VCardGetAtr vcard_get_atr
;
38 vcard_buffer_response_new(unsigned char *buffer
, int size
)
40 VCardBufferResponse
*new_buffer
;
42 new_buffer
= g_new(VCardBufferResponse
, 1);
43 new_buffer
->buffer
= (unsigned char *)g_memdup(buffer
, size
);
44 new_buffer
->buffer_len
= size
;
45 new_buffer
->current
= new_buffer
->buffer
;
46 new_buffer
->len
= size
;
51 vcard_buffer_response_delete(VCardBufferResponse
*buffer_response
)
53 if (buffer_response
== NULL
) {
56 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
);
129 vcard_set_applet_private(VCardApplet
*applet
, VCardAppletPrivate
*private,
130 VCardAppletPrivateFree private_free
)
132 if (applet
->applet_private_free
) {
133 applet
->applet_private_free(applet
->applet_private
);
135 applet
->applet_private
= private;
136 applet
->applet_private_free
= private_free
;
140 vcard_new(VCardEmul
*private, VCardEmulFree private_free
)
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;
153 vcard_reference(VCard
*vcard
)
158 vcard
->reference_count
++;
163 vcard_free(VCard
*vcard
)
165 VCardApplet
*current_applet
;
166 VCardApplet
*next_applet
;
171 vcard
->reference_count
--;
172 if (vcard
->reference_count
!= 0) {
175 if (vcard
->vcard_private_free
) {
176 (*vcard
->vcard_private_free
)(vcard
->vcard_private
);
178 for (current_applet
= vcard
->applet_list
; current_applet
;
179 current_applet
= next_applet
) {
180 next_applet
= current_applet
->next
;
181 vcard_delete_applet(current_applet
);
183 vcard_buffer_response_delete(vcard
->vcard_buffer_response
);
188 vcard_get_atr(VCard
*vcard
, unsigned char *atr
, int *atr_len
)
190 if (vcard
->vcard_get_atr
) {
191 (*vcard
->vcard_get_atr
)(vcard
, atr
, atr_len
);
194 vcard_emul_get_atr(vcard
, atr
, atr_len
);
198 vcard_set_atr_func(VCard
*card
, VCardGetAtr vcard_get_atr
)
200 card
->vcard_get_atr
= vcard_get_atr
;
205 vcard_add_applet(VCard
*card
, VCardApplet
*applet
)
207 applet
->next
= card
->applet_list
;
208 card
->applet_list
= applet
;
209 /* if our card-type is direct, always call the applet */
210 if (card
->type
== VCARD_DIRECT
) {
213 for (i
= 0; i
< MAX_CHANNEL
; i
++) {
214 card
->current_applet
[i
] = applet
;
224 vcard_find_applet(VCard
*card
, unsigned char *aid
, int aid_len
)
226 VCardApplet
*current_applet
;
228 for (current_applet
= card
->applet_list
; current_applet
;
229 current_applet
= current_applet
->next
) {
230 if (current_applet
->aid_len
!= aid_len
) {
233 if (memcmp(current_applet
->aid
, aid
, aid_len
) == 0) {
237 return current_applet
;
241 vcard_applet_get_aid(VCardApplet
*applet
, int *aid_len
)
243 if (applet
== NULL
) {
246 *aid_len
= applet
->aid_len
;
252 vcard_select_applet(VCard
*card
, int channel
, VCardApplet
*applet
)
254 assert(channel
< MAX_CHANNEL
);
256 /* If using an emulated card, make sure to log out of any already logged in
258 vcard_emul_logout(card
);
260 card
->current_applet
[channel
] = applet
;
261 /* reset the applet */
262 if (applet
&& applet
->reset_applet
) {
263 applet
->reset_applet(card
, channel
);
268 vcard_get_current_applet_private(VCard
*card
, int channel
)
270 VCardApplet
*applet
= card
->current_applet
[channel
];
272 if (applet
== NULL
) {
275 return applet
->applet_private
;
279 vcard_process_applet_apdu(VCard
*card
, VCardAPDU
*apdu
,
280 VCardResponse
**response
)
282 if (card
->current_applet
[apdu
->a_channel
]) {
283 return card
->current_applet
[apdu
->a_channel
]->process_apdu(
284 card
, apdu
, response
);
292 /* accessor functions for the response buffer */
293 VCardBufferResponse
*
294 vcard_get_buffer_response(VCard
*card
)
296 return card
->vcard_buffer_response
;
300 vcard_set_buffer_response(VCard
*card
, VCardBufferResponse
*buffer
)
302 card
->vcard_buffer_response
= buffer
;
306 /* accessor functions for the type */
308 vcard_get_type(VCard
*card
)
314 vcard_set_type(VCard
*card
, VCardType type
)
319 /* accessor for private data */
321 vcard_get_private(VCard
*vcard
)
323 return vcard
->vcard_private
;