Esempio n. 1
0
static int do_change(int argc, char **argv)
{
	int ref, r, tries_left = -1;
	u8 oldpin[64];
	u8 newpin[64];
	size_t oldpinlen = 0;
	size_t newpinlen = 0;
	struct sc_pin_cmd_data data;

	memset(&data, 0, sizeof(data));
	data.cmd = SC_PIN_CMD_CHANGE;

	if (argc < 1 || argc > 3)
		return usage(do_change);
	if (strncasecmp(argv[0], "CHV", 3)) {
		printf("Invalid type.\n");
		return usage(do_change);
	}
	if (sscanf(argv[0] + 3, "%d", &ref) != 1) {
		printf("Invalid key reference.\n");
		return usage(do_change);
	}

	if (argc == 3) {
		oldpinlen = sizeof(oldpin);
		if (parse_string_or_hexdata(argv[1], oldpin, &oldpinlen) != 0) {
			printf("Invalid key value.\n");
			return usage(do_change);
		}
	}

	if (argc >= 2) {
		newpinlen = sizeof(newpin);
		if (parse_string_or_hexdata(argv[argc-1], newpin, &newpinlen) != 0) {
			printf("Invalid key value.\n");
			return usage(do_change);
		}
	}

	data.pin_type = SC_AC_CHV;
	data.pin_reference = ref;
	data.pin1.data = oldpinlen ? oldpin : NULL;
	data.pin1.len = oldpinlen;
	data.pin2.data = newpinlen ? newpin : NULL;
	data.pin2.len = newpinlen;

	r = sc_pin_cmd(card, &data, &tries_left);
	if (r) {
		if (r == SC_ERROR_PIN_CODE_INCORRECT) {
			if (tries_left >= 0)
				printf("Incorrect code, %d tries left.\n", tries_left);
			else
				printf("Incorrect code.\n");
		}
		printf("Unable to change PIN code: %s\n", sc_strerror(r));
		return -1;
	}
	printf("PIN changed.\n");
	return 0;
}
static int do_unblock(int argc, char **argv)
{
	int ref, r;
	u8 puk[30];
	u8 newpin[30];
	size_t puklen = 0;
	size_t newpinlen = 0;

	if (argc < 1 || argc > 3)
		goto usage;
	if (strncasecmp(argv[0], "CHV", 3)) {
		printf("Invalid type.\n");
		goto usage;
	}
	if (sscanf(argv[0] + 3, "%d", &ref) != 1) {
		printf("Invalid key reference.\n");
		goto usage;
	}

	if (argc > 1) {
		puklen = sizeof(puk);
		if (parse_string_or_hexdata(argv[1], puk, &puklen) != 0) {
			printf("Invalid key value.\n");
			goto usage;
		}
	}

	if (argc > 2)   {
		newpinlen = sizeof(newpin);
		if (parse_string_or_hexdata(argv[2], newpin, &newpinlen) != 0) {
			printf("Invalid key value.\n");
			goto usage;
		}
	}

	r = sc_reset_retry_counter (card, SC_AC_CHV, ref,
                                      puklen ? puk : NULL, puklen,
                                      newpinlen ? newpin : NULL, newpinlen);
	if (r) {
		if (r == SC_ERROR_PIN_CODE_INCORRECT)
			printf("Incorrect code.\n");
		printf("Unable to unblock PIN code: %s\n", sc_strerror(r));
		return -1;
	}
	printf("PIN unblocked.\n");
	return 0;
usage:
	printf("Usage: unblock CHV<pin ref> [<puk> [<new pin>]]\n");
	printf("PUK and PIN values can be hexadecimal, ASCII, empty (\"\") or absent\n");
	printf("Examples:\n");
	printf("\tUnblock PIN and set a new value:   unblock CHV2 00:00:00:00:00:00 \"foobar\"\n");
	printf("\tUnblock PIN keeping the old value: unblock CHV2 00:00:00:00:00:00 \"\"\n");
	printf("\tSet new PIN value:                 unblock CHV2 \"\" \"foobar\"\n");
	printf("Examples with pinpad:\n");
	printf("\tUnblock PIN: new PIN value is prompted by pinpad:                   unblock CHV2 00:00:00:00:00:00\n");
	printf("\tSet PIN: new PIN value is prompted by pinpad:                       unblock CHV2 \"\"\n");
	printf("\tUnblock PIN: unblock code and new PIN value are prompted by pinpad: unblock CHV2\n");
	return -1;
}
static int do_change(int argc, char **argv)
{
	int ref, r, tries_left = -1;
	u8 oldpin[30];
	u8 newpin[30];
	size_t oldpinlen = 0;
	size_t newpinlen = 0;

	if (argc < 1 || argc > 3)
		goto usage;
	if (strncasecmp(argv[0], "CHV", 3)) {
		printf("Invalid type.\n");
		goto usage;
	}
	if (sscanf(argv[0] + 3, "%d", &ref) != 1) {
		printf("Invalid key reference.\n");
		goto usage;
	}

	if (argc == 3) {
		oldpinlen = sizeof(oldpin);
		if (parse_string_or_hexdata(argv[1], oldpin, &oldpinlen) != 0) {
			printf("Invalid key value.\n");
			goto usage;
		}
	}

	if (argc >= 2) {
		newpinlen = sizeof(newpin);
		if (parse_string_or_hexdata(argv[argc-1], newpin, &newpinlen) != 0) {
			printf("Invalid key value.\n");
			goto usage;
		}
	}

	r = sc_change_reference_data (card, SC_AC_CHV, ref,
                                      oldpinlen ? oldpin : NULL, oldpinlen,
                                      newpinlen ? newpin : NULL, newpinlen,
                                      &tries_left);
	if (r) {
		if (r == SC_ERROR_PIN_CODE_INCORRECT) {
			if (tries_left >= 0) 
				printf("Incorrect code, %d tries left.\n", tries_left);
			else
				printf("Incorrect code.\n");
		}
		printf("Unable to change PIN code: %s\n", sc_strerror(r));
		return -1;
	}
	printf("PIN changed.\n");
	return 0;
usage:
	printf("Usage: change CHV<pin ref> [[<old pin>] <new pin>]\n");
	printf("Examples: \n");
	printf("\tChange PIN: change CHV2 00:00:00:00:00:00 \"foobar\"\n");
	printf("\tSet PIN: change CHV2 \"foobar\"\n");
	printf("\tChange PIN with pinpad': change CHV2\n");
	return -1;
}
Esempio n. 4
0
static int do_unblock(int argc, char **argv)
{
	int ref, r;
	u8 puk[64];
	u8 newpin[64];
	size_t puklen = 0;
	size_t newpinlen = 0;
	struct sc_pin_cmd_data data;

	memset(&data, 0, sizeof(data));
	data.cmd = SC_PIN_CMD_UNBLOCK;

	if (argc < 1 || argc > 3)
		return usage(do_unblock);
	if (strncasecmp(argv[0], "CHV", 3)) {
		printf("Invalid type.\n");
		return usage(do_unblock);
	}
	if (sscanf(argv[0] + 3, "%d", &ref) != 1) {
		printf("Invalid key reference.\n");
		return usage(do_unblock);
	}

	if (argc > 1) {
		puklen = sizeof(puk);
		if (parse_string_or_hexdata(argv[1], puk, &puklen) != 0) {
			printf("Invalid key value.\n");
			return usage(do_unblock);
		}
	}

	if (argc > 2)   {
		newpinlen = sizeof(newpin);
		if (parse_string_or_hexdata(argv[2], newpin, &newpinlen) != 0) {
			printf("Invalid key value.\n");
			return usage(do_unblock);
		}
	}

	data.pin_type = SC_AC_CHV;
	data.pin_reference = ref;
	data.pin1.data = puklen ? puk : NULL;
	data.pin1.len = puklen;
	data.pin2.data = newpinlen ? newpin : NULL;
	data.pin2.len = newpinlen;

	r = sc_pin_cmd(card, &data, NULL);
	if (r) {
		if (r == SC_ERROR_PIN_CODE_INCORRECT)
			printf("Incorrect code.\n");
		printf("Unable to unblock PIN code: %s\n", sc_strerror(r));
		return -1;
	}
	printf("PIN unblocked.\n");
	return 0;
}
static int do_update_record(int argc, char **argv)
{
	u8 buf[240];
	size_t buflen;
	int r, i, err = 1;
	int rec, offs;
	sc_path_t path;
	sc_file_t *file;

	if (argc != 4)
		return usage(do_update_record);
	if (arg_to_path(argv[0], &path, 0) != 0)
		return usage(do_update_record);
	rec  = strtol(argv[1],NULL,10);
	offs = strtol(argv[2],NULL,10);

	printf("in: %i; %i; %s\n", rec, offs, argv[3]);

	r = sc_select_file(card, &path, &file);
	if (r) {
		check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file);
		return -1;
	}

	if (file->ef_structure != SC_FILE_EF_LINEAR_VARIABLE)   {
		printf("EF structure should be SC_FILE_EF_LINEAR_VARIABLE\n");
		goto err;
	} else if (rec < 1 || rec > file->record_count)   {
		printf("Invalid record number %i\n", rec);
		goto err;
	}

	r = sc_read_record(card, rec, buf, sizeof(buf), SC_RECORD_BY_REC_NR);
	if (r<0)   {
		printf("Cannot read record %i; return %i\n", rec, r);
		goto err;;
	}

	buflen = sizeof(buf) - offs;
	i = parse_string_or_hexdata(argv[3], buf + offs, &buflen);
	if (!i) {
		printf("unable to parse data\n");
		goto err;
	}

	r = sc_update_record(card, rec, buf, r, SC_RECORD_BY_REC_NR);
	if (r<0)   {
		printf("Cannot update record %i; return %i\n", rec, r);
		goto err;
	}

	printf("Total of %d bytes written to record %i at %i offset.\n", 
	       i, rec, offs);

	err = 0;
