示例#1
0
static int cda_test_pk(void)
{
	const struct emv_pk *pk = &mchip_05;
	struct tlvdb *db;

	db = tlvdb_external(0x90, sizeof(issuer_cert), issuer_cert);
	tlvdb_add(db, tlvdb_external(0x9f32, sizeof(issuer_exp), issuer_exp));
	tlvdb_add(db, tlvdb_external(0x92, sizeof(issuer_rem), issuer_rem));
	tlvdb_add(db, tlvdb_external(0x5a, sizeof(pan), pan));

	struct emv_pk *ipk = emv_pki_recover_issuer_cert(pk, db);
	if (!ipk) {
		fprintf(stderr, "Could not recover Issuer certificate!\n");
		tlvdb_free(db);
		return 2;
	}

	tlvdb_add(db, tlvdb_external(0x9f46, sizeof(icc_cert), icc_cert));
	tlvdb_add(db, tlvdb_external(0x9f47, sizeof(icc_exp), icc_exp));
	/*tlvdb_add(db, tlvdb_external(0x9f48, sizeof(issuer_rem), issuer_rem));*/

	struct emv_pk *iccpk = emv_pki_recover_icc_cert(ipk, db, &ssd1_tlv);
	if (!iccpk) {
		fprintf(stderr, "Could not recover ICC certificate!\n");
		emv_pk_free(ipk);
		tlvdb_free(db);
		return 2;
	}

	tlvdb_add(db, tlvdb_fixed(0x9f37, sizeof(dd1), dd1));

	struct tlvdb *cda_db;
	cda_db = tlvdb_fixed(0x9f27, 1, (unsigned char[]){ 0x40 });
示例#2
0
struct tlvdb *dol_parse(const struct tlv *tlv, const unsigned char *data, size_t data_len)
{
	if (!tlv)
		return NULL;

	const unsigned char *buf = tlv->value;
	size_t left = tlv->len;
	size_t res_len = dol_calculate_len(tlv, data_len);
	size_t pos = 0;
	struct tlvdb *db = NULL;

	if (res_len != data_len)
		return NULL;

	while (left) {
		struct tlv cur_tlv;
		if (!tlv_parse_tl(&buf, &left, &cur_tlv) || pos + cur_tlv.len > res_len) {
			tlvdb_free(db);
			return NULL;
		}

		/* Last tag can be of variable length */
		if (cur_tlv.len == 0 && left == 0)
			cur_tlv.len = res_len - pos;

		struct tlvdb *tag_db = tlvdb_fixed(cur_tlv.tag, cur_tlv.len, data + pos);
		if (!db)
			db = tag_db;
		else
			tlvdb_add(db, tag_db);

		pos += cur_tlv.len;
	}

	return db;
}
示例#3
0
static int sda_test_pk(void)
{
	const struct emv_pk *pk = &vsdc_01;
	struct tlvdb *db;

	db = tlvdb_external(0x90, sizeof(issuer_cert), issuer_cert);
	tlvdb_add(db, tlvdb_external(0x9f32, sizeof(issuer_exp), issuer_exp));
	tlvdb_add(db, tlvdb_external(0x92, sizeof(issuer_rem), issuer_rem));

	struct emv_pk *ipk = emv_pki_recover_issuer_cert(pk, db);
	if (!ipk) {
		fprintf(stderr, "Could not recover Issuer certificate!\n");
		tlvdb_free(db);
		return 2;
	}

	tlvdb_add(db, tlvdb_external(0x93, sizeof(ssad_cr), ssad_cr));

	struct tlvdb *dacdb = emv_pki_recover_dac(ipk, db, ssd1, sizeof(ssd1));
	if (!dacdb) {
		fprintf(stderr, "Could not recover DAC!\n");
		emv_pk_free(ipk);
		tlvdb_free(db);
		return 2;
	}

	const struct tlv *dac = tlvdb_get(dacdb, 0x9f45, NULL);
	if (!dac) {
		fprintf(stderr, "DAC not found!\n");
		tlvdb_free(dacdb);
		emv_pk_free(ipk);
		tlvdb_free(db);
		return 2;
	}

	dump_buffer(dac->value, dac->len, stdout);

	tlvdb_free(dacdb);
	emv_pk_free(ipk);
	tlvdb_free(db);

	return 0;
}
示例#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, 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;
}
示例#5
0
static struct emu_df *read_df(FILE *f, struct sc *sc, const unsigned char *name, size_t name_len)
{
	struct emu_df *df;
	int i, j;
	struct tlvdb *s;
	unsigned short sw;
	size_t outlen;
	unsigned char *outbuf;
	struct tlv pdol_data_tlv;
	size_t pdol_data_len;
	unsigned char *pdol_data;

	outbuf = sc_command(sc, 0x00, 0xa4, 0x04, 0x00, name_len, name, &sw, &outlen);
	if (sw != 0x9000)
		return NULL;

	s = tlvdb_parse(outbuf, outlen);
	if (!s)
		return NULL;

	df = emu_df_new();

	pdol_data_tlv.tag = 0x83;
	pdol_data_tlv.value = dol_process(tlvdb_get(s, 0x9f38, NULL), s, &pdol_data_tlv.len);
	pdol_data = tlv_encode(&pdol_data_tlv, &pdol_data_len);
	if (!pdol_data)
		return NULL;
	free((unsigned char *)pdol_data_tlv.value);

	tlvdb_free(s);

	emu_df_append(df, emu_property_new("name", emu_value_new_buf(name, name_len)));

	emu_df_append(df, emu_property_new("fci", emu_value_new_buf(outbuf, outlen)));
	free(outbuf);

	outbuf = sc_command(sc, 0x80, 0xa8, 0x00, 0x00, pdol_data_len, pdol_data, &sw, &outlen);
	free(pdol_data);
	if (sw == 0x9000) {
		emu_df_append(df, emu_property_new("gpo", emu_value_new_buf(outbuf, outlen)));
		free(outbuf);
	}

	for (i = 1; i < 31; i++) {
		int last = 0;
		struct emu_value *value = NULL;
		char buf[7];

		snprintf(buf, sizeof(buf), "sfi%d", i);

		for (j = 1; j < 256; j++) {
			outbuf = sc_command(sc, 0x00, 0xb2, j, (i << 3) | 4, 0, NULL, &sw, &outlen);
			if (sw == 0x6985)
				continue;
			else if (sw != 0x9000)
				break;

			for (; last < j - 1; last++)
				value = emu_value_append(value, "");

			value = emu_value_append_buf(value, outbuf, outlen);
			last ++;
			free(outbuf);
		}
		if (value)
			emu_df_append(df, emu_property_new(buf, value));
	}

	for (i = 0; card_data[i]; i++) {
		char buf[10];
		tlv_tag_t tag = card_data[i];
		outbuf = sc_command(sc, 0x80, 0xca, tag >> 8, tag & 0xff, 0, NULL, &sw, &outlen);
		if (sw != 0x9000)
			continue;

		snprintf(buf, sizeof(buf), "data%x", tag);
		emu_df_append(df, emu_property_new(buf, emu_value_new_buf(outbuf, outlen)));
		free(outbuf);
	}

	return df;
}
示例#6
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;
}