/*
 * Check whether a card was added/removed
 */
static int openct_reader_detect_card_presence(sc_reader_t *reader,
			sc_slot_info_t *slot)
{
	struct driver_data *data = (struct driver_data *) reader->drv_data;
	int rc, status;

	SC_FUNC_CALLED(reader->ctx, 1);

	slot->flags = 0;
	if (!data->h && !(data->h = ct_reader_connect(data->num)))
		return 0;

	if ((rc = ct_card_status(data->h, slot->id, &status)) < 0)
		return SC_ERROR_TRANSMIT_FAILED;

	if (status & IFD_CARD_PRESENT) {
		slot->flags = SC_SLOT_CARD_PRESENT;
		if (status & IFD_CARD_STATUS_CHANGED)
			slot->flags = SC_SLOT_CARD_PRESENT;
	}
	return slot->flags;
}
Ejemplo n.º 2
0
/*
 * Check whether a card was added/removed
 */
static int openct_reader_detect_card_presence(sc_reader_t *reader)
{
	struct driver_data *data = (struct driver_data *) reader->drv_data;
	int rc, status;

	SC_FUNC_CALLED(reader->ctx, SC_LOG_DEBUG_VERBOSE);

	if (reader->ctx->flags & SC_CTX_FLAG_TERMINATE)
		return SC_ERROR_NOT_ALLOWED;

	reader->flags = 0;
	if (!data->h && !(data->h = ct_reader_connect(data->num)))
		return 0;

	if ((rc = ct_card_status(data->h, data->slot, &status)) < 0)
		return SC_ERROR_TRANSMIT_FAILED;

	if (status & IFD_CARD_PRESENT) {
		reader->flags = SC_READER_CARD_PRESENT;
		if (status & IFD_CARD_STATUS_CHANGED)
			reader->flags = SC_READER_CARD_PRESENT;
	}
	return reader->flags;
}
int main(void) {
	unsigned char securid_atr[] = { 0x3b, 0x0f, 0x80, 0x22, 0x15, 0xe1, 0x5a, 0x00, 0x20, 0x00, 0x30, 0x21, 0x03, 0x31, 0x21, 0x03, 0x00 };
	unsigned char cmd1[] = { 0x00, 0xa4, 0x04, 0x00, 0x0a, 0xa0, 0x00, 0x00, 0x00, 0x63, 0x86, 0x53, 0x49, 0x44, 0x01};
	unsigned char cmd2[] = { 0x80, 0x56, 0x00, 0x00, 0x04 };
	unsigned char cmd3[] = { 0x80, 0x48, 0x00, 0x00, 0x04, 0xff, 0xff, 0xff, 0xff };
	unsigned char cmd4[] = { 0x80, 0x44, 0x00, 0x00, 0x05};
	unsigned char atr[64];
	int atr_len;
	unsigned char res[1024];
	ct_handle *h;
	ct_lock_handle lock1 = 0, lock2 = 0;
	unsigned int opt_slot = 0;
	int exit_code = 1;
	int status;
	int rc;
	int i;

	for (i = 0; i < OPENCT_MAX_READERS; i++) {
		if (
			(h = ct_reader_connect(i)) != NULL &&
			ct_card_lock(h, opt_slot, IFD_LOCK_SHARED, &lock1) >= 0 &&
			ct_card_status(h, opt_slot, &status) >= 0 &&
			(status & IFD_CARD_PRESENT) != 0 &&
			(atr_len = ct_card_reset(h, opt_slot, atr, sizeof(atr))) >= 0 &&
			sizeof(securid_atr) == (size_t)atr_len &&
			!memcmp(securid_atr, atr, atr_len)
		) {
			break;
		}

		if (lock1 != 0) {
			ct_card_unlock(h, 0, lock1);
			lock1 = 0;
		}

		if (h != NULL) {
			ct_reader_disconnect(h);
			h = NULL;
		}
	}
	if (i == OPENCT_MAX_READERS) {
		fprintf(stderr, "no RSA SecurID found\n");
		goto cleanup;
	}

	if ((rc = ct_card_lock(h, opt_slot, IFD_LOCK_EXCLUSIVE, &lock2)) < 0) {
		fprintf(stderr, "ct_card_lock: err=%d\n", rc);
		goto cleanup;
	}

	rc = ct_card_transact(h, opt_slot, cmd1, sizeof(cmd1), res, sizeof(res));
	if (rc < 0) {
		fprintf(stderr, "card communication failure (1), err=%d\n", rc);
		goto cleanup;
	}

	if ((rc != 2) || (res[0] != 0x90) || (res[1] != 0x00)) {
		fprintf(stderr, "cmd1 failed (%d): %02X%02X\n", rc, res[rc-2],
			res[rc-1]);
		goto cleanup;
	}

	rc = ct_card_transact(h, opt_slot, cmd2, sizeof(cmd2), res, sizeof(res));
	if (rc < 0) {
		fprintf(stderr, "card communication failure (2), err=%d\n", rc);
		goto cleanup;
	}

	if ((rc != 6) || (res[4] != 0x90) || (res[5] != 0x00)) {
		fprintf(stderr, "cmd2 failed (%d) : %02X%02X\n", rc, res[rc-2],
			res[rc-1]);
		goto cleanup;
	}

	/* get the argument for cmd3 from result of cmd2 */
	memcpy(cmd3+5, res, 4);

	/* non ISO APDU */
	rc = ct_card_transact(h, opt_slot, cmd3, sizeof(cmd3), res, sizeof(res));
	if (rc < 0) {
		fprintf(stderr, "card communication failure (3), err=%d\n", rc);
		goto cleanup;
	}

	if ((rc != 2) || (res[0] != 0x90) || (res[1] != 0x00)) {
		fprintf(stderr, "cmd3 failed (%d): %02X%02X\n", rc, res[rc-2],
			res[rc-1]);
		goto cleanup;
	}

	/* non iSO APDU */
	rc = ct_card_transact(h, opt_slot, cmd4, sizeof(cmd4), res, sizeof(res));
	if (rc < 0) {
		fprintf(stderr, "card communication failure (4), err=%d\n", rc);
		goto cleanup;
	}

	if ((rc != 7) || (res[5] != 0x90) || (res[6] != 0x00)) {
		fprintf(stderr, "cmd4 failed (%d): %02X%02X\n", rc, res[rc-2],
			res[rc-1]);
		goto cleanup;
	}

	printf("%02X%02X%02X\n", res[2], res[3], res[4]);
	exit_code = 0;

cleanup:

	if (lock2 != 0) {
		ct_card_unlock(h, 0, lock2);
	}
	if (lock1 != 0) {
		ct_card_unlock(h, 0, lock1);
	}
	if (h != NULL) {
		ct_reader_disconnect(h);
	}
	sleep(1);
	return exit_code;
}