static int list_readers(sc_context_t *ctx) { char card_atr[0x3e]; sc_card_t *card; sc_reader_t *reader; size_t i, rcount = sc_ctx_get_reader_count(ctx); if (rcount == 0) { printf("No smart card readers found.\n"); return 0; } printf("%-4s %-7s %s\n", "Nr.", "Driver", "Smart Card Reader"); for (i = 0; i < rcount; i++) { reader = sc_ctx_get_reader(ctx, i); memset(card_atr, '\0', sizeof card_atr); if (sc_detect_card_presence(reader) & SC_READER_CARD_PRESENT) { if (sc_connect_card(reader, &card) == SC_SUCCESS) { sc_bin_to_hex(card->atr.value, card->atr.len, card_atr, sizeof card_atr, ':'); } sc_disconnect_card(card); } else { strncpy(card_atr, "[no card present]", sizeof card_atr); } printf("%-4d %-7s %s\n", i, reader->driver->short_name, reader->name); printf(" ATR: %s\n", card_atr); } return 0; }
CK_RV card_detect_all(void) { unsigned int i; sc_log(context, "Detect all cards"); /* Detect cards in all initialized readers */ for (i=0; i< sc_ctx_get_reader_count(context); i++) { sc_reader_t *reader = sc_ctx_get_reader(context, i); if (reader->flags & SC_READER_REMOVED) { struct sc_pkcs11_slot *slot; card_removed(reader); while ((slot = reader_get_slot(reader))) { empty_slot(slot); } _sc_delete_reader(context, reader); i--; } else { if (!reader_get_slot(reader)) initialize_reader(reader); else card_detect(sc_ctx_get_reader(context, i)); } } sc_log(context, "All cards detected"); return CKR_OK; }
CK_RV card_detect_all(void) { unsigned int i; /* Detect cards in all initialized readers */ for (i=0; i< sc_ctx_get_reader_count(context); i++) { sc_reader_t *reader = sc_ctx_get_reader(context, i); if (!reader_get_slot(reader)) initialize_reader(reader); card_detect(sc_ctx_get_reader(context, i)); } return CKR_OK; }
int initialize(int reader_id, int verbose, sc_context_t **ctx, sc_reader_t **reader) { unsigned int i, reader_count; if (!ctx || !reader) return SC_ERROR_INVALID_ARGUMENTS; int r = sc_establish_context(ctx, ""); if (r < 0 || !*ctx) { fprintf(stderr, "Failed to create initial context: %s", sc_strerror(r)); return r; } (*ctx)->debug = verbose; (*ctx)->enable_default_driver = 1; reader_count = sc_ctx_get_reader_count(*ctx); if (reader_count == 0) { sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "No reader not found.\n"); return SC_ERROR_NO_READERS_FOUND; } if (reader_id < 0) { /* Automatically try to skip to a reader with a card if reader not specified */ for (i = 0; i < reader_count; i++) { *reader = sc_ctx_get_reader(*ctx, i); if (sc_detect_card_presence(*reader) & SC_READER_CARD_PRESENT) { reader_id = i; sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "Using the first reader" " with a card: %s", (*reader)->name); break; } } if (reader_id >= reader_count) { sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "No card found, using the first reader."); reader_id = 0; } } if (reader_id >= reader_count) { sc_debug(*ctx, SC_LOG_DEBUG_NORMAL, "Invalid reader number " "(%d), only %d available.\n", reader_id, reader_count); return SC_ERROR_NO_READERS_FOUND; } *reader = sc_ctx_get_reader(*ctx, reader_id); return SC_SUCCESS; }
CK_RV C_Finalize(CK_VOID_PTR pReserved) { int i; void *p; sc_pkcs11_slot_t *slot; CK_RV rv; if (pReserved != NULL_PTR) return CKR_ARGUMENTS_BAD; #if !defined(_WIN32) sc_notify_close(); #endif if (context == NULL) return CKR_CRYPTOKI_NOT_INITIALIZED; rv = sc_pkcs11_lock(); if (rv != CKR_OK) return rv; sc_log(context, "C_Finalize()"); /* cancel pending calls */ in_finalize = 1; sc_cancel(context); /* remove all cards from readers */ for (i=0; i < (int)sc_ctx_get_reader_count(context); i++) card_removed(sc_ctx_get_reader(context, i)); while ((p = list_fetch(&sessions))) free(p); list_destroy(&sessions); while ((slot = list_fetch(&virtual_slots))) { list_destroy(&slot->objects); list_destroy(&slot->logins); free(slot); } list_destroy(&virtual_slots); sc_release_context(context); context = NULL; /* Release and destroy the mutex */ sc_pkcs11_free_lock(); return rv; }
static int list_readers(void) { unsigned int i, rcount = sc_ctx_get_reader_count(ctx); if (rcount == 0) { printf("No readers configured!\n"); return 0; } printf("Readers known about:\n"); printf("Nr. Driver Name\n"); for (i = 0; i < rcount; i++) { sc_reader_t *screader = sc_ctx_get_reader(ctx, i); printf("%-7d%-11s%s\n", i, screader->driver->short_name, screader->name); } return 0; }
CK_RV C_Initialize(CK_VOID_PTR pInitArgs) { CK_RV rv; #if !defined(_WIN32) pid_t current_pid = getpid(); #endif int rc; unsigned int i; sc_context_param_t ctx_opts; #if !defined(_WIN32) /* Handle fork() exception */ if (current_pid != initialized_pid) { if (context) context->flags |= SC_CTX_FLAG_TERMINATE; C_Finalize(NULL_PTR); } initialized_pid = current_pid; in_finalize = 0; #endif if (context != NULL) { sc_log(context, "C_Initialize(): Cryptoki already initialized\n"); return CKR_CRYPTOKI_ALREADY_INITIALIZED; } rv = sc_pkcs11_init_lock((CK_C_INITIALIZE_ARGS_PTR) pInitArgs); if (rv != CKR_OK) goto out; /* set context options */ memset(&ctx_opts, 0, sizeof(sc_context_param_t)); ctx_opts.ver = 0; ctx_opts.app_name = MODULE_APP_NAME; ctx_opts.thread_ctx = &sc_thread_ctx; rc = sc_context_create(&context, &ctx_opts); if (rc != SC_SUCCESS) { rv = CKR_GENERAL_ERROR; goto out; } /* Load configuration */ load_pkcs11_parameters(&sc_pkcs11_conf, context); /* List of sessions */ list_init(&sessions); list_attributes_seeker(&sessions, session_list_seeker); /* List of slots */ list_init(&virtual_slots); list_attributes_seeker(&virtual_slots, slot_list_seeker); /* Create a slot for a future "PnP" stuff. */ if (sc_pkcs11_conf.plug_and_play) { create_slot(NULL); } /* Create slots for readers found on initialization, only if in 2.11 mode */ if (!sc_pkcs11_conf.plug_and_play) { for (i=0; i<sc_ctx_get_reader_count(context); i++) { initialize_reader(sc_ctx_get_reader(context, i)); } } out: if (context != NULL) sc_log(context, "C_Initialize() = %s", lookup_enum ( RV_T, rv )); if (rv != CKR_OK) { if (context != NULL) { sc_release_context(context); context = NULL; } /* Release and destroy the mutex */ sc_pkcs11_free_lock(); } return rv; }
int sc_test_init(int *argc, char *argv[]) { char *opt_driver = NULL, *app_name; int opt_debug = 0, opt_reader = -1; int i, c, rc; sc_context_param_t ctx_param; if ((app_name = strrchr(argv[0], '/')) != NULL) app_name++; else app_name = argv[0]; while ((c = getopt_long(*argc, argv, "r:c:d", options, NULL)) != -1) { switch (c) { case 'r': opt_reader = atoi(optarg); break; case 'c': opt_driver = optarg; break; case 'd': opt_debug++; break; default: fprintf(stderr, "usage: %s [-r reader] [-c driver] [-d]\n", app_name); exit(1); } } *argc = optind; printf("Using libopensc version %s.\n", sc_get_version()); memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; i = sc_context_create(&ctx, &ctx_param); if (i != SC_SUCCESS) { printf("Failed to establish context: %s\n", sc_strerror(i)); return i; } ctx->debug = opt_debug; if (opt_reader >= sc_ctx_get_reader_count(ctx)) { fprintf(stderr, "Illegal reader number.\n" "Only %d reader(s) configured.\n", sc_ctx_get_reader_count(ctx)); exit(1); } while (1) { if (opt_reader >= 0) { rc = sc_detect_card_presence(sc_ctx_get_reader(ctx, opt_reader)); printf("Card %s.\n", rc == 1 ? "present" : "absent"); if (rc < 0) return rc; } else { for (i = rc = 0; rc != 1 && i < sc_ctx_get_reader_count(ctx); i++) rc = sc_detect_card_presence(sc_ctx_get_reader(ctx, opt_reader)); if (rc == 1) opt_reader = i - 1; } if (rc > 0) { printf("Card detected in reader '%s'\n",sc_ctx_get_reader(ctx, opt_reader)->name); break; } if (rc < 0) return rc; printf("Please insert a smart card. Press return to continue"); fflush(stdout); while (getc(stdin) != '\n') ; } printf("Connecting... "); fflush(stdout); i = sc_connect_card(sc_ctx_get_reader(ctx, opt_reader), &card); if (i != SC_SUCCESS) { printf("Connecting to card failed: %s\n", sc_strerror(i)); return i; } printf("connected.\n"); { char tmp[SC_MAX_ATR_SIZE*3]; sc_bin_to_hex(card->atr, card->atr_len, tmp, sizeof(tmp) - 1, ':'); printf("ATR = %s\n",tmp); } if (opt_driver != NULL) { rc = sc_set_card_driver(ctx, opt_driver); if (rc != 0) { fprintf(stderr, "Driver '%s' not found!\n", opt_driver); return rc; } } return 0; }
int util_connect_card(sc_context_t *ctx, sc_card_t **cardp, int reader_id, int slot_id, int wait, int verbose) { sc_reader_t *reader; sc_card_t *card; int r; if (wait) { sc_reader_t *readers[16]; int slots[16]; unsigned int i; int j, k, found; unsigned int event; for (i = k = 0; i < sc_ctx_get_reader_count(ctx); i++) { if (reader_id >= 0 && (unsigned int)reader_id != i) continue; reader = sc_ctx_get_reader(ctx, i); for (j = 0; j < reader->slot_count; j++, k++) { readers[k] = reader; slots[k] = j; } } //printf("Waiting for card to be inserted...\n"); r = sc_wait_for_event(readers, slots, k, SC_EVENT_CARD_INSERTED, &found, &event, -1); if (r < 0) { syslog(LOG_ERR, "Error while waiting for card: %s\n", sc_strerror(r)); return 3; } reader = readers[found]; slot_id = slots[found]; } else { if (sc_ctx_get_reader_count(ctx) == 0) { syslog(LOG_ERR, "No smart card readers found.\n"); return 1; } if (reader_id < 0) { unsigned int i; /* Automatically try to skip to a reader with a card if reader not specified */ for (i = 0; i < sc_ctx_get_reader_count(ctx); i++) { reader = sc_ctx_get_reader(ctx, i); if (sc_detect_card_presence(reader, 0) & SC_SLOT_CARD_PRESENT) { reader_id = i; syslog(LOG_NOTICE, "Using reader with a card: %s\n", reader->name); goto autofound; } } reader_id = 0; } autofound: if ((unsigned int)reader_id >= sc_ctx_get_reader_count(ctx)) { syslog(LOG_ERR, "Illegal reader number. " "Only %d reader(s) configured.\n", sc_ctx_get_reader_count(ctx)); return 1; } reader = sc_ctx_get_reader(ctx, reader_id); slot_id = 0; if (sc_detect_card_presence(reader, 0) <= 0) { syslog(LOG_ERR, "Card not present.\n"); return 3; } } if (verbose) printf("Connecting to card in reader %s...\n", reader->name); if ((r = sc_connect_card(reader, slot_id, &card)) < 0) { syslog(LOG_ERR, "Failed to connect to card: %s\n", sc_strerror(r)); return 1; } if (verbose) printf("Using card driver %s.\n", card->driver->name); if ((r = sc_lock(card)) < 0) { syslog(LOG_ERR, "Failed to lock card: %s\n", sc_strerror(r)); sc_disconnect_card(card, 0); return 1; } *cardp = card; return 0; }
static int pcsc_detect_readers(sc_context_t *ctx, void *prv_data) { struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *) prv_data; LONG rv; DWORD reader_buf_size; char *reader_buf = NULL, *reader_name; const char *mszGroups = NULL; int ret = SC_ERROR_INTERNAL; SC_FUNC_CALLED(ctx, 3); if (!gpriv) { ret = SC_ERROR_NO_READERS_FOUND; goto out; } sc_debug(ctx, "Probing pcsc readers"); do { if (gpriv->pcsc_ctx == -1) { /* * Cannot call SCardListReaders with -1 * context as in Windows ERROR_INVALID_HANDLE * is returned instead of SCARD_E_INVALID_HANDLE */ rv = SCARD_E_INVALID_HANDLE; } else { rv = gpriv->SCardListReaders(gpriv->pcsc_ctx, NULL, NULL, (LPDWORD) &reader_buf_size); } if (rv != SCARD_S_SUCCESS) { if (rv != SCARD_E_INVALID_HANDLE) { PCSC_ERROR(ctx, "SCardListReaders failed", rv); ret = pcsc_ret_to_error(rv); goto out; } sc_debug(ctx, "Establish pcsc context"); rv = gpriv->SCardEstablishContext(SCARD_SCOPE_USER, NULL, NULL, &gpriv->pcsc_ctx); if (rv != SCARD_S_SUCCESS) { PCSC_ERROR(ctx, "SCardEstablishContext failed", rv); ret = pcsc_ret_to_error(rv); goto out; } rv = SCARD_E_INVALID_HANDLE; } } while (rv != SCARD_S_SUCCESS); reader_buf = (char *) malloc(sizeof(char) * reader_buf_size); if (!reader_buf) { ret = SC_ERROR_OUT_OF_MEMORY; goto out; } rv = gpriv->SCardListReaders(gpriv->pcsc_ctx, mszGroups, reader_buf, (LPDWORD) &reader_buf_size); if (rv != SCARD_S_SUCCESS) { PCSC_ERROR(ctx, "SCardListReaders failed", rv); ret = pcsc_ret_to_error(rv); goto out; } for (reader_name = reader_buf; *reader_name != '\x0'; reader_name += strlen (reader_name) + 1) { sc_reader_t *reader = NULL; struct pcsc_private_data *priv = NULL; struct pcsc_slot_data *pslot = NULL; sc_slot_info_t *slot = NULL; unsigned int i; int found = 0; for (i=0;i < sc_ctx_get_reader_count (ctx) && !found;i++) { sc_reader_t *reader2 = sc_ctx_get_reader (ctx, i); if (reader2 == NULL) { ret = SC_ERROR_INTERNAL; goto err1; } if (reader2->ops == &pcsc_ops && !strcmp (reader2->name, reader_name)) { found = 1; } } /* Reader already available, skip */ if (found) { continue; } sc_debug(ctx, "Found new pcsc reader '%s'", reader_name); if ((reader = (sc_reader_t *) calloc(1, sizeof(sc_reader_t))) == NULL) { ret = SC_ERROR_OUT_OF_MEMORY; goto err1; } if ((priv = (struct pcsc_private_data *) malloc(sizeof(struct pcsc_private_data))) == NULL) { ret = SC_ERROR_OUT_OF_MEMORY; goto err1; } if ((pslot = (struct pcsc_slot_data *) malloc(sizeof(struct pcsc_slot_data))) == NULL) { ret = SC_ERROR_OUT_OF_MEMORY; goto err1; } reader->drv_data = priv; reader->ops = &pcsc_ops; reader->driver = &pcsc_drv; reader->slot_count = 1; if ((reader->name = strdup(reader_name)) == NULL) { ret = SC_ERROR_OUT_OF_MEMORY; goto err1; } priv->gpriv = gpriv; if ((priv->reader_name = strdup(reader_name)) == NULL) { ret = SC_ERROR_OUT_OF_MEMORY; goto err1; } slot = &reader->slot[0]; memset(slot, 0, sizeof(*slot)); slot->drv_data = pslot; memset(pslot, 0, sizeof(*pslot)); if (_sc_add_reader(ctx, reader)) { ret = SC_SUCCESS; /* silent ignore */ goto err1; } refresh_slot_attributes(reader, slot); continue; err1: if (priv != NULL) { if (priv->reader_name) free(priv->reader_name); free(priv); } if (reader != NULL) { if (reader->name) free(reader->name); free(reader); } if (slot != NULL) free(pslot); goto out; } ret = SC_SUCCESS; out: if (reader_buf != NULL) free (reader_buf); SC_FUNC_RETURN(ctx, 3, ret); }
CK_RV C_Initialize(CK_VOID_PTR pInitArgs) { CK_RV rv; #if !defined(_WIN32) pid_t current_pid = getpid(); #endif int rc; unsigned int i; sc_context_param_t ctx_opts; /* Handle fork() exception */ #if !defined(_WIN32) if (current_pid != initialized_pid) { C_Finalize(NULL_PTR); } initialized_pid = current_pid; in_finalize = 0; #endif if (context != NULL) { sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_Initialize(): Cryptoki already initialized\n"); return CKR_CRYPTOKI_ALREADY_INITIALIZED; } rv = sc_pkcs11_init_lock((CK_C_INITIALIZE_ARGS_PTR) pInitArgs); if (rv != CKR_OK) goto out; /* set context options */ memset(&ctx_opts, 0, sizeof(sc_context_param_t)); ctx_opts.ver = 0; ctx_opts.app_name = "opensc-pkcs11"; ctx_opts.thread_ctx = &sc_thread_ctx; rc = sc_context_create(&context, &ctx_opts); if (rc != SC_SUCCESS) { rv = CKR_GENERAL_ERROR; goto out; } /* Load configuration */ load_pkcs11_parameters(&sc_pkcs11_conf, context); /* List of sessions */ list_init(&sessions); list_attributes_seeker(&sessions, session_list_seeker); /* List of slots */ list_init(&virtual_slots); list_attributes_seeker(&virtual_slots, slot_list_seeker); /* Create a slot for a future "PnP" stuff. */ if (sc_pkcs11_conf.plug_and_play) { create_slot(NULL); } /* Create slots for readers found on initialization */ for (i=0; i<sc_ctx_get_reader_count(context); i++) { initialize_reader(sc_ctx_get_reader(context, i)); } /* Set initial event state on slots */ for (i=0; i<list_size(&virtual_slots); i++) { sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i); slot->events = 0; /* Initially there are no events */ } out: if (context != NULL) sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_Initialize() = %s", lookup_enum ( RV_T, rv )); if (rv != CKR_OK) { if (context != NULL) { sc_release_context(context); context = NULL; } /* Release and destroy the mutex */ sc_pkcs11_free_lock(); } return rv; }
int main( int argc, char *argv[] ){ const struct option options[]={ { "help", 0, NULL, 'h' }, { "verbose", 0, NULL, 'v' }, { "reader", 1, NULL, 'r' }, { "pin", 1, NULL, 'p' }, { "puk", 1, NULL, 'u' }, { "pin0", 1, NULL, '0' }, { "pin1", 1, NULL, '1' }, { NULL, 0, NULL, 0 } }; sc_context_t *ctx; sc_context_param_t ctx_param; sc_card_t *card; int do_help=0, do_unblock=0, do_change=0, do_nullpin=0, do_readcert=0, do_writecert=0; u8 newpin[32]; char *certfile=NULL, *p; int r, oerr=0, reader=0, debug=0, newlen=0, pin_nr=-1, cert_nr=-1; size_t i; while((r=getopt_long(argc,argv,"hvr:p:u:0:1:",options,NULL))!=EOF) switch(r){ case 'h': ++do_help; break; case 'v': ++debug; break; case 'r': reader=atoi(optarg); break; case 'p': set_pin(pinlist[0].value, &pinlist[0].len, optarg); break; case 'u': set_pin(pinlist[1].value, &pinlist[1].len, optarg); break; case '0': set_pin(pinlist[2].value, &pinlist[2].len, optarg); break; case '1': set_pin(pinlist[3].value, &pinlist[3].len, optarg); break; default: ++oerr; } if(do_help){ fprintf(stderr,"This is netkey-tool V1.0, May 15 2005, Copyright Peter Koch <*****@*****.**>\n"); fprintf(stderr,"usage: %s <options> command\n", argv[0]); fprintf(stderr,"\nOptions:\n"); fprintf(stderr," -v : verbose, may be specified several times\n"); fprintf(stderr," --reader <num>, -r <num> : use reader num (default 0)\n"); fprintf(stderr," --pin <pin>, -p <pin> : current value of global PIN\n"); fprintf(stderr," --puk <pin>, -u <pin> : current value of global PUK\n"); fprintf(stderr," --pin0 <pin>, -0 <pin> : current value of local PIN0\n"); fprintf(stderr," --pin1 <pin>, -1 <pin> : current value of local PIN1\n"); fprintf(stderr,"\nCommands:\n"); fprintf(stderr," unblock {pin | pin0 | pin1}\n"); fprintf(stderr," change {pin | puk | pin0 | pin1} <new pin>\n"); fprintf(stderr," nullpin <new pin>\n"); fprintf(stderr," cert <certnum> <filepath>\n"); fprintf(stderr," cert <filepath> <certnum>\n"); fprintf(stderr,"\nExamples:\n"); fprintf(stderr,"list PINs and Certs without changing anything. Try this first!!\n"); fprintf(stderr," %s\n", argv[0]); fprintf(stderr,"\nlist PINs and Certs and initial PUK-value (after verification of global PIN)\n"); fprintf(stderr," %s --pin 123456\n", argv[0]); fprintf(stderr,"\nchange local PIN0 to 654321 after verification of global PIN\n"); fprintf(stderr," %s --pin 123456 change pin0 654321\n", argv[0]); fprintf(stderr,"\nchange global PIN from hex 01:02:03:04:05:06 to ascii 123456\n"); fprintf(stderr," %s --pin 01:02:03:04:05:06 change pin 123456\n", argv[0]); fprintf(stderr,"\nunblock global PIN with global PUK\n"); fprintf(stderr," %s --puk 12345678 unblock pin\n", argv[0]); fprintf(stderr,"\nset global PIN to initial value when in NullPin-state\n"); fprintf(stderr," %s nullpin 123456\n", argv[0]); fprintf(stderr,"\nstore Certificate into card at position 2 and read it back into file\n"); fprintf(stderr," %s --pin1 123456 cert /tmp/cert1 2\n", argv[0]); fprintf(stderr," %s cert 2 /tmp/cert2\n", argv[0]); fprintf(stderr,"\nBe carful - this tool may destroy your card\n"); fprintf(stderr,"\nQuestions? Comments? ==> [email protected]\n"); exit(1); } if(optind==argc-2 && !strcmp(argv[optind],"unblock")){ ++optind, do_unblock=1; pin_nr=pin_string2int(argv[optind++]); if(pin_nr<0 || pin_nr==1) ++oerr; } if(optind==argc-3 && !strcmp(argv[optind],"change")){ ++optind, do_change=1; pin_nr=pin_string2int(argv[optind++]); if(pin_nr<0 || pin_nr>3) ++oerr; set_pin(newpin,&newlen,argv[optind++]); } if(optind==argc-2 && !strcmp(argv[optind],"nullpin")){ ++optind, do_nullpin=1; set_pin(newpin,&newlen,argv[optind++]); } if(optind==argc-3 && !strcmp(argv[optind],"cert")){ ++optind; cert_nr=strtol(argv[optind],&p,10); if(argv[optind][0] && !*p && cert_nr>=0 && cert_nr<(int)(sizeof(certlist)/sizeof(certlist[0]))){ do_readcert=1, certfile=argv[optind+1]; } else { do_writecert=1, certfile=argv[optind]; cert_nr=strtol(argv[optind+1],&p,10); if(!argv[optind][0] || *p || cert_nr<0 || cert_nr>=(int)(sizeof(certlist)/sizeof(certlist[0]))) ++oerr; } optind+=2; } if(oerr || optind!=argc){ fprintf(stderr,"%s: invalid usage, try --help\n", argv[0]); exit(1); } memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = argv[0]; r = sc_context_create(&ctx, &ctx_param); if(r < 0){ fprintf(stderr,"Establish-Context failed: %s\n", sc_strerror(r)); exit(1); } ctx->debug=debug; if(ctx->debug>0) printf("Context for application \"%s\" created, Debug=%d\n", ctx->app_name, ctx->debug); for(i=0;ctx->card_drivers[i];++i) if(!strcmp("tcos", ctx->card_drivers[i]->short_name)) break; if(!ctx->card_drivers[i]){ fprintf(stderr,"Context does not support TCOS-cards\n"); exit(1); } printf("%d Reader detected\n", sc_ctx_get_reader_count(ctx)); for(i=0; i < sc_ctx_get_reader_count(ctx); ++i){ sc_reader_t *myreader = sc_ctx_get_reader(ctx, i); printf("%lu: %s, Driver: %s, %d Slot(s)\n", (unsigned long) i, myreader->name, myreader->driver->name, myreader->slot_count); } if(reader < 0 || reader >= (int)sc_ctx_get_reader_count(ctx)){ fprintf(stderr,"Cannot open reader %d\n", reader); exit(1); } if((r = sc_connect_card(sc_ctx_get_reader(ctx, 0), 0, &card))<0){ fprintf(stderr,"Connect-Card failed: %s\n", sc_strerror(r)); exit(1); } printf("\nCard detected (driver: %s)\nATR:", card->driver->name); for(i=0;i<card->atr_len;++i) printf("%c%02X", i?':':' ', card->atr[i]); printf("\n"); if((r = sc_lock(card))<0){ fprintf(stderr,"Lock failed: %s\n", sc_strerror(r)); exit(1); } show_card(card); if(do_unblock || do_change){ int i1=pinlist[pin_nr].p1, i2=pinlist[pin_nr].p2; if((do_unblock || !pinlist[pin_nr].len) && (i1<0 || !pinlist[i1].len) && (i2<0 || !pinlist[i2].len) ){ fprintf(stderr, "\nNeed %s", do_change ? pinlist[pin_nr].label : pinlist[i1].label); if(do_change && i1>=0) fprintf(stderr, " or %s", pinlist[i1].label); if(i2>=0) fprintf(stderr, " or %s", pinlist[i2].label); fprintf(stderr, " to %s %s\n", do_change ? "change" : "unblock", pinlist[pin_nr].label); } else { if(do_change && pinlist[pin_nr].len) i1=pin_nr; if(i1<0 || !pinlist[i1].len) i1=i2; handle_change(card, pin_nr, i1, do_change, newpin, newlen); } } if(do_nullpin){ handle_nullpin(card, newpin, newlen); show_initial_puk(card); } if(do_readcert) handle_readcert(card, cert_nr, certfile); if(do_writecert){ if(certlist[cert_nr].readonly){ fprintf(stderr, "\nReadonly-Certificate %d cannot be changed\n", cert_nr); } else if(!pinlist[0].len && !pinlist[3].len){ fprintf(stderr, "\nNeed %s or %s to change Card-Certificate %d\n", pinlist[0].label, pinlist[3].label, cert_nr ); } else handle_writecert(card, cert_nr, certfile); } if(do_unblock+do_change+do_nullpin+do_readcert==0) show_certs(card); sc_unlock(card); sc_disconnect_card(card,0); sc_release_context(ctx); exit(0); }