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.
11 #define G_LOG_DOMAIN "libcacard"
14 #include "qemu-common.h"
15 #include "qemu/thread.h"
18 #include "vcard_emul.h"
19 #include "card_7816.h"
22 #include "cac.h" /* just for debugging defines */
24 #define LIBCACARD_LOG_DOMAIN "libcacard"
26 struct VReaderStruct
{
32 VReaderEmul
*reader_private
;
33 VReaderEmulFree reader_private_free
;
41 apdu_ins_to_string(int ins
)
44 case VCARD7816_INS_MANAGE_CHANNEL
:
45 return "manage channel";
46 case VCARD7816_INS_EXTERNAL_AUTHENTICATE
:
47 return "external authenticate";
48 case VCARD7816_INS_GET_CHALLENGE
:
49 return "get challenge";
50 case VCARD7816_INS_INTERNAL_AUTHENTICATE
:
51 return "internal authenticate";
52 case VCARD7816_INS_ERASE_BINARY
:
53 return "erase binary";
54 case VCARD7816_INS_READ_BINARY
:
56 case VCARD7816_INS_WRITE_BINARY
:
57 return "write binary";
58 case VCARD7816_INS_UPDATE_BINARY
:
59 return "update binary";
60 case VCARD7816_INS_READ_RECORD
:
62 case VCARD7816_INS_WRITE_RECORD
:
63 return "write record";
64 case VCARD7816_INS_UPDATE_RECORD
:
65 return "update record";
66 case VCARD7816_INS_APPEND_RECORD
:
67 return "append record";
68 case VCARD7816_INS_ENVELOPE
:
70 case VCARD7816_INS_PUT_DATA
:
72 case VCARD7816_INS_GET_DATA
:
74 case VCARD7816_INS_SELECT_FILE
:
76 case VCARD7816_INS_VERIFY
:
78 case VCARD7816_INS_GET_RESPONSE
:
79 return "get response";
80 case CAC_GET_PROPERTIES
:
81 return "get properties";
86 case CAC_UPDATE_BUFFER
:
87 return "update buffer";
88 case CAC_SIGN_DECRYPT
:
89 return "sign decrypt";
90 case CAC_GET_CERTIFICATE
:
91 return "get certificate";
98 vreader_lock(VReader
*reader
)
100 qemu_mutex_lock(&reader
->lock
);
104 vreader_unlock(VReader
*reader
)
106 qemu_mutex_unlock(&reader
->lock
);
110 * vreader constructor
113 vreader_new(const char *name
, VReaderEmul
*private,
114 VReaderEmulFree private_free
)
118 reader
= (VReader
*)g_malloc(sizeof(VReader
));
119 qemu_mutex_init(&reader
->lock
);
120 reader
->reference_count
= 1;
121 reader
->name
= g_strdup(name
);
123 reader
->id
= (vreader_id_t
)-1;
124 reader
->reader_private
= private;
125 reader
->reader_private_free
= private_free
;
129 /* get a reference */
131 vreader_reference(VReader
*reader
)
133 if (reader
== NULL
) {
136 vreader_lock(reader
);
137 reader
->reference_count
++;
138 vreader_unlock(reader
);
142 /* free a reference */
144 vreader_free(VReader
*reader
)
146 if (reader
== NULL
) {
149 vreader_lock(reader
);
150 if (reader
->reference_count
-- > 1) {
151 vreader_unlock(reader
);
154 vreader_unlock(reader
);
156 vcard_free(reader
->card
);
159 g_free(reader
->name
);
161 if (reader
->reader_private_free
) {
162 reader
->reader_private_free(reader
->reader_private
);
168 vreader_get_card(VReader
*reader
)
172 vreader_lock(reader
);
173 card
= vcard_reference(reader
->card
);
174 vreader_unlock(reader
);
179 vreader_card_is_present(VReader
*reader
)
181 VCard
*card
= vreader_get_card(reader
);
184 return VREADER_NO_CARD
;
191 vreader_get_id(VReader
*reader
)
193 if (reader
== NULL
) {
194 return (vreader_id_t
)-1;
200 vreader_set_id(VReader
*reader
, vreader_id_t id
)
202 if (reader
== NULL
) {
203 return VREADER_NO_CARD
;
210 vreader_get_name(VReader
*reader
)
212 if (reader
== NULL
) {
219 vreader_get_private(VReader
*reader
)
221 return reader
->reader_private
;
225 vreader_reset(VReader
*reader
, VCardPower power
, unsigned char *atr
, int *len
)
227 VCard
*card
= vreader_get_card(reader
);
230 return VREADER_NO_CARD
;
235 vcard_reset(card
, power
);
237 vcard_get_atr(card
, atr
, len
);
239 vcard_free(card
); /* free our reference */
244 vreader_power_on(VReader
*reader
, unsigned char *atr
, int *len
)
246 return vreader_reset(reader
, VCARD_POWER_ON
, atr
, len
);
250 vreader_power_off(VReader
*reader
)
252 return vreader_reset(reader
, VCARD_POWER_OFF
, NULL
, 0);
257 vreader_xfr_bytes(VReader
*reader
,
258 unsigned char *send_buf
, int send_buf_len
,
259 unsigned char *receive_buf
, int *receive_buf_len
)
262 VCardResponse
*response
= NULL
;
263 VCardStatus card_status
;
264 unsigned short status
;
265 VCard
*card
= vreader_get_card(reader
);
268 return VREADER_NO_CARD
;
271 apdu
= vcard_apdu_new(send_buf
, send_buf_len
, &status
);
273 response
= vcard_make_response(status
);
274 card_status
= VCARD_DONE
;
276 g_debug("%s: CLS=0x%x,INS=0x%x,P1=0x%x,P2=0x%x,Lc=%d,Le=%d %s\n",
277 __func__
, apdu
->a_cla
, apdu
->a_ins
, apdu
->a_p1
, apdu
->a_p2
,
278 apdu
->a_Lc
, apdu
->a_Le
, apdu_ins_to_string(apdu
->a_ins
));
279 card_status
= vcard_process_apdu(card
, apdu
, &response
);
281 g_debug("%s: status=%d sw1=0x%x sw2=0x%x len=%d (total=%d)\n",
282 __func__
, response
->b_status
, response
->b_sw1
,
283 response
->b_sw2
, response
->b_len
, response
->b_total_len
);
286 assert(card_status
== VCARD_DONE
);
287 if (card_status
== VCARD_DONE
) {
288 int size
= MIN(*receive_buf_len
, response
->b_total_len
);
289 memcpy(receive_buf
, response
->b_data
, size
);
290 *receive_buf_len
= size
;
292 vcard_response_delete(response
);
293 vcard_apdu_delete(apdu
);
294 vcard_free(card
); /* free our reference */
298 struct VReaderListStruct
{
299 VReaderListEntry
*head
;
300 VReaderListEntry
*tail
;
303 struct VReaderListEntryStruct
{
304 VReaderListEntry
*next
;
305 VReaderListEntry
*prev
;
310 static VReaderListEntry
*
311 vreader_list_entry_new(VReader
*reader
)
313 VReaderListEntry
*new_reader_list_entry
;
315 new_reader_list_entry
= (VReaderListEntry
*)
316 g_malloc(sizeof(VReaderListEntry
));
317 new_reader_list_entry
->next
= NULL
;
318 new_reader_list_entry
->prev
= NULL
;
319 new_reader_list_entry
->reader
= vreader_reference(reader
);
320 return new_reader_list_entry
;
324 vreader_list_entry_delete(VReaderListEntry
*entry
)
329 vreader_free(entry
->reader
);
335 vreader_list_new(void)
337 VReaderList
*new_reader_list
;
339 new_reader_list
= (VReaderList
*)g_malloc(sizeof(VReaderList
));
340 new_reader_list
->head
= NULL
;
341 new_reader_list
->tail
= NULL
;
342 return new_reader_list
;
346 vreader_list_delete(VReaderList
*list
)
348 VReaderListEntry
*current_entry
;
349 VReaderListEntry
*next_entry
= NULL
;
350 for (current_entry
= vreader_list_get_first(list
); current_entry
;
351 current_entry
= next_entry
) {
352 next_entry
= vreader_list_get_next(current_entry
);
353 vreader_list_entry_delete(current_entry
);
362 vreader_list_get_first(VReaderList
*list
)
364 return list
? list
->head
: NULL
;
368 vreader_list_get_next(VReaderListEntry
*current
)
370 return current
? current
->next
: NULL
;
374 vreader_list_get_reader(VReaderListEntry
*entry
)
376 return entry
? vreader_reference(entry
->reader
) : NULL
;
380 vreader_queue(VReaderList
*list
, VReaderListEntry
*entry
)
386 entry
->prev
= list
->tail
;
388 list
->tail
->next
= entry
;
396 vreader_dequeue(VReaderList
*list
, VReaderListEntry
*entry
)
401 if (entry
->next
== NULL
) {
402 list
->tail
= entry
->prev
;
403 } else if (entry
->prev
== NULL
) {
404 list
->head
= entry
->next
;
406 entry
->prev
->next
= entry
->next
;
407 entry
->next
->prev
= entry
->prev
;
409 if ((list
->tail
== NULL
) || (list
->head
== NULL
)) {
410 list
->head
= list
->tail
= NULL
;
412 entry
->next
= entry
->prev
= NULL
;
415 static VReaderList
*vreader_list
;
416 static QemuMutex vreader_list_mutex
;
419 vreader_list_init(void)
421 vreader_list
= vreader_list_new();
422 qemu_mutex_init(&vreader_list_mutex
);
426 vreader_list_lock(void)
428 qemu_mutex_lock(&vreader_list_mutex
);
432 vreader_list_unlock(void)
434 qemu_mutex_unlock(&vreader_list_mutex
);
438 vreader_copy_list(VReaderList
*list
)
440 VReaderList
*new_list
= NULL
;
441 VReaderListEntry
*current_entry
= NULL
;
443 new_list
= vreader_list_new();
444 if (new_list
== NULL
) {
447 for (current_entry
= vreader_list_get_first(list
); current_entry
;
448 current_entry
= vreader_list_get_next(current_entry
)) {
449 VReader
*reader
= vreader_list_get_reader(current_entry
);
450 VReaderListEntry
*new_entry
= vreader_list_entry_new(reader
);
452 vreader_free(reader
);
453 vreader_queue(new_list
, new_entry
);
459 vreader_get_reader_list(void)
461 VReaderList
*new_reader_list
;
464 new_reader_list
= vreader_copy_list(vreader_list
);
465 vreader_list_unlock();
466 return new_reader_list
;
470 vreader_get_reader_by_id(vreader_id_t id
)
472 VReader
*reader
= NULL
;
473 VReaderListEntry
*current_entry
= NULL
;
475 if (id
== (vreader_id_t
) -1) {
480 for (current_entry
= vreader_list_get_first(vreader_list
); current_entry
;
481 current_entry
= vreader_list_get_next(current_entry
)) {
482 VReader
*creader
= vreader_list_get_reader(current_entry
);
483 if (creader
->id
== id
) {
487 vreader_free(creader
);
489 vreader_list_unlock();
494 vreader_get_reader_by_name(const char *name
)
496 VReader
*reader
= NULL
;
497 VReaderListEntry
*current_entry
= NULL
;
500 for (current_entry
= vreader_list_get_first(vreader_list
); current_entry
;
501 current_entry
= vreader_list_get_next(current_entry
)) {
502 VReader
*creader
= vreader_list_get_reader(current_entry
);
503 if (strcmp(creader
->name
, name
) == 0) {
507 vreader_free(creader
);
509 vreader_list_unlock();
513 /* called from card_emul to initialize the readers */
515 vreader_add_reader(VReader
*reader
)
517 VReaderListEntry
*reader_entry
;
519 reader_entry
= vreader_list_entry_new(reader
);
520 if (reader_entry
== NULL
) {
521 return VREADER_OUT_OF_MEMORY
;
524 vreader_queue(vreader_list
, reader_entry
);
525 vreader_list_unlock();
526 vevent_queue_vevent(vevent_new(VEVENT_READER_INSERT
, reader
, NULL
));
532 vreader_remove_reader(VReader
*reader
)
534 VReaderListEntry
*current_entry
;
537 for (current_entry
= vreader_list_get_first(vreader_list
); current_entry
;
538 current_entry
= vreader_list_get_next(current_entry
)) {
539 if (current_entry
->reader
== reader
) {
543 vreader_dequeue(vreader_list
, current_entry
);
544 vreader_list_unlock();
545 vreader_list_entry_delete(current_entry
);
546 vevent_queue_vevent(vevent_new(VEVENT_READER_REMOVE
, reader
, NULL
));
551 * Generate VEVENT_CARD_INSERT or VEVENT_CARD_REMOVE based on vreader
552 * state. Separated from vreader_insert_card to allow replaying events
556 vreader_queue_card_event(VReader
*reader
)
558 vevent_queue_vevent(vevent_new(
559 reader
->card
? VEVENT_CARD_INSERT
: VEVENT_CARD_REMOVE
, reader
,
564 * insert/remove a new card. for removal, card == NULL
567 vreader_insert_card(VReader
*reader
, VCard
*card
)
569 vreader_lock(reader
);
571 /* decrement reference count */
572 vcard_free(reader
->card
);
575 reader
->card
= vcard_reference(card
);
576 vreader_unlock(reader
);
577 vreader_queue_card_event(reader
);
582 * initialize all the static reader structures