Exemple #1
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;

	/* 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);
}
Exemple #2
0
/* 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);
    }
}
Exemple #3
0
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;
}
Exemple #4
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;
}
Exemple #5
0
static void die(int ret)
{
	if (card) {
		sc_unlock(card);
		sc_disconnect_card(card, 0);
	}
	if (ctx)
		sc_release_context(ctx);
	exit(ret);
}
Exemple #6
0
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;
	}
}
Exemple #9
0
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;
}
Exemple #10
0
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);
}
Exemple #12
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;
}
Exemple #13
0
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;
}
Exemple #14
0
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;
}
Exemple #15
0
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;
}
Exemple #17
0
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;
}
Exemple #18
0
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;
}
Exemple #19
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;
}
Exemple #20
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);
}
Exemple #21
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\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);
}
Exemple #22
0
void sc_test_cleanup(void)
{
	sc_disconnect_card(card);
	sc_release_context(ctx);
}
Exemple #23
0
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;
}