Beispiel #1
0
int main(int argc, char **argv)
{
	FILE *f;
	int i;
	struct sc *sc;
	struct emu_fs *fs;

	if (argc == 1 || !strcmp(argv[1], "-"))
		f = stdout;
	else
		f = fopen(argv[1], "w");
	if (!f) {
		perror("fopen");
		return 1;
	}

	sc = scard_init(NULL);
	if (!sc) {
		printf("Cannot init scard\n");
		fclose(f);
		return 1;
	}

	scard_connect(sc, 0);
	if (scard_is_error(sc)) {
		printf("%s\n", scard_error(sc));
		fclose(f);
		return 1;
	}

	fs = emu_fs_new();
	for (i = 0; apps[i].name_len != 0; i++)
		emu_fs_append(fs, read_df(f, sc, apps[i].name, apps[i].name_len));

	emu_fs_dump(fs, f);

	fclose(f);

	emu_fs_free(fs);

	scard_disconnect(sc);
	if (scard_is_error(sc)) {
		printf("%s\n", scard_error(sc));
		return 1;
	}
	scard_shutdown(sc);

	return 0;
}
void scard_device_control(SCARD_DEVICE* scard, IRP* irp)
{
	uint32 output_len, input_len, ioctl_code;
	uint32 stream_len, result;
	uint32 pos, pad_len;
	uint32 irp_len;
	uint32 irp_result_pos, output_len_pos, result_pos;

	stream_read_uint32(irp->input, output_len);
	stream_read_uint32(irp->input, input_len);
	stream_read_uint32(irp->input, ioctl_code);

	stream_seek(irp->input, 20);	/* padding */

	// stream_seek(irp->input, 4);	/* TODO: parse len, le, v1 */
	// stream_seek(irp->input, 4);	/* 0xcccccccc */
	// stream_seek(irp->input, 4);	/* rpce len */

	/* [MS-RDPESC] 3.2.5.1 Sending Outgoing Messages */
	stream_extend(irp->output, 2048);

	irp_result_pos = stream_get_pos(irp->output);

	stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */

	/* [MS-RPCE] 2.2.6.1 */
	stream_write_uint32(irp->output, 0x00081001); /* len 8, LE, v1 */
	stream_write_uint32(irp->output, 0xcccccccc); /* filler */

	output_len_pos = stream_get_pos(irp->output);
	stream_seek(irp->output, 4);		/* size */

	stream_write_uint32(irp->output, 0x0);	/* filler */

	result_pos = stream_get_pos(irp->output);
	stream_seek(irp->output, 4);		/* result */

	/* body */
	switch (ioctl_code)
	{
		case SCARD_IOCTL_ESTABLISH_CONTEXT:
			result = handle_EstablishContext(irp);
			break;

		case SCARD_IOCTL_IS_VALID_CONTEXT:
			result = handle_IsValidContext(irp);
			break;

		case SCARD_IOCTL_RELEASE_CONTEXT:
			result = handle_ReleaseContext(irp);
			break;

		case SCARD_IOCTL_LIST_READERS:
			result = handle_ListReaders(irp, 0);
			break;
		case SCARD_IOCTL_LIST_READERS + 4:
			result = handle_ListReaders(irp, 1);
			break;

		case SCARD_IOCTL_LIST_READER_GROUPS:
		case SCARD_IOCTL_LIST_READER_GROUPS + 4:
			/* typically not used unless list_readers fail */
			result = SCARD_F_INTERNAL_ERROR;
			break;

		case SCARD_IOCTL_GET_STATUS_CHANGE:
			result = handle_GetStatusChange(irp, 0);
			break;
		case SCARD_IOCTL_GET_STATUS_CHANGE + 4:
			result = handle_GetStatusChange(irp, 1);
			break;

		case SCARD_IOCTL_CANCEL:
			result = handle_Cancel(irp);
			break;

		case SCARD_IOCTL_CONNECT:
			result = handle_Connect(irp, 0);
			break;
		case SCARD_IOCTL_CONNECT + 4:
			result = handle_Connect(irp, 1);
			break;

		case SCARD_IOCTL_RECONNECT:
			result = handle_Reconnect(irp);
			break;

		case SCARD_IOCTL_DISCONNECT:
			result = handle_Disconnect(irp);
			break;

		case SCARD_IOCTL_BEGIN_TRANSACTION:
			result = handle_BeginTransaction(irp);
			break;

		case SCARD_IOCTL_END_TRANSACTION:
			result = handle_EndTransaction(irp);
			break;

		case SCARD_IOCTL_STATE:
			result = handle_State(irp);
			break;

		case SCARD_IOCTL_STATUS:
			result = handle_Status(irp, 0);
			break;
		case SCARD_IOCTL_STATUS + 4:
			result = handle_Status(irp, 1);
			break;

		case SCARD_IOCTL_TRANSMIT:
			result = handle_Transmit(irp);
			break;

		case SCARD_IOCTL_CONTROL:
			result = handle_Control(irp);
			break;

		case SCARD_IOCTL_GETATTRIB:
			result = handle_GetAttrib(irp);
			break;

		case SCARD_IOCTL_ACCESS_STARTED_EVENT:
			result = handle_AccessStartedEvent(irp);
			break;

		case SCARD_IOCTL_LOCATE_CARDS_BY_ATR:
			result = handle_LocateCardsByATR(irp, 0);
			break;
		case SCARD_IOCTL_LOCATE_CARDS_BY_ATR + 4:
			result = handle_LocateCardsByATR(irp, 1);
			break;

		default:
			result = 0xc0000001;
			printf("scard unknown ioctl 0x%x\n", ioctl_code);
			break;
	}

	/* look for NTSTATUS errors */
	if ((result & 0xc0000000) == 0xc0000000)
		return scard_error(scard, irp, result);

	/* per Ludovic Rousseau, map different usage of this particular
  	 * error code between pcsc-lite & windows */
	if (result == 0x8010001F)
		result = 0x80100022;

	/* handle response packet */
	pos = stream_get_pos(irp->output);
	stream_len = pos - irp_result_pos - 4;

	stream_set_pos(irp->output, output_len_pos);
	stream_write_uint32(irp->output, stream_len - 24);

	stream_set_pos(irp->output, result_pos);
	stream_write_uint32(irp->output, result);

	stream_set_pos(irp->output, pos);

	/* pad stream to 16 byte align */
	pad_len = stream_len % 16;
	stream_write_zero(irp->output, pad_len);
	pos = stream_get_pos(irp->output);
	irp_len = stream_len + pad_len;

	stream_set_pos(irp->output, irp_result_pos);
	stream_write_uint32(irp->output, irp_len);
	stream_set_pos(irp->output, pos);

#ifdef WITH_DEBUG_SCARD
	freerdp_hexdump(stream_get_data(irp->output), stream_get_length(irp->output));
#endif
	irp->IoStatus = 0;

	irp->Complete(irp);

}
Beispiel #3
0
int main(void)
{
	int i;
	struct sc *sc;

	sc = scard_init(NULL);
	if (!sc) {
		printf("Cannot init scard\n");
		return 1;
	}

	scard_connect(sc, openemv_config_get_int("scard.reader", 0));
	if (scard_is_error(sc)) {
		printf("%s\n", scard_error(sc));
		return 1;
	}

	struct tlvdb *s;
	struct tlvdb *t;
	for (i = 0, s = NULL; apps[i].name_len != 0; i++) {
		const struct tlv aid_tlv = {
			.len = apps[i].name_len,
			.value = apps[i].name,
		};
		s = emv_select(sc, &aid_tlv);
		if (s)
			break;
	}
	if (!s)
		return 1;

	struct tlv *pdol_data_tlv = dol_process(tlvdb_get(s, 0x9f38, NULL), s, 0x83);
	if (!pdol_data_tlv)
		return 1;

	t = emv_gpo(sc, pdol_data_tlv);
	free(pdol_data_tlv);
	if (!t)
		return 1;
	tlvdb_add(s, t);

	struct tlv *sda_tlv = emv_read_records(sc, s);
	if (!sda_tlv)
		return 1;

	/* Only PTC read should happen before VERIFY */
	tlvdb_add(s, emv_get_data(sc, 0x9f17));

	verify_offline_clear(s, sc);

#define TAG(tag, len, value...) tlvdb_add(s, tlvdb_fixed(tag, len, (unsigned char[]){value}))
//	TAG(0x9f02, 6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
//	TAG(0x9f1a, 2, 0x06, 0x43);
	TAG(0x95, 5, 0x80, 0x00, 0x00, 0x00, 0x00);
//	TAG(0x5f2a, 2, 0x06, 0x43);
//	TAG(0x9a, 3, 0x14, 0x09, 0x25);
//	TAG(0x9c, 1, 0x50);
//	TAG(0x9f37, 4, 0x12, 0x34, 0x57, 0x79);
	TAG(0x9f35, 1, 0x34);
	TAG(0x9f34, 3, 0x01, 0x00, 0x02);
#undef TAG

	/* Generate ARQC */
	struct tlv *crm_tlv = dol_process(tlvdb_get(s, 0x8c, NULL), s, 0);
	if (!crm_tlv)
		return 1;
	t = emv_generate_ac(sc, 0x80, crm_tlv);
	free(crm_tlv);
	tlvdb_add(s, t);

	build_cap(s);

#define TAG(tag, len, value...) tlvdb_add(s, tlvdb_fixed(tag, len, (unsigned char[]){value}))
	TAG(0x8a, 2, 'Z', '3');
#undef TAG

	/* Generate AC asking for AAC */
	crm_tlv = dol_process(tlvdb_get(s, 0x8d, NULL), s, 0);
	if (!crm_tlv)
		return 1;
	t = emv_generate_ac(sc, 0x00, crm_tlv);
	free(crm_tlv);
	tlvdb_add(s, t);

	tlvdb_visit(s, print_cb, NULL);
	tlvdb_free(s);

	scard_disconnect(sc);
	if (scard_is_error(sc)) {
		printf("%s\n", scard_error(sc));
		return 1;
	}
	scard_shutdown(sc);

	return 0;
}
Beispiel #4
0
int main(void)
{
	int i;
	struct sc *sc;

	sc = scard_init(NULL);
	if (!sc) {
		printf("Cannot init scard\n");
		return 1;
	}

	scard_connect(sc, 0);
	if (scard_is_error(sc)) {
		printf("%s\n", scard_error(sc));
		return 1;
	}

	struct tlvdb *s;
	struct tlvdb *t;
	for (i = 0, s = NULL; apps[i].name_len != 0; i++) {
		s = emv_select(sc, apps[i].name, apps[i].name_len);
		if (s)
			break;
	}
	if (!s)
		return 1;

	size_t pdol_data_len;
	unsigned char *pdol_data = dol_process(tlvdb_get(s, 0x9f38, NULL), s, &pdol_data_len);
	struct tlv pdol_data_tlv = { .tag = 0x83, .len = pdol_data_len, .value = pdol_data };

	size_t pdol_data_tlv_data_len;
	unsigned char *pdol_data_tlv_data = tlv_encode(&pdol_data_tlv, &pdol_data_tlv_data_len);
	free(pdol_data);
	if (!pdol_data_tlv_data)
		return 1;

	t = emv_gpo(sc, pdol_data_tlv_data, pdol_data_tlv_data_len);
	free(pdol_data_tlv_data);
	if (!t)
		return 1;
	tlvdb_add(s, t);

	unsigned char *sda_data = NULL;
	size_t sda_len = 0;
	bool ok = emv_read_records(sc, s, &sda_data, &sda_len);
	if (!ok)
		return 1;

	free(sda_data);

	/* Generate AC asking for AAC */
	size_t crm_data_len;
	unsigned char *crm_data = dol_process(tlvdb_get(s, 0x8c, NULL), s, &crm_data_len);
	t = emv_generate_ac(sc, 0x00, crm_data, crm_data_len);
	free(crm_data);
	tlvdb_add(s, t);

	tlvdb_add(s, emv_get_data(sc, 0x9f36));
	tlvdb_add(s, emv_get_data(sc, 0x9f13));
	tlvdb_add(s, emv_get_data(sc, 0x9f17));
	tlvdb_add(s, emv_get_data(sc, 0x9f4f));

	tlvdb_visit(s, print_cb, NULL);

	const struct tlv *logent_tlv = tlvdb_get(s, 0x9f4d, NULL);
	const struct tlv *logent_dol = tlvdb_get(s, 0x9f4f, NULL);
	if (logent_tlv && logent_tlv->len == 2 && logent_dol) {
		for (i = 1; i <= logent_tlv->value[1]; i++) {
			unsigned short sw;
			size_t log_len;
			unsigned char *log = emv_read_record(sc, logent_tlv->value[0], i, &sw, &log_len);
			if (!log)
				continue;

			if (sw == 0x9000) {
				printf("Log #%d\n", i);
				struct tlvdb *log_db = dol_parse(logent_dol, log, log_len);
				tlvdb_visit(log_db, print_cb, NULL);
				tlvdb_free(log_db);
			}
			free(log);
		}
	}

	tlvdb_free(s);

	scard_disconnect(sc);
	if (scard_is_error(sc)) {
		printf("%s\n", scard_error(sc));
		return 1;
	}
	scard_shutdown(sc);

	return 0;
}