err:
	sc_file_free(file);
	select_current_path_or_die();
	return -err;
}
Esempio n. 6
0
/**
 * Use PUT DATA command to write to Data Object.
 **/
static int do_put_data(int argc, char **argv)
{
	unsigned int tag;
	u8 buf[8192];
	size_t buflen = sizeof(buf);
	int r;

	if (argc != 2)
		return usage(do_put_data);

	/* Extract DO's tag */
	tag = strtoul(argv[0], NULL, 16);

	/* Extract the new content */
	/* buflen is the max length of reception buffer */
	r = parse_string_or_hexdata(argv[1], buf, &buflen);
	if (r < 0) {
		printf("unable to parse data\n");
		return -1;
	}

	/* Call OpenSC to do put data */
	r = sc_put_data(card, tag, buf, buflen);
	if (r < 0) {
		printf("Cannot put data to %04X; return %i\n", tag, r);
		return -1;
	}

	printf("Total of %d bytes written.\n", r);

	return 0;
}
Esempio n. 7
0
static int do_apdu(int argc, char **argv)
{
	sc_apdu_t apdu;
	u8 buf[SC_MAX_APDU_BUFFER_SIZE * 2];
	u8 rbuf[SC_MAX_APDU_BUFFER_SIZE * 2];
	size_t len, i;
	int r;

	if (argc < 1)
		return usage(do_apdu);

	for (i = 0, len = 0; i < (unsigned) argc; i++)   {
		size_t len0 = strlen(argv[i]);

		if ((r = parse_string_or_hexdata(argv[i], buf + len, &len0)) < 0) {
			fprintf(stderr, "error parsing %s: %s\n", argv[i], sc_strerror(r));
			return r;
		};
		len += len0;
	}

	r = sc_bytes2apdu(card->ctx, buf, len, &apdu);
	if (r) {
		fprintf(stderr, "Invalid APDU: %s\n", sc_strerror(r));
		return 2;
	}

	apdu.resp = rbuf;
	apdu.resplen = sizeof(rbuf);

	printf("Sending: ");
	util_hex_dump(stdout, buf, len, " ");
	printf("\n");
	r = sc_transmit_apdu(card, &apdu);
	if (r) {
		fprintf(stderr, "APDU transmit failed: %s\n", sc_strerror(r));
		return 1;
	}
	printf("Received (SW1=0x%02X, SW2=0x%02X)%s\n", apdu.sw1, apdu.sw2,
	       apdu.resplen ? ":" : "");
	if (apdu.resplen)
		util_hex_dump_asc(stdout, apdu.resp, apdu.resplen, -1);

	r = sc_check_sw(card, apdu.sw1, apdu.sw2);
	if (r)
		printf("Failure: %s\n", sc_strerror(r));
	else
		printf("Success!\n");

	return 0;
}
static int do_update_binary(int argc, char **argv)
{
	u8 buf[240];
	size_t buflen = sizeof(buf);
	int r, err = 1;
	int offs;
	sc_path_t path;
	sc_file_t *file;

	if (argc != 3)
		return usage(do_update_binary);
	if (arg_to_path(argv[0], &path, 0) != 0)
		return usage(do_update_binary);
	offs = strtol(argv[1],NULL,10);

	printf("in: %i; %s\n", offs, argv[2]);

	r = parse_string_or_hexdata(argv[2], buf, &buflen);
	if (r < 0) {
		printf("unable to parse data\n");
		return -1;
	}

	r = sc_select_file(card, &path, &file);
	if (r) {
		check_ret(r, SC_AC_OP_SELECT, "unable to select file", current_file);
		return -1;
	}

	if (file->ef_structure != SC_FILE_EF_TRANSPARENT)   {
		printf("EF structure should be SC_FILE_EF_TRANSPARENT\n");
		goto err;
	}

	r = sc_update_binary(card, offs, buf, buflen, 0);
	if (r < 0) {
		printf("Cannot update %04X; return %i\n", file->id, r);
		goto err;
	}

	printf("Total of %d bytes written to %04X at %i offset.\n", 
	       r, file->id, offs);

	err = 0;
err:
	sc_file_free(file);
	select_current_path_or_die();
	return -err;
}
static int do_verify(int argc, char **argv)
{
	const id2str_t typeNames[] = {
		{ SC_AC_CHV,	"CHV"	},
		{ SC_AC_AUT,	"KEY"	},
		{ SC_AC_AUT,	"AUT"	},
		{ SC_AC_PRO,	"PRO"	},
		{ SC_AC_NONE,	NULL, 	}
	};
	int r, tries_left = -1;
	u8 buf[64];
	size_t buflen = sizeof(buf), i;
	struct sc_pin_cmd_data data;

	if (argc < 1 || argc > 2)
		goto usage;

	memset(&data, 0, sizeof(data));
	data.cmd = SC_PIN_CMD_VERIFY;

	data.pin_type = SC_AC_NONE;
	for (i = 0; typeNames[i].str; i++) {
		if (strncasecmp(argv[0], typeNames[i].str, 3) == 0) {
			data.pin_type = typeNames[i].id;
			break;
		}
	}
	if (data.pin_type == SC_AC_NONE) {
		printf("Invalid type.\n");
		goto usage;
	}
	if (sscanf(argv[0] + 3, "%d", &data.pin_reference) != 1) {
		printf("Invalid key reference.\n");
		goto usage;
	}

	if (argc < 2) {
		if (!(card->reader->capabilities & SC_READER_CAP_PIN_PAD)) {
			printf("Card reader or driver doesn't support PIN PAD\n");
			return -1;
		}
		printf("Please enter PIN on the reader's pin pad.\n");
		data.pin1.prompt = "Please enter PIN";
		data.flags |= SC_PIN_CMD_USE_PINPAD;
	} else {
		r = parse_string_or_hexdata(argv[1], buf, &buflen);
		if (0 != r) {
			printf("Invalid key value.\n");
			goto usage;
		}
		data.pin1.data = buf;
		data.pin1.len = buflen;
	}
	r = sc_pin_cmd(card, &data, &tries_left);

	if (r) {
		if (r == SC_ERROR_PIN_CODE_INCORRECT) {
			if (tries_left >= 0) 
				printf("Incorrect code, %d tries left.\n", tries_left);
			else
				printf("Incorrect code.\n");
		} else
			printf("Unable to verify PIN code: %s\n", sc_strerror(r));
		return -1;
	}
	printf("Code correct.\n");
	return 0;
usage:
	printf("Usage: verify <key type><key ref> [<pin>]\n");
	printf("Possible values of <key type>:\n");
	for (i = 0; typeNames[i].str; i++)
		printf("\t%s\n", typeNames[i].str);
	printf("Example: verify CHV2 31:32:33:34:00:00:00:00\n");
	printf("If key is omitted, card reader's keypad will be used to collect PIN.\n");
	return -1;
}
Esempio n. 10
0
static int do_verify(int argc, char **argv)
{
	const id2str_t typeNames[] = {
		{ SC_AC_CHV,	"CHV"	},
		{ SC_AC_AUT,	"KEY"	},
		{ SC_AC_AUT,	"AUT"	},
		{ SC_AC_PRO,	"PRO"	},
		{ SC_AC_NONE,	NULL, 	}
	};
	int r, tries_left = -1;
	u8 buf[64];
	size_t buflen = sizeof(buf), i;
	struct sc_pin_cmd_data data;
	int prefix_len = 0;

	if (argc < 1 || argc > 2)
		return usage(do_verify);

	memset(&data, 0, sizeof(data));
	data.cmd = SC_PIN_CMD_VERIFY;

	data.pin_type = SC_AC_NONE;
	for (i = 0; typeNames[i].str; i++) {
		prefix_len = strlen(typeNames[i].str);
		if (strncasecmp(argv[0], typeNames[i].str, prefix_len) == 0) {
			data.pin_type = typeNames[i].id;
			break;
		}
	}
	if (data.pin_type == SC_AC_NONE) {
		printf("Invalid type.\n");
		return usage(do_verify);
	}
	if (sscanf(argv[0] + prefix_len, "%d", &data.pin_reference) != 1) {
		printf("Invalid key reference.\n");
		return usage(do_verify);
	}

	if (argc < 2) {
		if (card->reader->capabilities & SC_READER_CAP_PIN_PAD) {
			printf("Please enter PIN on the reader's pin pad.\n");
			data.pin1.prompt = "Please enter PIN";
			data.flags |= SC_PIN_CMD_USE_PINPAD;
		}
		else {
			char *pin = NULL;
			size_t len = 0;

			printf("Please enter PIN: ");
			r = util_getpass(&pin, &len, stdin);
			if (r < 0) {
				printf("No PIN entered - aborting VERIFY.\n");
				return -1;
			}

			if (strlcpy((char *)buf, pin, sizeof(buf)) >= sizeof(buf)) {
				free(pin);
				printf("PIN too long - aborting VERIFY.\n");
				return -1;
			}
			free(pin);
			data.pin1.data = buf;
			data.pin1.len = strlen((char *)buf);
		}
	} else {
		r = parse_string_or_hexdata(argv[1], buf, &buflen);
		if (0 != r) {
			printf("Invalid key value.\n");
			return usage(do_verify);
		}
		data.pin1.data = buf;
		data.pin1.len = buflen;
	}
	r = sc_pin_cmd(card, &data, &tries_left);

	if (r) {
		if (r == SC_ERROR_PIN_CODE_INCORRECT) {
			if (tries_left >= 0)
				printf("Incorrect code, %d tries left.\n", tries_left);
			else
				printf("Incorrect code.\n");
		} else
			printf("Unable to verify PIN code: %s\n", sc_strerror(r));
		return -1;
	}
	printf("Code correct.\n");
	return 0;
}