int main(int argc, char **argv) { sc_context_t *ctx = NULL; sc_context_param_t ctx_param; sc_card_t *card = NULL; int r; /* get options */ decode_options(argc, argv); /* connect to the card */ memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; r = sc_context_create(&ctx, &ctx_param); if (r) { fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); return 1; } r = util_connect_card(ctx, &card, opt_reader, opt_wait, 0); if (r) { fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(r)); return 1; } /* Check card type */ if (card->type == SC_CARD_TYPE_MCRD_ESTEID_V10 || card->type == SC_CARD_TYPE_MCRD_ESTEID_V11 || card->type == SC_CARD_TYPE_MCRD_ESTEID_V30) do_esteid(card); else if (card->type == SC_CARD_TYPE_BELPIC_EID) do_belpic(card); else { fprintf(stderr, "Not an EstEID or Belpic card!\n"); goto out; } if (exec_program) { char *const largv[] = {exec_program, NULL}; sc_unlock(card); sc_disconnect_card(card); sc_release_context(ctx); execv(exec_program, largv); /* we should not get here */ perror("execv()"); exit(1); } out: sc_unlock(card); sc_disconnect_card(card); sc_release_context(ctx); exit(exit_status); }
/* Close a card and release all resources */ void card_close (CARD card) { if (card) { #ifdef HAVE_OPENSC if (card->p15card) { sc_pkcs15_unbind (card->p15card); card->p15card = NULL; } if (card->p15priv) p15_release_private_data (card); if (card->scard) { sc_unlock (card->scard); sc_disconnect_card (card->scard, 0); card->scard = NULL; } if (card->ctx) { sc_release_context (card->ctx); card->ctx = NULL; } #endif xfree (card); } }
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_removed(sc_reader_t * reader) { unsigned int i; struct sc_pkcs11_card *p11card = NULL; /* Mark all slots as "token not present" */ sc_log(context, "%s: card removed", reader->name); for (i=0; i < list_size(&virtual_slots); i++) { sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i); if (slot->reader == reader) { /* Save the "card" object */ if (slot->p11card) p11card = slot->p11card; slot_token_removed(slot->id); } } if (p11card) { p11card->framework->unbind(p11card); sc_disconnect_card(p11card->card); for (i=0; i < p11card->nmechanisms; ++i) { if (p11card->mechanisms[i]->free_mech_data) { p11card->mechanisms[i]->free_mech_data(p11card->mechanisms[i]->mech_data); } free(p11card->mechanisms[i]); } free(p11card->mechanisms); free(p11card); } return CKR_OK; }
static void die(int ret) { if (card) { sc_unlock(card); sc_disconnect_card(card, 0); } if (ctx) sc_release_context(ctx); exit(ret); }
static void die(int ret) { sc_file_free(current_file); if (card) { sc_unlock(card); sc_disconnect_card(card); } if (ctx) sc_release_context(ctx); exit(ret); }
static void close_pkcs15(PluginInstance *inst) { if (inst->p15card) { sc_pkcs15_unbind(inst->p15card); inst->p15card = NULL; } if (inst->card) { sc_disconnect_card(inst->card, 0); inst->card = NULL; } if (inst->ctx) { sc_release_context(inst->ctx); inst->ctx = NULL; } }
void sc_close(void) { if (p15card) { sc_pkcs15_unbind(p15card); p15card = NULL; } if (card) { sc_disconnect_card(card, 0); card = NULL; } if (ctx) { sc_release_context(ctx); ctx = NULL; } }
CK_RV card_removed(sc_reader_t * reader) { unsigned int i; struct sc_pkcs11_card *card = NULL; /* Mark all slots as "token not present" */ sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: card removed", reader->name); for (i=0; i < list_size(&virtual_slots); i++) { sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i); if (slot->reader == reader) { /* Save the "card" object */ if (slot->card) card = slot->card; slot_token_removed(slot->id); } } if (card) { card->framework->unbind(card); sc_disconnect_card(card->card); /* FIXME: free mechanisms * spaces allocated by the * sc_pkcs11_register_sign_and_hash_mechanism * and sc_pkcs11_new_fw_mechanism. * but see sc_pkcs11_register_generic_mechanisms for (i=0; i < card->nmechanisms; ++i) { // if 'mech_data' is a pointer earlier returned by the ?alloc free(card->mechanisms[i]->mech_data); // if 'mechanisms[i]' is a pointer earlier returned by the ?alloc free(card->mechanisms[i]); } */ free(card->mechanisms); free(card); } return CKR_OK; }
int main(int argc, char* argv[]) { int opt_reader = -1; int opt_wait = 0; const char *opt_pin = NULL; int opt_key = 0; int opt_is_iv = 0; u8 opt_keytype = SC_RUTOKEN_OPTIONS_GOST_CRYPT_PZ; const char *opt_input = NULL; const char *opt_output = NULL; int opt_operation = OP_NONE; int opt_debug = 0; char IV[IV_SIZE]; int err = 0; sc_context_t *ctx = NULL; sc_context_param_t ctx_param; sc_card_t *card = NULL; int c, long_optind, r, tries_left; while (1) { c = getopt_long(argc, argv, "r:wp:k:I:t:i:o:sgedmv", options, &long_optind); if (c == -1) break; switch (c) { case '?': util_print_usage_and_die(app_name, options, option_help); case 'r': opt_reader = atoi(optarg); break; case 'w': opt_wait = 1; break; case 'p': opt_pin = optarg; break; case 'k': opt_key = atoi(optarg); if (opt_key <= 0 || opt_key < SC_RUTOKEN_DO_ALL_MIN_ID || opt_key > SC_RUTOKEN_DO_NOCHV_MAX_ID) { fprintf(stderr, "Error: Key ID is invalid" " (%d <= ID <= %d)\n", SC_RUTOKEN_DO_ALL_MIN_ID > 0 ? SC_RUTOKEN_DO_ALL_MIN_ID : 1, SC_RUTOKEN_DO_NOCHV_MAX_ID); return -1; } break; case 'I': opt_is_iv = 1; strncpy(IV, optarg, sizeof(IV)); break; case 't': if (strcmp(optarg, "CFB") == 0) opt_keytype = SC_RUTOKEN_OPTIONS_GOST_CRYPT_GAMMOS; else if (strcmp(optarg, "SM") == 0) opt_keytype = SC_RUTOKEN_OPTIONS_GOST_CRYPT_GAMM; else if (strcmp(optarg, "ECB") != 0) { fprintf(stderr, "Error: Key type must be either" " ECB, SM or CFB\n"); return -1; } break; case 'i': opt_input = optarg; break; case 'o': opt_output = optarg; break; case 's': opt_operation = OP_GET_INFO; break; case 'g': opt_operation = OP_GEN_KEY; break; case 'e': opt_operation = OP_ENCRYPT; break; case 'd': opt_operation = OP_DECRYPT; break; case 'm': opt_operation = OP_MAC; break; case 'v': opt_debug++; break; } } memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.app_name = app_name; r = sc_context_create(&ctx, &ctx_param); if (r) { fprintf(stderr, "Error: Failed to establish context: %s\n", sc_strerror(r)); return -1; } ctx->debug = opt_debug; if (util_connect_card(ctx, &card, opt_reader, 0, opt_wait, opt_debug) != 0) err = -1; if (err == 0 && opt_pin) { /* verify */ r = sc_verify(card, SC_AC_CHV, SC_RUTOKEN_DEF_ID_GCHV_USER, (u8*)opt_pin, strlen(opt_pin), &tries_left); if (r) { fprintf(stderr, "Error: PIN verification failed: %s", sc_strerror(r)); if (r == SC_ERROR_PIN_CODE_INCORRECT) fprintf(stderr, " (tries left %d)\n", tries_left); else putc('\n', stderr); err = 1; } } if (err == 0) { err = -1; switch (opt_operation) { case OP_GET_INFO: err = rutoken_info(card); break; case OP_DECRYPT: case OP_ENCRYPT: case OP_MAC: if (!opt_input) { fprintf(stderr, "Error: No input file specified\n"); break; } if (opt_operation != OP_MAC && !opt_output) { fprintf(stderr, "Error: No output file specified\n"); break; } case OP_GEN_KEY: if (opt_key == 0) { fprintf(stderr, "Error: You must set key ID\n"); break; } if (opt_operation == OP_GEN_KEY) err = generate_gostkey(card, (u8)opt_key, opt_keytype); else if (opt_operation == OP_MAC) err = gostmac(card, (u8)opt_key, opt_input); else err = gostchiper(card, (u8)opt_key, opt_input,opt_output, IV, opt_is_iv, opt_operation); break; default: fprintf(stderr, "Error: No operation specified\n"); break; } } if (card) { /* sc_lock and sc_connect_card in util_connect_card */ sc_unlock(card); sc_disconnect_card(card, 0); } if (ctx) sc_release_context(ctx); return err; }
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); }
CK_RV card_detect(sc_reader_t *reader) { struct sc_pkcs11_card *p11card = NULL; int free_p11card = 0; int rc; CK_RV rv; unsigned int i; int j; sc_log(context, "%s: Detecting smart card", reader->name); /* Check if someone inserted a card */ again: rc = sc_detect_card_presence(reader); if (rc < 0) { sc_log(context, "%s: failed, %s", reader->name, sc_strerror(rc)); return sc_to_cryptoki_error(rc, NULL); } if (rc == 0) { sc_log(context, "%s: card absent", reader->name); card_removed(reader); /* Release all resources */ return CKR_TOKEN_NOT_PRESENT; } /* If the card was changed, disconnect the current one */ if (rc & SC_READER_CARD_CHANGED) { sc_log(context, "%s: Card changed", reader->name); /* The following should never happen - but if it * does we'll be stuck in an endless loop. * So better be fussy. if (!retry--) return CKR_TOKEN_NOT_PRESENT; */ card_removed(reader); goto again; } /* Locate a slot related to the reader */ for (i=0; i<list_size(&virtual_slots); i++) { sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i); if (slot->reader == reader) { p11card = slot->p11card; break; } } /* Detect the card if it's not known already */ if (p11card == NULL) { sc_log(context, "%s: First seen the card ", reader->name); p11card = (struct sc_pkcs11_card *)calloc(1, sizeof(struct sc_pkcs11_card)); if (!p11card) return CKR_HOST_MEMORY; free_p11card = 1; p11card->reader = reader; } if (p11card->card == NULL) { sc_log(context, "%s: Connecting ... ", reader->name); rc = sc_connect_card(reader, &p11card->card); if (rc != SC_SUCCESS) { sc_log(context, "%s: SC connect card error %i", reader->name, rc); rv = sc_to_cryptoki_error(rc, NULL); goto fail; } /* escape commands are only guaranteed to be working with a card * inserted. That's why by now, after sc_connect_card() the reader's * metadata may have changed. We re-initialize the metadata for every * slot of this reader here. */ if (reader->flags & SC_READER_ENABLE_ESCAPE) { for (i = 0; i<list_size(&virtual_slots); i++) { sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i); if (slot->reader == reader) init_slot_info(&slot->slot_info, reader); } } sc_log(context, "%s: Connected SC card %p", reader->name, p11card->card); } /* Detect the framework */ if (p11card->framework == NULL) { struct sc_app_info *app_generic = sc_pkcs15_get_application_by_type(p11card->card, "generic"); sc_log(context, "%s: Detecting Framework. %i on-card applications", reader->name, p11card->card->app_count); sc_log(context, "%s: generic application %s", reader->name, app_generic ? app_generic->label : "<none>"); for (i = 0; frameworks[i]; i++) if (frameworks[i]->bind != NULL) break; /*TODO: only first framework is used: pkcs15init framework is not reachable here */ if (frameworks[i] == NULL) { rv = CKR_GENERAL_ERROR; goto fail; } p11card->framework = frameworks[i]; /* Initialize framework */ sc_log(context, "%s: Detected framework %d. Creating tokens.", reader->name, i); /* Bind 'generic' application or (emulated?) card without applications */ if (app_generic || !p11card->card->app_count) { scconf_block *conf_block = NULL; int enable_InitToken = 0; conf_block = sc_match_atr_block(p11card->card->ctx, NULL, &p11card->reader->atr); if (!conf_block) /* check default block */ conf_block = sc_get_conf_block(context, "framework", "pkcs15", 1); enable_InitToken = scconf_get_bool(conf_block, "pkcs11_enable_InitToken", 0); sc_log(context, "%s: Try to bind 'generic' token.", reader->name); rv = frameworks[i]->bind(p11card, app_generic); if (rv == CKR_TOKEN_NOT_RECOGNIZED && enable_InitToken) { sc_log(context, "%s: 'InitToken' enabled -- accept non-binded card", reader->name); rv = CKR_OK; } if (rv != CKR_OK) { sc_log(context, "%s: cannot bind 'generic' token: rv 0x%lX", reader->name, rv); goto fail; } sc_log(context, "%s: Creating 'generic' token.", reader->name); rv = frameworks[i]->create_tokens(p11card, app_generic); if (rv != CKR_OK) { sc_log(context, "%s: create 'generic' token error 0x%lX", reader->name, rv); goto fail; } } /* Now bind the rest of applications that are not 'generic' */ for (j = 0; j < p11card->card->app_count; j++) { struct sc_app_info *app_info = p11card->card->app[j]; char *app_name = app_info ? app_info->label : "<anonymous>"; if (app_generic && app_generic == p11card->card->app[j]) continue; sc_log(context, "%s: Binding %s token.", reader->name, app_name); rv = frameworks[i]->bind(p11card, app_info); if (rv != CKR_OK) { sc_log(context, "%s: bind %s token error Ox%lX", reader->name, app_name, rv); continue; } sc_log(context, "%s: Creating %s token.", reader->name, app_name); rv = frameworks[i]->create_tokens(p11card, app_info); if (rv != CKR_OK) { sc_log(context, "%s: create %s token error 0x%lX", reader->name, app_name, rv); goto fail; } } } sc_log(context, "%s: Detection ended", reader->name); return CKR_OK; fail: if (free_p11card) { if (p11card->framework) p11card->framework->unbind(p11card); if (p11card->card != NULL) sc_disconnect_card(p11card->card); free(p11card); } return rv; }
int main(int argc, char * const argv[]) { int err = 0, r, c, long_optind = 0; int do_list_sdos = 0; int do_list_apps = 0; int action_count = 0; sc_context_param_t ctx_param; setbuf(stderr, NULL); setbuf(stdout, NULL); while (1) { c = getopt_long(argc, argv, "v", options, &long_optind); if (c == -1) break; if (c == '?') util_print_usage_and_die(app_name, options, option_help, NULL); switch (c) { case OPT_LIST_SDOS: do_list_sdos = 1; opt_sdo_tag = optarg; action_count++; break; case OPT_LIST_APPLICATIONS: do_list_apps = 1; action_count++; break; case OPT_BIND_TO_AID: opt_bind_to_aid = optarg; break; case OPT_READER: opt_reader = optarg; break; case 'v': verbose++; break; } } if (action_count == 0) util_print_usage_and_die(app_name, options, option_help, NULL); memset(&ctx_param, 0, sizeof(sc_context_param_t)); ctx_param.app_name = app_name; r = sc_context_create(&ctx, &ctx_param); if (r != SC_SUCCESS) { fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); return 1; } /* Only change if not in opensc.conf */ if (verbose > 1 && ctx->debug == 0) { ctx->debug = verbose; sc_ctx_log_to_file(ctx, "stderr"); } if (action_count <= 0) goto end; err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); if (err) goto end; if (opt_bind_to_aid) { struct sc_aid aid; aid.len = sizeof(aid.value); if (sc_hex_to_bin(opt_bind_to_aid, aid.value, &aid.len)) { fprintf(stderr, "Invalid AID value: '%s'\n", opt_bind_to_aid); return 1; } r = sc_pkcs15_bind(card, &aid, &p15card); } else if (!do_list_sdos) { r = sc_pkcs15_bind(card, NULL, &p15card); } if (do_list_sdos) { if ((err = list_sdos(opt_sdo_tag))) goto end; action_count--; } if (do_list_apps) { if ((err = list_apps(stdout))) goto end; action_count--; } end: if (p15card) sc_pkcs15_unbind(p15card); if (card) { sc_unlock(card); sc_disconnect_card(card); } if (ctx) sc_release_context(ctx); return err; }
int main(int argc, char * const argv[]) { int err = 0, r, c, long_optind = 0; int action_count = 0; int do_initialize = 0; int do_import_dkek_share = 0; int do_create_dkek_share = 0; int do_wrap_key = 0; int do_unwrap_key = 0; sc_path_t path; sc_file_t *file = NULL; const char *opt_so_pin = NULL; const char *opt_pin = NULL; const char *opt_filename = NULL; char *opt_password = NULL; int opt_retry_counter = 3; int opt_dkek_shares = -1; int opt_key_reference = -1; int opt_password_shares_threshold = -1; int opt_password_shares_total = -1; int opt_force = 0; int opt_iter = 10000000; sc_context_param_t ctx_param; setbuf(stderr, NULL); setbuf(stdout, NULL); while (1) { c = getopt_long(argc, argv, "XC:I:W:U:s:i:fr:wv", options, &long_optind); if (c == -1) break; if (c == '?') util_print_usage_and_die(app_name, options, option_help, NULL); switch (c) { case 'X': do_initialize = 1; action_count++; break; case 'C': do_create_dkek_share = 1; opt_filename = optarg; action_count++; break; case 'I': do_import_dkek_share = 1; opt_filename = optarg; action_count++; break; case 'W': do_wrap_key = 1; opt_filename = optarg; action_count++; break; case 'U': do_unwrap_key = 1; opt_filename = optarg; action_count++; break; case OPT_PASSWORD: opt_password = optarg; break; case OPT_SO_PIN: opt_so_pin = optarg; break; case OPT_PIN: opt_pin = optarg; break; case OPT_RETRY: opt_retry_counter = atol(optarg); break; case OPT_PASSWORD_SHARES_THRESHOLD: opt_password_shares_threshold = atol(optarg); break; case OPT_PASSWORD_SHARES_TOTAL: opt_password_shares_total = atol(optarg); break; case 's': opt_dkek_shares = atol(optarg); break; case 'f': opt_force = 1; break; case 'i': opt_key_reference = atol(optarg); break; case 'r': opt_reader = optarg; break; case 'v': verbose++; break; case 'w': opt_wait = 1; break; } } CRYPTO_malloc_init(); ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); memset(&ctx_param, 0, sizeof(sc_context_param_t)); ctx_param.app_name = app_name; r = sc_context_create(&ctx, &ctx_param); if (r != SC_SUCCESS) { fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); return 1; } /* Only change if not in opensc.conf */ if (verbose > 1 && ctx->debug == 0) { ctx->debug = verbose; sc_ctx_log_to_file(ctx, "stderr"); } err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); if (r != SC_SUCCESS) { fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(r)); goto end; } sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0); r = sc_select_file(card, &path, &file); if (r != SC_SUCCESS) { fprintf(stderr, "Failed to select application: %s\n", sc_strerror(r)); goto end; } if (do_initialize) { initialize(card, opt_so_pin, opt_pin, opt_retry_counter, opt_dkek_shares); } if (do_create_dkek_share) { create_dkek_share(card, opt_filename, opt_iter, opt_password, opt_password_shares_threshold, opt_password_shares_total); } if (do_import_dkek_share) { import_dkek_share(card, opt_filename, opt_iter, opt_password, opt_password_shares_total); } if (do_wrap_key) { wrap_key(card, opt_key_reference, opt_filename, opt_pin); } if (do_unwrap_key) { unwrap_key(card, opt_key_reference, opt_filename, opt_pin, opt_force); } if (action_count == 0) { print_info(card, file); } end: if (card) { sc_unlock(card); sc_disconnect_card(card); } if (ctx) sc_release_context(ctx); ERR_print_errors_fp(stderr); return err; }
int main(int argc, char *const argv[]) { int err = 0, r, c, long_optind = 0; int do_info = 0; int do_format = 0; int do_change_startkey = 0; int action_count = 0; const char *opt_driver = NULL; const char *opt_startkey = NULL; const char *opt_change_startkey = NULL; sc_context_param_t ctx_param; while (1) { c = getopt_long(argc, argv, "hifs:r:vdc:wS:", options, &long_optind); if (c == -1) break; switch (c) { case 'h': printf("NB! This tool is only for Siemens CardOS based cards!\n\n"); util_print_usage_and_die(app_name, options, option_help); case 'i': do_info = 1; action_count++; break; case 'f': do_format = 1; action_count++; break; case 's': opt_startkey = optarg; break; case 'S': do_change_startkey = 1; opt_change_startkey = optarg; action_count++; break; case 'r': opt_reader = optarg; break; case 'v': verbose++; break; case 'c': opt_driver = optarg; break; case 'w': opt_wait = 1; break; } } /* create sc_context_t object */ memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; r = sc_context_create(&ctx, &ctx_param); if (r) { fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); return 1; } if (verbose > 1) { ctx->debug = verbose; ctx->debug_file = stderr; } if (opt_driver != NULL) { err = sc_set_card_driver(ctx, opt_driver); if (err) { fprintf(stderr, "Driver '%s' not found!\n", opt_driver); err = 1; goto end; } } err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); if (err) goto end; if (do_info) { if ((err = cardos_info())) { goto end; } action_count--; } if (do_change_startkey) { if ((err = cardos_change_startkey(opt_change_startkey))) { goto end; } action_count--; } if (do_format) { if ((err = cardos_format(opt_startkey))) { goto end; } action_count--; } end: if (card) { sc_unlock(card); sc_disconnect_card(card); } if (ctx) sc_release_context(ctx); return err; }
int main(int argc, char * const argv[]) { int err = 0, r, c, long_optind = 0; int do_list_readers = 0; int do_list_drivers = 0; int do_list_rdrivers = 0; int do_list_files = 0; int do_send_apdu = 0; int do_print_atr = 0; int do_print_serial = 0; int do_print_name = 0; int action_count = 0; const char *opt_driver = NULL; sc_context_param_t ctx_param; setbuf(stderr, NULL); setbuf(stdout, NULL); while (1) { c = getopt_long(argc, argv, "nlfr:vs:DRc:aw", options, &long_optind); if (c == -1) break; if (c == '?') print_usage_and_die(app_name, options, option_help); switch (c) { case 'l': do_list_readers = 1; action_count++; break; case 'D': do_list_drivers = 1; action_count++; break; case 'R': do_list_rdrivers = 1; action_count++; break; case 'f': do_list_files = 1; action_count++; break; case 's': opt_apdus = (char **) realloc(opt_apdus, (opt_apdu_count + 1) * sizeof(char *)); opt_apdus[opt_apdu_count] = optarg; do_send_apdu++; if (opt_apdu_count == 0) action_count++; opt_apdu_count++; break; case 'a': do_print_atr = 1; action_count++; break; case 'n': do_print_name = 1; action_count++; break; case 'r': opt_reader = atoi(optarg); break; case 'v': verbose++; break; case 'c': opt_driver = optarg; break; case 'w': opt_wait = 1; break; case OPT_SERIAL: do_print_serial = 1; action_count++; break; } } if (action_count == 0) print_usage_and_die(app_name, options, option_help); memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; r = sc_context_create(&ctx, &ctx_param); if (r) { fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); return 1; } if (verbose > 1) ctx->debug = verbose-1; if (do_list_rdrivers) { if ((err = list_reader_drivers())) goto end; action_count--; } if (do_list_readers) { if ((err = list_readers())) goto end; action_count--; } if (do_list_drivers) { if ((err = list_drivers())) goto end; action_count--; } if (action_count <= 0) goto end; if (opt_driver != NULL) { err = sc_set_card_driver(ctx, opt_driver); if (err) { fprintf(stderr, "Driver '%s' not found!\n", opt_driver); err = 1; goto end; } } err = connect_card(ctx, &card, opt_reader, 0, opt_wait, verbose); if (err) goto end; if (do_print_atr) { if (verbose) { printf("Card ATR:\n"); hex_dump_asc(stdout, card->atr, card->atr_len, -1); } else { char tmp[SC_MAX_ATR_SIZE*3]; sc_bin_to_hex(card->atr, card->atr_len, tmp, sizeof(tmp) - 1, ':'); fprintf(stdout,"%s\n",tmp); } action_count--; } if (do_print_serial) { if (verbose) printf("Card serial number:"); print_serial(card); action_count--; } if (do_print_name) { if (verbose) printf("Card name: "); printf("%s\n", card->name); action_count--; } if (do_send_apdu) { if ((err = send_apdu())) goto end; action_count--; } if (do_list_files) { if ((err = list_files())) goto end; action_count--; } end: if (card) { sc_unlock(card); sc_disconnect_card(card, 0); } if (ctx) sc_release_context(ctx); return err; }
int main(int argc, char * const argv[]) { int err = 0, r, c, long_optind = 0; int do_decipher = 0; int do_sign = 0; int action_count = 0; struct sc_pkcs15_object *key; sc_context_param_t ctx_param; while (1) { c = getopt_long(argc, argv, "sck:r:i:o:f:Rp:vw", options, &long_optind); if (c == -1) break; if (c == '?') util_print_usage_and_die(app_name, options, option_help, NULL); switch (c) { case 's': do_sign++; action_count++; break; case 'c': do_decipher++; action_count++; break; case 'k': opt_key_id = optarg; action_count++; break; case 'r': opt_reader = optarg; break; case 'i': opt_input = optarg; break; case 'o': opt_output = optarg; break; case 'f': opt_sig_format = optarg; break; case 'R': opt_raw = 1; break; case OPT_SHA1: opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA1; break; case OPT_SHA256: opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA256; break; case OPT_SHA384: opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA384; break; case OPT_SHA512: opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA512; break; case OPT_SHA224: opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_SHA224; break; case OPT_MD5: opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_MD5; break; case OPT_PKCS1: opt_crypt_flags |= SC_ALGORITHM_RSA_PAD_PKCS1; break; case 'v': verbose++; break; case 'p': opt_pincode = optarg; break; case OPT_BIND_TO_AID: opt_bind_to_aid = optarg; break; case 'w': opt_wait = 1; break; } } if (action_count == 0) util_print_usage_and_die(app_name, options, option_help, NULL); if (!(opt_crypt_flags & SC_ALGORITHM_RSA_HASHES)) opt_crypt_flags |= SC_ALGORITHM_RSA_HASH_NONE; memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; r = sc_context_create(&ctx, &ctx_param); if (r) { fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); return 1; } if (verbose > 1) { ctx->debug = verbose; sc_ctx_log_to_file(ctx, "stderr"); } err = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); if (err) goto end; if (verbose) fprintf(stderr, "Trying to find a PKCS #15 compatible card...\n"); if (opt_bind_to_aid) { struct sc_aid aid; aid.len = sizeof(aid.value); if (sc_hex_to_bin(opt_bind_to_aid, aid.value, &aid.len)) { fprintf(stderr, "Invalid AID value: '%s'\n", opt_bind_to_aid); return 1; } r = sc_pkcs15_bind(card, &aid, &p15card); } else { r = sc_pkcs15_bind(card, NULL, &p15card); } if (r) { fprintf(stderr, "PKCS #15 binding failed: %s\n", sc_strerror(r)); err = 1; goto end; } if (verbose) fprintf(stderr, "Found %s!\n", p15card->tokeninfo->label); if (do_decipher) { if ((err = get_key(SC_PKCS15_PRKEY_USAGE_DECRYPT, &key)) || (err = decipher(key))) goto end; action_count--; } if (do_sign) { if ((err = get_key(SC_PKCS15_PRKEY_USAGE_SIGN| SC_PKCS15_PRKEY_USAGE_SIGNRECOVER| SC_PKCS15_PRKEY_USAGE_NONREPUDIATION, &key)) || (err = sign(key))) goto end; action_count--; } end: if (p15card) sc_pkcs15_unbind(p15card); if (card) { sc_unlock(card); sc_disconnect_card(card); } if (ctx) sc_release_context(ctx); return err; }
int main(int argc, char *argv[]) { int r, c, long_optind = 0; sc_context_param_t ctx_param; sc_card_t *card = NULL; sc_context_t *ctx = NULL; sc_file_t *file = NULL; sc_path_t path; RSA *rsa = NULL; BIGNUM *bn = NULL; BIO *mem = NULL; static const char *pin = NULL; static const char *puk = NULL; while (1) { c = getopt_long(argc, argv, "r:wgol:ix:y:nut:fj:k:hv", \ options, &long_optind); if (c == -1) break; if (c == '?' || c == 'h') util_print_usage_and_die(app_name, options, option_help, NULL); switch (c) { case 'r': opt_reader = optarg; break; case 'w': opt_wait = 1; break; case 'g': if(keylen == 0) keylen = 1536; break; case 'o': overwrite = 1; break; case 'l': keylen = atoi(optarg); break; case 'i': install_pin = 1; break; case 'x': util_get_pin(optarg, &pin); break; case 'y': util_get_pin(optarg, &puk); break; case 'n': new_pin = 1; break; case 'u': unlock = 1; break; case 't': cert = optarg; break; case 'f': finalize = 1; break; case 'j': get_filename = optarg; break; case 'k': put_filename = optarg; break; case 'v': verbose++; break; } } 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) { printf("Failed to establish context: %s\n", sc_strerror(r)); return 1; } if (verbose > 1) { ctx->debug = verbose; sc_ctx_log_to_file(ctx, "stderr"); } if (opt_driver != NULL) { r = sc_set_card_driver(ctx, opt_driver); if (r) { printf("Driver '%s' not found!\n", opt_driver); goto out; } } r = util_connect_card(ctx, &card, opt_reader, opt_wait, 0); if (r) goto out; sc_format_path("3F00", &path); r = sc_select_file(card, &path, NULL); if(r) goto out; if(install_pin) { sc_format_path("AAAA", &path); r = sc_select_file(card, &path, NULL); if(r) { if(r != SC_ERROR_FILE_NOT_FOUND) goto out; file = sc_file_new(); if(file == NULL) { printf("Not enougth memory.\n"); goto out; } file->type = SC_FILE_TYPE_INTERNAL_EF; file->ef_structure = SC_FILE_EF_TRANSPARENT; file->shareable = 0; file->id = 0xAAAA; file->size = 37; r = sc_file_add_acl_entry(file, SC_AC_OP_READ, SC_AC_NONE, 0); if(r) goto out; r = sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, SC_AC_NONE, 0); if(r) goto out; r = sc_file_add_acl_entry(file, SC_AC_OP_ERASE, SC_AC_NONE, 0); if(r) goto out; /* sc_format_path("3F00AAAA", &(file->path)); */ file->path = path; r = sc_create_file(card, file); if(r) goto out; } if(pin != NULL) { sc_changekey_t ck; struct sc_pin_cmd_pin pin_cmd; int ret; memset(&pin_cmd, 0, sizeof(pin_cmd)); memset(&ck, 0, sizeof(ck)); memcpy(ck.key_template, "\x1e\x00\x00\x10", 4); pin_cmd.encoding = SC_PIN_ENCODING_GLP; pin_cmd.len = strlen(pin); pin_cmd.data = (u8*)pin; pin_cmd.max_length = 8; ret = sc_build_pin(ck.new_key.key_value, sizeof(ck.new_key.key_value), &pin_cmd, 1); if(ret < 0) goto out; ck.new_key.key_len = ret; r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_CHANGE_KEY, &ck); if(r) goto out; } if(puk != NULL) { sc_changekey_t ck; struct sc_pin_cmd_pin puk_cmd; int ret; memset(&puk_cmd, 0, sizeof(puk_cmd)); memset(&ck, 0, sizeof(ck)); memcpy(ck.key_template, "\x1e\x00\x00\x20", 4); puk_cmd.encoding = SC_PIN_ENCODING_GLP; puk_cmd.len = strlen(puk); puk_cmd.data = (u8*)puk; puk_cmd.max_length = 8; ret = sc_build_pin(ck.new_key.key_value, sizeof(ck.new_key.key_value), &puk_cmd, 1); if(ret < 0) goto out; ck.new_key.key_len = ret; r = sc_card_ctl(card, SC_CARDCTL_WESTCOS_CHANGE_KEY, &ck); if(r) goto out; } } if(new_pin) { if(change_pin(card, 0, pin, puk)) printf("Wrong pin.\n"); goto out; } if(unlock) { if(unlock_pin(card, 0, puk, pin)) printf("Error unblocking pin.\n"); goto out; } printf("verify pin.\n"); { if(verify_pin(card, 0, pin)) { printf("Wrong pin.\n"); goto out; } } if(keylen) { size_t lg; struct sc_pkcs15_pubkey key; struct sc_pkcs15_pubkey_rsa *dst = &(key.u.rsa); u8 *pdata; memset(&key, 0, sizeof(key)); key.algorithm = SC_ALGORITHM_RSA; printf("Generate key of length %d.\n", keylen); #if OPENSSL_VERSION_NUMBER>=0x00908000L rsa = RSA_new(); bn = BN_new(); mem = BIO_new(BIO_s_mem()); if(rsa == NULL || bn == NULL || mem == NULL) { printf("Not enougth memory.\n"); goto out; } if(!BN_set_word(bn, RSA_F4) || !RSA_generate_key_ex(rsa, keylen, bn, NULL)) #else rsa = RSA_generate_key(keylen, RSA_F4, NULL, NULL); mem = BIO_new(BIO_s_mem()); if(mem == NULL) { printf("Not enougth memory.\n"); goto out; } if (!rsa) #endif { printf("RSA_generate_key_ex return %ld\n", ERR_get_error()); goto out; } RSA_set_method(rsa, RSA_PKCS1_OpenSSL()); if(!i2d_RSAPrivateKey_bio(mem, rsa)) { printf("i2d_RSAPrivateKey_bio return %ld\n", ERR_get_error()); goto out; } lg = BIO_get_mem_data(mem, &pdata); sc_format_path("0001", &path); r = sc_select_file(card, &path, NULL); if(r) { if(r != SC_ERROR_FILE_NOT_FOUND) goto out; file = sc_file_new(); if(file == NULL) { printf("Not enougth memory.\n"); goto out; } file->type = SC_FILE_TYPE_WORKING_EF; file->ef_structure = SC_FILE_EF_TRANSPARENT; file->shareable = 0; file->size = ((lg/4)+1)*4; r = sc_file_add_acl_entry(file, SC_AC_OP_READ, SC_AC_CHV, 0); if(r) goto out; r = sc_file_add_acl_entry(file, SC_AC_OP_UPDATE, SC_AC_CHV, 0); if(r) goto out; r = sc_file_add_acl_entry(file, SC_AC_OP_ERASE, SC_AC_CHV, 0); if(r) goto out; file->path = path; printf("File key creation %s, size %"SC_FORMAT_LEN_SIZE_T"d.\n", file->path.value, file->size); r = sc_create_file(card, file); if(r) goto out; } else { if(!overwrite) { printf("Key file already exist,"\ " use -o to replace it.\n"); goto out; } } printf("Private key length is %"SC_FORMAT_LEN_SIZE_T"d\n", lg); printf("Write private key.\n"); r = sc_update_binary(card,0,pdata,lg,0); if(r<0) goto out; printf("Private key correctly written.\n"); r = create_file_cert(card); if(r) goto out; { const BIGNUM *rsa_n, *rsa_e; RSA_get0_key(rsa, &rsa_n, &rsa_e, NULL); if (!do_convert_bignum(&dst->modulus, rsa_n) || !do_convert_bignum(&dst->exponent, rsa_e)) goto out; } r = sc_pkcs15_encode_pubkey(ctx, &key, &pdata, &lg); if(r) goto out; printf("Public key length %"SC_FORMAT_LEN_SIZE_T"d\n", lg); sc_format_path("3F000002", &path); r = sc_select_file(card, &path, NULL); if(r) goto out; printf("Write public key.\n"); r = sc_update_binary(card,0,pdata,lg,0); if(r<0) goto out; printf("Public key correctly written.\n"); } if(cert) { BIO *bio; X509 *xp; u8 *pdata; bio = BIO_new(BIO_s_file()); if (BIO_read_filename(bio, cert) <= 0) { BIO_free(bio); printf("Can't open file %s.\n", cert); goto out; } xp = PEM_read_bio_X509(bio, NULL, NULL, NULL); BIO_free(bio); if (xp == NULL) { print_openssl_error(); goto out; } else { int lg = cert2der(xp, &pdata); sc_format_path("0002", &path); r = sc_select_file(card, &path, NULL); if(r) goto out; /* FIXME: verify if the file has a compatible size... */ printf("Write certificate %s.\n", cert); r = sc_update_binary(card,0,pdata,lg,0); if(r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { if(verify_pin(card, 0, pin)) { printf("Wrong pin.\n"); } else { r = sc_update_binary(card,0,pdata,lg,0); } } if(r<0) { if(pdata) free(pdata); goto out; } if(xp) X509_free(xp); if(pdata) free(pdata); printf("Certificate correctly written.\n"); } } if(finalize) { int mode = SC_CARDCTRL_LIFECYCLE_USER; if(card->atr.value[10] != 0x82) { sc_format_path("0001", &path); r = sc_select_file(card, &path, NULL); if(r) { printf("This card don't have private key"\ " and can't be finalize.\n"); goto out; } printf("Finalize card...\n"); if(sc_card_ctl(card, SC_CARDCTL_WESTCOS_AUT_KEY, NULL) || sc_card_ctl(card, SC_CARDCTL_LIFECYCLE_SET, &mode)) { printf("Error finalizing card,"\ " card isn't secure.\n"); goto out; } } printf("Card correctly finalized.\n"); } if(get_filename) { FILE *fp; u8 *b; if(file) { sc_file_free(file); file = NULL; } sc_format_path(get_filename, &path); r = sc_select_file(card, &path, &file); if(r) { printf("Error file not found.\n"); goto out; } b = malloc(file->size); if(b == NULL) { printf("Not enougth memory.\n"); goto out; } r = sc_read_binary(card, 0, b, file->size, 0); if(r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { if(verify_pin(card, 0, pin)) { printf("Wrong pin.\n"); goto out; } r = sc_read_binary(card, 0, b, file->size, 0); } if(r<0) { printf("Error reading file.\n"); goto out; } fp = fopen(get_filename, "wb"); fwrite(b, 1, file->size, fp); fclose(fp); free(b); } if(put_filename) { FILE *fp; u8 *b; if(file) { sc_file_free(file); file = NULL; } sc_format_path(put_filename, &path); r = sc_select_file(card, &path, &file); if(r) { printf("File not found.\n"); goto out; } b = malloc(file->size); if(b == NULL) { printf("Not enougth memory.\n"); goto out; } memset(b, 0, file->size); fp = fopen(put_filename, "rb"); fread(b, 1, file->size, fp); fclose(fp); r = sc_update_binary(card, 0, b, file->size, 0); if(r == SC_ERROR_SECURITY_STATUS_NOT_SATISFIED) { if(verify_pin(card, 0, pin)) { printf("Wrong pin.\n"); } else { r = sc_update_binary(card, 0, b, file->size, 0); } } if(r<0) { free(b); printf("Error writing file.\n"); goto out; } free(b); } out: if(mem) BIO_free(mem); if(bn) BN_free(bn); if(rsa) RSA_free(rsa); if(file) sc_file_free(file); if (card) { sc_unlock(card); sc_disconnect_card(card); } sc_release_context(ctx); return EXIT_SUCCESS; }
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; }
int main(int argc, char **argv) { sc_context_t *ctx = NULL; sc_context_param_t ctx_param; sc_card_t *card = NULL; int r; int argind = 0; int exit_status = EXIT_SUCCESS; /* decode options */ argind = decode_options(argc, argv); /* connect to the card */ memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; r = sc_context_create(&ctx, &ctx_param); if (r) { util_fatal("failed to establish context: %s", sc_strerror(r)); return EXIT_FAILURE; } r = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); if (r) { util_fatal("failed to connect to card: %s", sc_strerror(r)); return EXIT_FAILURE; } /* check card type */ if ((card->type != SC_CARD_TYPE_OPENPGP_BASE) && (card->type != SC_CARD_TYPE_OPENPGP_V1) && (card->type != SC_CARD_TYPE_OPENPGP_V2) && (card->type != SC_CARD_TYPE_OPENPGP_V3) && (card->type != SC_CARD_TYPE_OPENPGP_GNUK)) { util_error("card type %X: not an OpenPGP card", card->type); exit_status = EXIT_FAILURE; goto out; } /* fail on too many arguments */ if (argind > argc) util_print_usage_and_die(app_name, options, option_help, NULL); /* set default action */ if (!actions) opt_userinfo = 1; if (opt_cardinfo) exit_status |= do_info(card, card_data); if (opt_userinfo) exit_status |= do_info(card, user_data); if (opt_keyinfo) exit_status |= do_info(card, key_data); if (opt_verify && opt_pin) { exit_status |= do_verify(card, verifytype, pin); } if (opt_dump_do) { size_t n; for (n = 0; n < opt_dump_do; n++) { exit_status |= do_dump_do(card, do_dump_idx[n]); } } if (opt_genkey) exit_status |= do_genkey(card, key_id, keytype); if (exec_program) { char *const largv[] = {exec_program, NULL}; sc_unlock(card); sc_disconnect_card(card); sc_release_context(ctx); #ifndef _WIN32 execv(exec_program, largv); #else _execv(exec_program, (const char * const*)largv); #endif /* we should not get here */ perror("execv()"); exit(EXIT_FAILURE); } if (opt_delkey) exit_status |= do_delete_key(card, key_id); if (opt_erase) exit_status |= do_erase(card); out: sc_unlock(card); sc_disconnect_card(card); sc_release_context(ctx); exit(exit_status); }
int main(int argc, char **argv) { sc_context_t *ctx = NULL; sc_context_param_t ctx_param; sc_card_t *card = NULL; int r; int argind = 0; int exit_status = EXIT_SUCCESS; /* decode options */ argind = decode_options(argc, argv); /* connect to the card */ memset(&ctx_param, 0, sizeof(ctx_param)); ctx_param.ver = 0; ctx_param.app_name = app_name; r = sc_context_create(&ctx, &ctx_param); if (r) { util_fatal("failed to establish context: %s\n", sc_strerror(r)); return EXIT_FAILURE; } if (verbose > 1) { ctx->debug = verbose; sc_ctx_log_to_file(ctx, "stderr"); } r = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); if (r) { util_fatal("failed to connect to card: %s\n", sc_strerror(r)); return EXIT_FAILURE; } /* check card type */ if ((card->type != SC_CARD_TYPE_OPENPGP_V1) && (card->type != SC_CARD_TYPE_OPENPGP_V2)) { util_error("not an OpenPGP card"); exit_status = EXIT_FAILURE; goto out; } /* fail on too many arguments */ if (argind > argc) util_print_usage_and_die(app_name, options, option_help, NULL); /* set default action */ if (!actions) opt_userinfo = 1; if (opt_userinfo) exit_status |= do_userinfo(card); if (opt_verify && opt_pin) { exit_status |= do_verify(card, verifytype, pin); } if (opt_dump_do) { exit_status |= do_dump_do(card, 0x0100 + do_dump_idx); } if (opt_genkey) exit_status |= do_genkey(card, key_id, key_len); if (exec_program) { char *const largv[] = {exec_program, NULL}; sc_unlock(card); sc_disconnect_card(card); sc_release_context(ctx); execv(exec_program, largv); /* we should not get here */ perror("execv()"); exit(EXIT_FAILURE); } out: sc_unlock(card); sc_disconnect_card(card); sc_release_context(ctx); exit(exit_status); }
void sc_test_cleanup(void) { sc_disconnect_card(card); sc_release_context(ctx); }
int main(int argc, char * const argv[]) { int err = 0, r, c, long_optind = 0; int action_count = 0; int do_initialize = 0; int do_unblock = 0; int do_change_admin = 0; sc_path_t path; const char *opt_so_pin = NULL; const char *opt_pin = NULL; const char *opt_serial_number = NULL; const char *opt_new_key = NULL; sc_context_param_t ctx_param; setbuf(stderr, NULL); setbuf(stdout, NULL); while (1) { c = getopt_long(argc, argv, "XUCr:wv", options, &long_optind); if (c == -1) break; if (c == '?') util_print_usage_and_die(app_name, options, option_help, NULL); switch (c) { case 'X': do_initialize = 1; action_count++; break; case OPT_SO_PIN: util_get_pin(optarg, &opt_so_pin); break; case OPT_PIN: util_get_pin(optarg, &opt_pin); break; case OPT_SERIAL_NUMBER: util_get_pin(optarg, &opt_serial_number); break; case OPT_NEW_KEY: util_get_pin(optarg, &opt_new_key); break; case 'U': do_unblock = 1; action_count++; break; case 'C': do_change_admin = 1; action_count++; break; case 'r': opt_reader = optarg; break; case 'v': verbose++; break; case 'w': opt_wait = 1; break; } } CRYPTO_malloc_init(); ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); memset(&ctx_param, 0, sizeof(sc_context_param_t)); ctx_param.app_name = app_name; r = sc_context_create(&ctx, &ctx_param); if (r != SC_SUCCESS) { fprintf(stderr, "Failed to establish context: %s\n", sc_strerror(r)); exit(1); } /* Only change if not in opensc.conf */ if (verbose > 1 && ctx->debug == 0) { ctx->debug = verbose; sc_ctx_log_to_file(ctx, "stderr"); } r = util_connect_card(ctx, &card, opt_reader, opt_wait, verbose); if (r != SC_SUCCESS) { if (r < 0) { fprintf(stderr, "Failed to connect to card: %s\n", sc_strerror(err)); } goto end; } sc_path_set(&path, SC_FILE_TYPE_WORKING_EF, gids_aid.value, gids_aid.len, 0, 0); r = sc_select_file(card, &path, NULL); if (r != SC_SUCCESS) { fprintf(stderr, "Failed to select application: %s\n", sc_strerror(r)); goto fail; } if (do_initialize && initialize(card, opt_so_pin, opt_pin, opt_serial_number)) goto fail; if (do_unblock && unblock(card, opt_so_pin, opt_pin)) goto fail; if (do_change_admin && changeAdminKey(card, opt_so_pin, opt_new_key)) goto fail; if (action_count == 0) { print_info(card); } err = 0; goto end; fail: err = 1; end: if (card) { sc_unlock(card); sc_disconnect_card(card); } if (ctx) sc_release_context(ctx); ERR_print_errors_fp(stderr); return err; }