root/trunk/src/libopensc/card.c

Revision 3496, 24.3 KB (checked in by ludovic.rousseau, 7 months ago)

card.c:756: warning: unused variable 'j'

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2 * card.c: General smart card functions
3 *
4 * Copyright (C) 2001, 2002  Juha YrjölÀ <juha.yrjola@iki.fi>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21#include "internal.h"
22#include "asn1.h"
23#include <assert.h>
24#include <stdlib.h>
25#ifdef HAVE_UNISTD_H
26#include <unistd.h>
27#endif
28#include <string.h>
29
30int sc_check_sw(sc_card_t *card, unsigned int sw1, unsigned int sw2)
31{
32        if (card == NULL)
33                return SC_ERROR_INVALID_ARGUMENTS;
34        if (card->ops->check_sw == NULL)
35                return SC_ERROR_NOT_SUPPORTED;
36        return card->ops->check_sw(card, sw1, sw2);
37}
38
39void sc_format_apdu(sc_card_t *card, sc_apdu_t *apdu,
40                    int cse, int ins, int p1, int p2)
41{
42        assert(card != NULL && apdu != NULL);
43        memset(apdu, 0, sizeof(*apdu));
44        apdu->cla = (u8) card->cla;
45        apdu->cse = cse;
46        apdu->ins = (u8) ins;
47        apdu->p1 = (u8) p1;
48        apdu->p2 = (u8) p2;
49}
50
51static sc_card_t * sc_card_new(sc_context_t *ctx)
52{
53        sc_card_t *card;
54
55        if (ctx == NULL)
56                return NULL;
57
58        card = (sc_card_t *) calloc(1, sizeof(struct sc_card));
59        if (card == NULL)
60                return NULL;
61        card->ops = (struct sc_card_operations *) malloc(sizeof(struct sc_card_operations));
62        if (card->ops == NULL) {
63                free(card);
64                return NULL;
65        }
66
67        card->ctx = ctx;
68        if (sc_mutex_create(ctx, &card->mutex) != SC_SUCCESS) {
69                free(card->ops);
70                free(card);
71                return NULL;
72        }
73
74        card->type = -1;
75        card->app_count = -1;
76        card->magic = SC_CARD_MAGIC;
77
78        return card;
79}
80
81static void sc_card_free(sc_card_t *card)
82{
83        assert(sc_card_valid(card));
84        sc_free_apps(card);
85        if (card->ef_dir != NULL)
86                sc_file_free(card->ef_dir);
87        free(card->ops);
88        if (card->algorithms != NULL)
89                free(card->algorithms);
90        if (card->mutex != NULL) {
91                int r = sc_mutex_destroy(card->ctx, card->mutex);
92                if (r != SC_SUCCESS)
93                        sc_error(card->ctx, "unable to destroy mutex\n");
94        }
95        sc_mem_clear(card, sizeof(*card));
96        free(card);
97}
98
99int sc_connect_card(sc_reader_t *reader, int slot_id, sc_card_t **card_out)
100{
101        sc_card_t *card;
102        sc_context_t *ctx;
103        sc_slot_info_t *slot = _sc_get_slot_info(reader, slot_id);
104        struct sc_card_driver *driver;
105        int i, r = 0, idx, connected = 0;
106
107        if (card_out == NULL || reader == NULL)
108                return SC_ERROR_INVALID_ARGUMENTS;
109        ctx = reader->ctx;
110        SC_FUNC_CALLED(ctx, 1);
111        if (reader->ops->connect == NULL)
112                SC_FUNC_RETURN(ctx, 0, SC_ERROR_NOT_SUPPORTED);
113        if (slot == NULL)
114                SC_FUNC_RETURN(ctx, 0, SC_ERROR_SLOT_NOT_FOUND);
115
116        card = sc_card_new(ctx);
117        if (card == NULL)
118                SC_FUNC_RETURN(ctx, 1, SC_ERROR_OUT_OF_MEMORY);
119        r = reader->ops->connect(reader, slot);
120        if (r)
121                goto err;
122
123        connected = 1;
124        card->reader = reader;
125        card->slot = slot;
126        card->ctx = ctx;
127
128        /* These can be overridden by the card driver */
129        card->max_send_size = reader->driver->max_send_size;
130        card->max_recv_size = reader->driver->max_recv_size;
131
132        memcpy(card->atr, slot->atr, slot->atr_len);
133        card->atr_len = slot->atr_len;
134
135        _sc_parse_atr(reader->ctx, slot);
136
137        /* See if the ATR matches any ATR specified in the config file */
138        if ((driver = ctx->forced_driver) == NULL) {
139                if (ctx->debug >= 3)
140                        sc_debug(ctx, "matching configured ATRs\n");
141                for (i = 0; ctx->card_drivers[i] != NULL; i++) {
142                        driver = ctx->card_drivers[i];
143
144                        if (driver->atr_map == NULL ||
145                            !strcmp(driver->short_name, "default")) {
146                                driver = NULL;
147                                continue;
148                        }
149                        if (ctx->debug >= 3)
150                                sc_debug(ctx, "trying driver: %s\n", driver->short_name);
151                        idx = _sc_match_atr(card, driver->atr_map, NULL);
152                        if (idx >= 0) {
153                                struct sc_atr_table *src = &driver->atr_map[idx];
154
155                                if (ctx->debug >= 3)
156                                        sc_debug(ctx, "matched: %s\n", driver->name);
157                                /* It's up to card driver to notice these correctly */
158                                card->name = src->name;
159                                card->type = src->type;
160                                card->flags = src->flags;
161                                break;
162                        }
163                        driver = NULL;
164                }
165        }
166
167        if (driver != NULL) {
168                /* Forced driver, or matched via ATR mapping from
169                 * config file */
170                card->driver = driver;
171                memcpy(card->ops, card->driver->ops, sizeof(struct sc_card_operations));
172                if (card->ops->init != NULL) {
173                        r = card->ops->init(card);
174                        if (r) {
175                                sc_error(ctx, "driver '%s' init() failed: %s\n", card->driver->name,
176                                      sc_strerror(r));
177                                goto err;
178                        }
179                }
180        } else {
181                if (ctx->debug >= 3)
182                        sc_debug(ctx, "matching built-in ATRs\n");
183                for (i = 0; ctx->card_drivers[i] != NULL; i++) {
184                        struct sc_card_driver *drv = ctx->card_drivers[i];
185                        const struct sc_card_operations *ops = drv->ops;
186
187                        if (ctx->debug >= 3)
188                                sc_debug(ctx, "trying driver: %s\n", drv->short_name);
189                        if (ops == NULL || ops->match_card == NULL)
190                                continue;
191                        /* Needed if match_card() needs to talk with the card (e.g. card-muscle) */
192                        *card->ops = *ops;
193                        if (ops->match_card(card) != 1)
194                                continue;
195                        if (ctx->debug >= 3)
196                                sc_debug(ctx, "matched: %s\n", drv->name);
197                        memcpy(card->ops, ops, sizeof(struct sc_card_operations));
198                        card->driver = drv;
199                        r = ops->init(card);
200                        if (r) {
201                                sc_error(ctx, "driver '%s' init() failed: %s\n", drv->name,
202                                      sc_strerror(r));
203                                if (r == SC_ERROR_INVALID_CARD) {
204                                        card->driver = NULL;
205                                        continue;
206                                }
207                                goto err;
208                        }
209                        break;
210                }
211        }
212        if (card->driver == NULL) {
213                sc_error(ctx, "unable to find driver for inserted card\n");
214                r = SC_ERROR_INVALID_CARD;
215                goto err;
216        }
217        if (card->name == NULL)
218                card->name = card->driver->name;
219        *card_out = card;
220
221        sc_debug(ctx, "card info: %s, %i, 0x%X\n", card->name, card->type, card->flags);
222        SC_FUNC_RETURN(ctx, 1, 0);
223err:
224        if (connected)
225                reader->ops->disconnect(reader, slot);
226        if (card != NULL)
227                sc_card_free(card);
228        SC_FUNC_RETURN(ctx, 1, r);
229}
230
231int sc_disconnect_card(sc_card_t *card, int action)
232{
233        sc_context_t *ctx;
234        assert(sc_card_valid(card));
235        ctx = card->ctx;
236        SC_FUNC_CALLED(ctx, 1);
237        assert(card->lock_count == 0);
238        if (card->ops->finish) {
239                int r = card->ops->finish(card);
240                if (r)
241                        sc_error(card->ctx, "card driver finish() failed: %s\n",
242                              sc_strerror(r));
243        }
244        if (card->reader->ops->disconnect) {
245                int r = card->reader->ops->disconnect(card->reader, card->slot);
246                if (r)
247                        sc_error(card->ctx, "disconnect() failed: %s\n",
248                              sc_strerror(r));
249        }
250        sc_card_free(card);
251        SC_FUNC_RETURN(ctx, 1, 0);
252}
253
254int sc_reset(sc_card_t *card)
255{
256        int r, r2;
257
258        if (card == NULL)
259                return SC_ERROR_INVALID_ARGUMENTS;
260        if (card->reader->ops->reset == NULL)
261                return SC_ERROR_NOT_SUPPORTED;
262
263        r = sc_mutex_lock(card->ctx, card->mutex);
264        if (r != SC_SUCCESS)
265                return r;
266
267        r = card->reader->ops->reset(card->reader, card->slot);
268        /* invalidate cache */
269        memset(&card->cache, 0, sizeof(card->cache));
270        card->cache_valid = 0;
271
272        r2 = sc_mutex_unlock(card->ctx, card->mutex);
273        if (r2 != SC_SUCCESS) {
274                sc_error(card->ctx, "unable to release lock\n");
275                r = r != SC_SUCCESS ? r : r2;
276        }
277
278        return r;
279}
280
281int sc_lock(sc_card_t *card)
282{
283        int r = 0, r2 = 0;
284
285        SC_FUNC_CALLED(card->ctx, 3);
286       
287        if (card == NULL)
288                return SC_ERROR_INVALID_ARGUMENTS;
289        r = sc_mutex_lock(card->ctx, card->mutex);
290        if (r != SC_SUCCESS)
291                return r;
292        if (card->lock_count == 0) {
293                if (card->reader->ops->lock != NULL)
294                        r = card->reader->ops->lock(card->reader, card->slot);
295                if (r == 0)
296                        card->cache_valid = 1;
297        }
298        if (r == 0)
299                card->lock_count++;
300        r2 = sc_mutex_unlock(card->ctx, card->mutex);
301        if (r2 != SC_SUCCESS) {
302                sc_error(card->ctx, "unable to release lock\n");
303                r = r != SC_SUCCESS ? r : r2;
304        }
305        return r;
306}
307
308int sc_unlock(sc_card_t *card)
309{
310        int r, r2;
311
312        SC_FUNC_CALLED(card->ctx, 3);
313
314        if (card == NULL)
315                return SC_ERROR_INVALID_ARGUMENTS;
316        r = sc_mutex_lock(card->ctx, card->mutex);
317        if (r != SC_SUCCESS)
318                return r;
319        assert(card->lock_count >= 1);
320        if (--card->lock_count == 0) {
321                /* invalidate cache */
322                memset(&card->cache, 0, sizeof(card->cache));
323                card->cache_valid = 0;
324                /* release reader lock */
325                if (card->reader->ops->unlock != NULL)
326                        r = card->reader->ops->unlock(card->reader, card->slot);
327        }
328        r2 = sc_mutex_unlock(card->ctx, card->mutex);
329        if (r2 != SC_SUCCESS) {
330                sc_error(card->ctx, "unable to release lock\n");
331                r = (r == SC_SUCCESS) ? r2 : r;
332        }
333        return r;
334}
335
336int sc_list_files(sc_card_t *card, u8 *buf, size_t buflen)
337{
338        int r;
339
340        assert(card != NULL);
341        SC_FUNC_CALLED(card->ctx, 1);
342        if (card->ops->list_files == NULL)
343                SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
344        r = card->ops->list_files(card, buf, buflen);
345        SC_FUNC_RETURN(card->ctx, 1, r);
346}
347
348int sc_create_file(sc_card_t *card, sc_file_t *file)
349{
350        int r;
351
352        assert(card != NULL);
353        if (card->ctx->debug >= 1) {
354                char pbuf[SC_MAX_PATH_STRING_SIZE];
355                const sc_path_t *in_path = &file->path;
356
357                r = sc_path_print(pbuf, sizeof(pbuf), in_path);
358                if (r != SC_SUCCESS)
359                        pbuf[0] = '\0';
360
361                sc_debug(card->ctx, "called; type=%d, path=%s, size=%u\n",
362                                in_path->type, pbuf, file->size);
363        }
364        if (card->ops->create_file == NULL)
365                SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
366        r = card->ops->create_file(card, file);
367        SC_FUNC_RETURN(card->ctx, 1, r);
368}
369
370int sc_delete_file(sc_card_t *card, const sc_path_t *path)
371{
372        int r;
373
374        assert(card != NULL);
375        if (card->ctx->debug >= 1) {
376                char pbuf[SC_MAX_PATH_STRING_SIZE];
377
378                r = sc_path_print(pbuf, sizeof(pbuf), path);
379                if (r != SC_SUCCESS)
380                        pbuf[0] = '\0';
381
382                sc_debug(card->ctx, "called; type=%d, path=%s\n",
383                                path->type, pbuf);
384        }
385        if (card->ops->delete_file == NULL)
386                SC_FUNC_RETURN(card->ctx, 1, SC_ERROR_NOT_SUPPORTED);
387        r = card->ops->delete_file(card, path);
388        SC_FUNC_RETURN(card->ctx, 1, r);
389}
390
391int sc_read_binary(sc_card_t *card, unsigned int idx,
392                   unsigned char *buf, size_t count, unsigned long flags)
393{
394        size_t max_le = card->max_recv_size;
395        int r;
396
397        assert(card != NULL && card->ops != NULL && buf != NULL);
398        if (card->ctx->debug >= 2)
399                sc_debug(card->ctx, "called; %d bytes at index %d\n", count, idx);
400        if (count == 0)
401                return 0;
402        if (card->ops->read_binary == NULL)
403                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
404        if (count > max_le) {
405                int bytes_read = 0;
406                unsigned char *p = buf;
407
408                r = sc_lock(card);
409                SC_TEST_RET(card->ctx, r, "sc_lock() failed");
410                while (count > 0) {
411                        size_t n = count > max_le ? max_le : count;
412                        r = sc_read_binary(card, idx, p, n, flags);
413                        if (r < 0) {
414                                sc_unlock(card);
415                                SC_TEST_RET(card->ctx, r, "sc_read_binary() failed");
416                        }
417                        p += r;
418                        idx += r;
419                        bytes_read += r;
420                        count -= r;
421                        if (r == 0) {
422                                sc_unlock(card);
423                                SC_FUNC_RETURN(card->ctx, 2, bytes_read);
424                        }
425                }
426                sc_unlock(card);
427                SC_FUNC_RETURN(card->ctx, 2, bytes_read);
428        }
429        r = card->ops->read_binary(card, idx, buf, count, flags);
430        SC_FUNC_RETURN(card->ctx, 2, r);
431}
432
433int sc_write_binary(sc_card_t *card, unsigned int idx,
434                    const u8 *buf, size_t count, unsigned long flags)
435{
436        size_t max_lc = card->max_send_size;
437        int r;
438
439        assert(card != NULL && card->ops != NULL && buf != NULL);
440        if (card->ctx->debug >= 2)
441                sc_debug(card->ctx, "called; %d bytes at index %d\n", count, idx);
442        if (count == 0)
443                return 0;
444        if (card->ops->write_binary == NULL)
445                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
446        if (count > max_lc) {
447                int bytes_written = 0;
448                const u8 *p = buf;
449
450                r = sc_lock(card);
451                SC_TEST_RET(card->ctx, r, "sc_lock() failed");
452                while (count > 0) {
453                        size_t n = count > max_lc? max_lc : count;
454                        r = sc_write_binary(card, idx, p, n, flags);
455                        if (r < 0) {
456                                sc_unlock(card);
457                                SC_TEST_RET(card->ctx, r, "sc_write_binary() failed");
458                        }
459                        p += r;
460                        idx += r;
461                        bytes_written += r;
462                        count -= r;
463                        if (r == 0) {
464                                sc_unlock(card);
465                                SC_FUNC_RETURN(card->ctx, 2, bytes_written);
466                        }
467                }
468                sc_unlock(card);
469                SC_FUNC_RETURN(card->ctx, 2, bytes_written);
470        }
471        r = card->ops->write_binary(card, idx, buf, count, flags);
472        SC_FUNC_RETURN(card->ctx, 2, r);
473}
474
475int sc_update_binary(sc_card_t *card, unsigned int idx,
476                     const u8 *buf, size_t count, unsigned long flags)
477{
478        size_t max_lc = card->max_send_size;
479        int r;
480
481        assert(card != NULL && card->ops != NULL && buf != NULL);
482        if (card->ctx->debug >= 2)
483                sc_debug(card->ctx, "called; %d bytes at index %d\n", count, idx);
484        if (count == 0)
485                return 0;
486        if (card->ops->update_binary == NULL)
487                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
488        if (count > max_lc) {
489                int bytes_written = 0;
490                const u8 *p = buf;
491
492                r = sc_lock(card);
493                SC_TEST_RET(card->ctx, r, "sc_lock() failed");
494                while (count > 0) {
495                        size_t n = count > max_lc? max_lc : count;
496                        r = sc_update_binary(card, idx, p, n, flags);
497                        if (r < 0) {
498                                sc_unlock(card);
499                                SC_TEST_RET(card->ctx, r, "sc_update_binary() failed");
500                        }
501                        p += r;
502                        idx += r;
503                        bytes_written += r;
504                        count -= r;
505                        if (r == 0) {
506                                sc_unlock(card);
507                                SC_FUNC_RETURN(card->ctx, 2, bytes_written);
508                        }
509                }
510                sc_unlock(card);
511                SC_FUNC_RETURN(card->ctx, 2, bytes_written);
512        }
513        r = card->ops->update_binary(card, idx, buf, count, flags);
514        SC_FUNC_RETURN(card->ctx, 2, r);
515}
516
517int sc_select_file(sc_card_t *card,
518                   const sc_path_t *in_path,
519                   sc_file_t **file)
520{
521        int r;
522
523        assert(card != NULL && in_path != NULL);
524        if (card->ctx->debug >= 1) {
525                char pbuf[SC_MAX_PATH_STRING_SIZE];
526
527                r = sc_path_print(pbuf, sizeof(pbuf), in_path);
528                if (r != SC_SUCCESS)
529                        pbuf[0] = '\0';
530
531                sc_debug(card->ctx, "called; type=%d, path=%s\n",
532                                in_path->type, pbuf);
533        }
534        if (in_path->len > SC_MAX_PATH_SIZE)
535                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_INVALID_ARGUMENTS);
536        if (in_path->type == SC_PATH_TYPE_PATH) {
537                /* Perform a sanity check */
538                size_t i;
539                if ((in_path->len & 1) != 0)
540                        SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_INVALID_ARGUMENTS);
541                for (i = 0; i < in_path->len/2; i++) {
542                        u8 p1 = in_path->value[2*i],
543                           p2 = in_path->value[2*i+1];
544                        if ((p1 == 0x3F && p2 == 0x00) && i != 0)
545                                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_INVALID_ARGUMENTS);
546                }
547        }
548        if (card->ops->select_file == NULL)
549                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
550        r = card->ops->select_file(card, in_path, file);
551        /* Remember file path */
552        if (r == 0 && file && *file)
553                (*file)->path = *in_path;
554        SC_FUNC_RETURN(card->ctx, 1, r);
555}
556
557int sc_get_data(sc_card_t *card, unsigned int tag, u8 *buf, size_t len)
558{
559        int     r;
560
561        sc_debug(card->ctx, "called, tag=%04x\n", tag);
562        if (card->ops->get_data == NULL)
563                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
564        r = card->ops->get_data(card, tag, buf, len);
565        SC_FUNC_RETURN(card->ctx, 1, r);
566}
567
568int sc_put_data(sc_card_t *card, unsigned int tag, const u8 *buf, size_t len)
569{
570        int     r;
571
572        sc_debug(card->ctx, "called, tag=%04x\n", tag);
573        if (card->ops->put_data == NULL)
574                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
575        r = card->ops->put_data(card, tag, buf, len);
576        SC_FUNC_RETURN(card->ctx, 1, r);
577}
578
579int sc_get_challenge(sc_card_t *card, u8 *rnd, size_t len)
580{
581        int r;
582
583        assert(card != NULL);
584        SC_FUNC_CALLED(card->ctx, 2);
585        if (card->ops->get_challenge == NULL)
586                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
587        r = card->ops->get_challenge(card, rnd, len);
588        SC_FUNC_RETURN(card->ctx, 2, r);
589}
590
591int sc_read_record(sc_card_t *card, unsigned int rec_nr, u8 *buf,
592                   size_t count, unsigned long flags)
593{
594        int r;
595
596        assert(card != NULL);
597        SC_FUNC_CALLED(card->ctx, 2);
598        if (card->ops->read_record == NULL)
599                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
600        r = card->ops->read_record(card, rec_nr, buf, count, flags);
601        SC_FUNC_RETURN(card->ctx, 2, r);
602}
603
604int sc_write_record(sc_card_t *card, unsigned int rec_nr, const u8 * buf,
605                    size_t count, unsigned long flags)
606{
607        int r;
608
609        assert(card != NULL);
610        SC_FUNC_CALLED(card->ctx, 2);
611        if (card->ops->write_record == NULL)
612                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
613        r = card->ops->write_record(card, rec_nr, buf, count, flags);
614        SC_FUNC_RETURN(card->ctx, 2, r);
615}
616
617int sc_append_record(sc_card_t *card, const u8 * buf, size_t count,
618                     unsigned long flags)
619{
620        int r;
621
622        assert(card != NULL);
623        SC_FUNC_CALLED(card->ctx, 2);
624        if (card->ops->append_record == NULL)
625                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
626        r = card->ops->append_record(card, buf, count, flags);
627        SC_FUNC_RETURN(card->ctx, 2, r);
628}
629
630int sc_update_record(sc_card_t *card, unsigned int rec_nr, const u8 * buf,
631                     size_t count, unsigned long flags)
632{
633        int r;
634
635        assert(card != NULL);
636        SC_FUNC_CALLED(card->ctx, 2);
637        if (card->ops->update_record == NULL)
638                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
639        r = card->ops->update_record(card, rec_nr, buf, count, flags);
640        SC_FUNC_RETURN(card->ctx, 2, r);
641}
642
643int sc_delete_record(sc_card_t *card, unsigned int rec_nr)
644{
645        int r;
646
647        assert(card != NULL);
648        SC_FUNC_CALLED(card->ctx, 2);
649        if (card->ops->delete_record == NULL)
650                SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
651        r = card->ops->delete_record(card, rec_nr);
652        SC_FUNC_RETURN(card->ctx, 2, r);
653}
654
655int sc_card_valid(const sc_card_t *card) {
656#ifndef NDEBUG
657        assert(card != NULL);
658#endif
659        return card->magic == SC_CARD_MAGIC;
660}
661
662int
663sc_card_ctl(sc_card_t *card, unsigned long cmd, void *args)
664{
665        int r = SC_ERROR_NOT_SUPPORTED;
666
667        assert(card != NULL);
668        SC_FUNC_CALLED(card->ctx, 2);
669        if (card->ops->card_ctl != NULL)
670                r = card->ops->card_ctl(card, cmd, args);
671
672        /* suppress "not supported" error messages */
673        if (r == SC_ERROR_NOT_SUPPORTED) {
674                sc_debug(card->ctx, "card_ctl(%lu) not supported\n",
675                        (unsigned long) cmd);
676                return r;
677        }
678        SC_FUNC_RETURN(card->ctx, 2, r);
679}
680
681int _sc_card_add_algorithm(sc_card_t *card, const sc_algorithm_info_t *info)
682{
683        sc_algorithm_info_t *p;
684
685        assert(sc_card_valid(card) && info != NULL);
686        p = (sc_algorithm_info_t *) realloc(card->algorithms, (card->algorithm_count + 1) * sizeof(*info));
687        if (!p) {
688                if (card->algorithms)
689                        free(card->algorithms);
690                card->algorithms = NULL;
691                card->algorithm_count = 0;
692                return SC_ERROR_OUT_OF_MEMORY;
693        }
694        card->algorithms = p;
695        p += card->algorithm_count;
696        card->algorithm_count++;
697        *p = *info;
698        return 0;
699}
700
701int _sc_card_add_rsa_alg(sc_card_t *card, unsigned int key_length,
702                         unsigned long flags, unsigned long exponent)
703{
704        sc_algorithm_info_t info;
705
706        memset(&info, 0, sizeof(info));
707        info.algorithm = SC_ALGORITHM_RSA;
708        info.key_length = key_length;
709        info.flags = flags;
710        info.u._rsa.exponent = exponent;
711
712        return _sc_card_add_algorithm(card, &info);
713}
714
715sc_algorithm_info_t * _sc_card_find_rsa_alg(sc_card_t *card,
716                                                 unsigned int key_length)
717{
718        int i;
719
720        for (i = 0; i < card->algorithm_count; i++) {
721                sc_algorithm_info_t *info = &card->algorithms[i];
722
723                if (info->algorithm != SC_ALGORITHM_RSA)
724                        continue;
725                if (info->key_length != key_length)
726                        continue;
727                return info;
728        }
729        return NULL;
730}
731
732static int match_atr_table(sc_context_t *ctx, struct sc_atr_table *table, u8 *atr, size_t atr_len)
733{
734        u8 *card_atr_bin = atr;
735        size_t card_atr_bin_len = atr_len;
736        char card_atr_hex[3 * SC_MAX_ATR_SIZE];
737        size_t card_atr_hex_len;
738        unsigned int i = 0;
739
740        if (ctx == NULL || table == NULL || atr == NULL)
741                return -1;
742        sc_bin_to_hex(card_atr_bin, card_atr_bin_len, card_atr_hex, sizeof(card_atr_hex), ':');
743        card_atr_hex_len = strlen(card_atr_hex);
744
745        if (ctx->debug >= 4)
746                sc_debug(ctx, "ATR     : %s\n", card_atr_hex);
747
748        for (i = 0; table[i].atr != NULL; i++) {
749                const char *tatr = table[i].atr;
750                const char *matr = table[i].atrmask;
751                size_t tatr_len = strlen(tatr);
752                u8 mbin[SC_MAX_ATR_SIZE], tbin[SC_MAX_ATR_SIZE];
753                size_t mbin_len, tbin_len, s, matr_len;
754                size_t fix_hex_len = card_atr_hex_len;
755                size_t fix_bin_len = card_atr_bin_len;
756#ifdef __APPLE__
757                unsigned int j = 0;
758#endif
759
760                if (ctx->debug >= 4)
761                        sc_debug(ctx, "ATR try : %s\n", tatr);
762
763#ifdef __APPLE__
764                /* Leopard PCSC bug */
765                tbin_len = sizeof(tbin);
766                sc_hex_to_bin(tatr, tbin, &tbin_len);
767               
768                if (card_atr_bin_len == SC_MAX_ATR_SIZE && tbin_len < SC_MAX_ATR_SIZE) {
769                        char card_atr_hex_tmp[3 * SC_MAX_ATR_SIZE];
770                        for(j=tbin_len;j<SC_MAX_ATR_SIZE;j++)
771                                if (card_atr_bin[j] != 0x0)
772                                        goto not_apple_bug;
773
774                        sc_bin_to_hex(card_atr_bin, tbin_len, card_atr_hex_tmp, sizeof(card_atr_hex_tmp), ':');
775                        fix_hex_len = strlen(card_atr_hex_tmp);
776                        fix_bin_len = tbin_len;
777                        if (ctx->debug >= 4)
778                                sc_debug(ctx, "ATR fix : %s\n", card_atr_hex_tmp);
779
780                }
781not_apple_bug:         
782#endif
783                if (tatr_len != fix_hex_len) {
784                        if (ctx->debug >= 5)
785                                sc_debug(ctx, "ignored - wrong length\n", tatr);
786                        continue;
787                }
788                if (matr != NULL) {
789                        if (ctx->debug >= 4)
790                                sc_debug(ctx, "ATR mask: %s\n", matr);
791
792                        matr_len = strlen(matr);
793                        if (tatr_len != matr_len)
794                                continue;
795                        tbin_len = sizeof(tbin);
796                        sc_hex_to_bin(tatr, tbin, &tbin_len);
797                        mbin_len = sizeof(mbin);
798                        sc_hex_to_bin(matr, mbin, &mbin_len);
799                        if (mbin_len != fix_bin_len) {
800                                sc_error(ctx,"length of atr and atr mask do not match - ignored: %s - %s", tatr, matr);
801                                continue;
802                        }
803                        for (s = 0; s < tbin_len; s++) {
804                                /* reduce tatr with mask */
805                                tbin[s] = (tbin[s] & mbin[s]);
806                                /* create copy of card_atr_bin masked) */
807                                mbin[s] = (card_atr_bin[s] & mbin[s]);
808                        }
809                        if (memcmp(tbin, mbin, tbin_len) != 0)
810                                continue;
811                } else {
812                        if (strncasecmp(tatr, card_atr_hex, tatr_len) != 0)
813                                continue;
814                }
815                return i;
816        }
817        return -1;
818}
819
820int _sc_match_atr(sc_card_t *card, struct sc_atr_table *table, int *type_out)
821{
822        int res;
823
824        if (card == NULL)
825                return -1;
826        res = match_atr_table(card->ctx, table, card->atr, card->atr_len);
827        if (res < 0)
828                return res;
829        if (type_out != NULL)
830                *type_out = table[res].type;
831        return res;
832}
833
834scconf_block *_sc_match_atr_block(sc_context_t *ctx, struct sc_card_driver *driver, u8 *atr, size_t atr_len)
835{
836        struct sc_card_driver *drv;
837        struct sc_atr_table *table;
838        int res;
839
840        if (ctx == NULL)
841                return NULL;
842        if (driver) {
843                drv = driver;
844                table = drv->atr_map;
845                res = match_atr_table(ctx, table, atr, atr_len);
846                if (res < 0)
847                        return NULL;
848                return table[res].card_atr;
849        } else {
850                unsigned int i;
851
852                for (i = 0; ctx->card_drivers[i] != NULL; i++) {
853                        drv = ctx->card_drivers[i];
854                        table = drv->atr_map;
855                        res = match_atr_table(ctx, table, atr, atr_len);
856                        if (res < 0)
857                                continue;
858                        return table[res].card_atr;
859                }
860        }
861        return NULL;
862}
863
864int _sc_add_atr(sc_context_t *ctx, struct sc_card_driver *driver, struct sc_atr_table *src)
865{
866        struct sc_atr_table *map, *dst;
867
868        map = (struct sc_atr_table *) realloc(driver->atr_map,
869                        (driver->natrs + 2) * sizeof(struct sc_atr_table));
870        if (!map)
871                return SC_ERROR_OUT_OF_MEMORY;
872        driver->atr_map = map;
873        dst = &driver->atr_map[driver->natrs++];
874        memset(dst, 0, sizeof(*dst));
875        memset(&driver->atr_map[driver->natrs], 0, sizeof(struct sc_atr_table));
876        dst->atr = strdup(src->atr);
877        if (!dst->atr)
878                return SC_ERROR_OUT_OF_MEMORY;
879        if (src->atrmask) {
880                dst->atrmask = strdup(src->atrmask);
881                if (!dst->atrmask)
882                        return SC_ERROR_OUT_OF_MEMORY;
883        } else {
884                dst->atrmask = NULL;
885        }
886        if (src->name) {
887                dst->name = strdup(src->name);
888                if (!dst->name)
889                        return SC_ERROR_OUT_OF_MEMORY;
890        } else {
891                dst->name = NULL;
892        }
893        dst->type = src->type;
894        dst->flags = src->flags;
895        dst->card_atr = src->card_atr;
896        return SC_SUCCESS;
897}
898
899int _sc_free_atr(sc_context_t *ctx, struct sc_card_driver *driver)
900{
901        unsigned int i;
902
903        for (i = 0; i < driver->natrs; i++) {
904                struct sc_atr_table *src = &driver->atr_map[i];
905
906                if (src->atr)
907                        free(src->atr);
908                if (src->atrmask)
909                        free(src->atrmask);
910                if (src->name)
911                        free(src->name);
912                src->card_atr = NULL;
913                src = NULL;
914        }
915        if (driver->atr_map)
916                free(driver->atr_map);
917        driver->atr_map = NULL;
918        driver->natrs = 0;
919
920        return SC_SUCCESS;
921}
922
923int _sc_check_forced_protocol(sc_context_t *ctx, u8 *atr, size_t atr_len, unsigned int *protocol)
924{
925        scconf_block *atrblock = NULL;
926        int ok = 0;
927
928        if (!protocol)
929                return 0;
930        atrblock = _sc_match_atr_block(ctx, NULL, atr, atr_len);
931        if (atrblock != NULL) {
932                const char *forcestr;
933
934                forcestr = scconf_get_str(atrblock, "force_protocol", "unknown");
935                if (!strcmp(forcestr, "t0")) {
936                        *protocol = SC_PROTO_T0;
937                        ok = 1;
938                } else if (!strcmp(forcestr, "t1")) {
939                        *protocol = SC_PROTO_T1;
940                        ok = 1;
941                } else if (!strcmp(forcestr, "raw")) {
942                        *protocol = SC_PROTO_RAW;
943                        ok = 1;
944                }
945                if (ok)
946                        sc_debug(ctx, "force_protocol: %s\n", forcestr);
947        }
948        return ok;
949}
950
951scconf_block *sc_get_conf_block(sc_context_t *ctx, const char *name1, const char *name2, int priority)
952{
953        int i;
954        scconf_block *conf_block = NULL;
955       
956        for (i = 0; ctx->conf_blocks[i] != NULL; i++) {
957                scconf_block **blocks;
958               
959                blocks = scconf_find_blocks(ctx->conf, ctx->conf_blocks[i], name1, name2);
960                if (blocks != NULL) {
961                        conf_block = blocks[0];
962                        free(blocks);
963                }
964                if (conf_block != NULL && priority)
965                        break;
966        }
967        return conf_block;
968}
Note: See TracBrowser for help on using the browser.