int main(int argc, char * const argv[]) { int r, c, long_optind = 0, err = 0; char *line; int cargc; char *cargv[260]; sc_context_param_t ctx_param; int lcycle = SC_CARDCTRL_LIFECYCLE_ADMIN; printf("OpenSC Explorer version %s\n", sc_get_version()); while (1) { c = getopt_long(argc, argv, "r:c:vwm:", options, &long_optind); if (c == -1) break; if (c == '?') util_print_usage_and_die(app_name, options, option_help); switch (c) { case 'r': opt_reader = optarg; break; case 'c': opt_driver = optarg; break; case 'w': opt_wait = 1; break; case 'v': verbose++; break; case 'm': opt_startfile = optarg; break; } } 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, 0); if (err) goto end; if (opt_startfile) { if(*opt_startfile) { char startpath[1024]; char *args[] = { startpath }; strncpy(startpath, opt_startfile, sizeof(startpath)-1); r = do_cd(1, args); if (r) { printf("unable to select file %s: %s\n", opt_startfile, sc_strerror(r)); return -1; } } } else { sc_format_path("3F00", ¤t_path); r = sc_select_file(card, ¤t_path, ¤t_file); if (r) { printf("unable to select MF: %s\n", sc_strerror(r)); return 1; } } r = sc_card_ctl(card, SC_CARDCTL_LIFECYCLE_SET, &lcycle); if (r && r != SC_ERROR_NOT_SUPPORTED) printf("unable to change lifecycle: %s\n", sc_strerror(r)); while (1) { struct command *cmd; char prompt[3*SC_MAX_PATH_STRING_SIZE]; sprintf(prompt, "OpenSC [%s]> ", path_to_filename(¤t_path, '/')); line = my_readline(prompt); if (line == NULL) break; cargc = parse_line(line, cargv, DIM(cargv)); if (cargc < 1) continue; for (r=cargc; r < (int)DIM(cargv); r++) cargv[r] = ""; cmd = ambiguous_match(cmds, cargv[0]); if (cmd == NULL) { do_help(0, NULL); } else { cmd->func(cargc-1, cargv+1); } } end: die(err); return 0; /* not reached */ }
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 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 sc_context_create(sc_context_t **ctx_out, const sc_context_param_t *parm) { sc_context_t *ctx; struct _sc_ctx_options opts; int r; if (ctx_out == NULL || parm == NULL) return SC_ERROR_INVALID_ARGUMENTS; ctx = calloc(1, sizeof(sc_context_t)); if (ctx == NULL) return SC_ERROR_OUT_OF_MEMORY; memset(&opts, 0, sizeof(opts)); /* set the application name if set in the parameter options */ if (parm->app_name != NULL) ctx->app_name = strdup(parm->app_name); else ctx->app_name = strdup("default"); if (ctx->app_name == NULL) { sc_release_context(ctx); return SC_ERROR_OUT_OF_MEMORY; } set_defaults(ctx, &opts); list_init(&ctx->readers); list_attributes_seeker(&ctx->readers, reader_list_seeker); /* set thread context and create mutex object (if specified) */ if (parm->thread_ctx != NULL) ctx->thread_ctx = parm->thread_ctx; r = sc_mutex_create(ctx, &ctx->mutex); if (r != SC_SUCCESS) { sc_release_context(ctx); return r; } process_config_file(ctx, &opts); sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "==================================="); /* first thing in the log */ sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "opensc version: %s", sc_get_version()); #ifdef HAVE_LTDL_H /* initialize ltdl, if available. See scdl.c for more information */ if (lt_dlinit() != 0) { sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "lt_dlinit() failed"); sc_release_context(ctx); return SC_ERROR_INTERNAL; } #endif #ifdef ENABLE_PCSC ctx->reader_driver = sc_get_pcsc_driver(); /* XXX: remove cardmod pseudoreader driver */ #ifdef ENABLE_MINIDRIVER if(strcmp(ctx->app_name, "cardmod") == 0) { ctx->reader_driver = sc_get_cardmod_driver(); } #endif #elif ENABLE_CTAPI ctx->reader_driver = sc_get_ctapi_driver(); #elif ENABLE_OPENCT ctx->reader_driver = sc_get_openct_driver(); #endif load_reader_driver_options(ctx); ctx->reader_driver->ops->init(ctx); load_card_drivers(ctx, &opts); load_card_atrs(ctx); if (opts.forced_card_driver) { /* FIXME: check return value? */ sc_set_card_driver(ctx, opts.forced_card_driver); free(opts.forced_card_driver); } del_drvs(&opts); sc_ctx_detect_readers(ctx); *ctx_out = ctx; return SC_SUCCESS; }
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 *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 main(int argc, char * const argv[]) { int r, c, long_optind = 0, err = 0; char *line; int cargc; char *cargv[20]; sc_context_param_t ctx_param; printf("OpenSC Explorer version %s\n", sc_get_version()); while (1) { c = getopt_long(argc, argv, "r:c:vw", options, &long_optind); if (c == -1) break; if (c == '?') print_usage_and_die(app_name, options, option_help); switch (c) { case 'r': opt_reader = atoi(optarg); break; case 'c': opt_driver = optarg; break; case 'w': opt_wait = 1; break; case 'v': verbose++; break; } } 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 (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, 0); if (err) goto end; sc_format_path("3F00", ¤t_path); r = sc_select_file(card, ¤t_path, ¤t_file); if (r) { printf("unable to select MF: %s\n", sc_strerror(r)); return 1; } while (1) { struct command *cmd; size_t i; char prompt[40]; sprintf(prompt, "OpenSC ["); for (i = 0; i < current_path.len; i++) { if ((i & 1) == 0 && i && current_path.type != SC_PATH_TYPE_DF_NAME) sprintf(prompt+strlen(prompt), "/"); sprintf(prompt+strlen(prompt), "%02X", current_path.value[i]); } sprintf(prompt+strlen(prompt), "]> "); line = my_readline(prompt); if (line == NULL) break; cargc = parse_line(line, cargv, DIM(cargv)); if (cargc < 1) continue; for (r=cargc; r < (int)DIM(cargv); r++) cargv[r] = ""; cmd = ambiguous_match(cmds, cargv[0]); if (cmd == NULL) { usage(); } else { cmd->func(cargc-1, cargv+1); } } end: die(err); return 0; /* not reached */ }