static int
openct_reader_internal_transmit(sc_reader_t *reader,
		sc_slot_info_t *slot,
		const u8 *sendbuf, size_t sendsize,
		u8 *recvbuf, size_t *recvsize, unsigned long control)
{
	struct driver_data *data = (struct driver_data *) reader->drv_data;
	int rc;

	/* Hotplug check */
	if ((rc = openct_reader_reconnect(reader, slot)) < 0)
		return rc;

	rc = ct_card_transact(data->h, slot->id,
			sendbuf, sendsize,
			recvbuf, *recvsize);

	if (rc == IFD_ERROR_NOT_CONNECTED) {
		ct_reader_disconnect(data->h);
		data->h = NULL;
		return SC_ERROR_READER_DETACHED;
	}

	if (rc >= 0)
		*recvsize = rc;

	return openct_error(reader, rc);
}
static int
openct_reader_connect(sc_reader_t *reader,
			sc_slot_info_t *slot)
{
	struct driver_data *data = (struct driver_data *) reader->drv_data;
	int rc;

	SC_FUNC_CALLED(reader->ctx, 1);

	if (data->h)
		ct_reader_disconnect(data->h);

	if (!(data->h = ct_reader_connect(data->num))) {
		sc_error(reader->ctx, "ct_reader_connect socket failed\n");
		return SC_ERROR_CARD_NOT_PRESENT;
	}

	rc = ct_card_request(data->h, slot->id, 0, NULL,
				slot->atr, sizeof(slot->atr));
	if (rc < 0) {
		sc_error(reader->ctx,
				"openct_reader_connect read failed: %s\n",
				ct_strerror(rc));
		return SC_ERROR_CARD_NOT_PRESENT;
	}

	if (rc == 0) {
		sc_error(reader->ctx, "openct_reader_connect recved no data\n");
		return SC_ERROR_READER;
	}

	slot->atr_len = rc;
	return SC_NO_ERROR;
}
示例#3
0
static int openct_reader_lock(sc_reader_t *reader)
{
	struct driver_data *data = (struct driver_data *) reader->drv_data;
	int rc;

	SC_FUNC_CALLED(reader->ctx, SC_LOG_DEBUG_VERBOSE);

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

	/* Hotplug check */
	if ((rc = openct_reader_reconnect(reader)) < 0)
		return rc;

	rc = ct_card_lock(data->h, data->slot,
				IFD_LOCK_EXCLUSIVE,
				&data->excl_lock);

	if (rc == IFD_ERROR_NOT_CONNECTED) {
		ct_reader_disconnect(data->h);
		data->h = NULL;

		/* Try to reconnect as reader may be plugged-in again */
		return openct_reader_reconnect(reader);
	}

	return openct_error(reader, rc);
}
示例#4
0
文件: client.c 项目: OpenSC/openct
/*
 * Connect to a reader manager
 */
ct_handle *ct_reader_connect(unsigned int reader)
{
	const ct_info_t *info;
	char path[PATH_MAX];
	char file[PATH_MAX];
	ct_handle *h;
	int rc, len;

	len = PATH_MAX;

	snprintf(file, PATH_MAX, "%d", reader);
	if (!ct_format_path(path, PATH_MAX, file)) {
		return NULL;
	}

	if ((rc = ct_status(&info)) < 0 || reader > (unsigned int)rc)
		return NULL;

	if (!(h = (ct_handle *) calloc(1, sizeof(*h))))
		return NULL;

	if (!(h->sock = ct_socket_new(CT_SOCKET_BUFSIZ))) {
		free(h);
		return NULL;
	}
	if (ct_socket_connect(h->sock, path) < 0) {
		ct_reader_disconnect(h);
		return NULL;
	}

	h->info = info + reader;
	return h;
}
static int openct_reader_disconnect(sc_reader_t *reader, sc_slot_info_t *slot)
{
	struct driver_data *data = (struct driver_data *) reader->drv_data;

	SC_FUNC_CALLED(reader->ctx, 1);
	if (data->h)
		ct_reader_disconnect(data->h);
	data->h = NULL;
	return SC_NO_ERROR;
}
示例#6
0
static int openct_reader_disconnect(sc_reader_t *reader)
{
	struct driver_data *data = (struct driver_data *) reader->drv_data;

	SC_FUNC_CALLED(reader->ctx, SC_LOG_DEBUG_VERBOSE);
	if (data->h && !(reader->ctx->flags & SC_CTX_FLAG_TERMINATE))
		ct_reader_disconnect(data->h);
	data->h = NULL;
	return SC_SUCCESS;
}
示例#7
0
/*
 * Called when releasing a reader.  release() has to
 * deallocate the private data.  Other fields will be
 * freed by OpenSC.
 */
static int openct_reader_release(sc_reader_t *reader)
{
	struct driver_data *data = (struct driver_data *) reader->drv_data;

	SC_FUNC_CALLED(reader->ctx, SC_LOG_DEBUG_VERBOSE);
	if (data) {
		if (data->h && !(reader->ctx->flags & SC_CTX_FLAG_TERMINATE))
			ct_reader_disconnect(data->h);
		sc_mem_clear(data, sizeof(*data));
		reader->drv_data = NULL;
		free(data);
	}

	return SC_SUCCESS;
}
/*
 * Called when releasing a reader.  release() has to
 * deallocate the private data.  Other fields will be
 * freed by OpenSC.
 */
static int openct_reader_release(sc_reader_t *reader)
{
	struct driver_data *data = (struct driver_data *) reader->drv_data;
	int i;

	SC_FUNC_CALLED(reader->ctx, 1);
	if (data) {
		if (data->h)
			ct_reader_disconnect(data->h);
		sc_mem_clear(data, sizeof(*data));
		reader->drv_data = NULL;
		free(data);
	}

	for (i = 0; i < SC_MAX_SLOTS; i++) {
		if(reader->slot[i].drv_data)
			free(reader->slot[i].drv_data);
	}
	
	return SC_NO_ERROR;
}
static int openct_reader_lock(sc_reader_t *reader, sc_slot_info_t *slot)
{
	struct driver_data *data = (struct driver_data *) reader->drv_data;
	struct slot_data *slot_data = (struct slot_data *) slot->drv_data;
	int rc;

	SC_FUNC_CALLED(reader->ctx, 1);

	/* Hotplug check */
	if ((rc = openct_reader_reconnect(reader, slot)) < 0)
		return rc;

	rc = ct_card_lock(data->h, slot->id,
				IFD_LOCK_EXCLUSIVE,
				&slot_data->excl_lock);

	if (rc == IFD_ERROR_NOT_CONNECTED) {
		ct_reader_disconnect(data->h);
		data->h = NULL;
		return SC_ERROR_READER_DETACHED;
	}

	return openct_error(reader, rc);
}
示例#10
0
static int
openct_reader_connect(sc_reader_t *reader)
{
	struct driver_data *data = (struct driver_data *) reader->drv_data;
	int rc;

	SC_FUNC_CALLED(reader->ctx, SC_LOG_DEBUG_VERBOSE);

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

	if (data->h)
		ct_reader_disconnect(data->h);

	if (!(data->h = ct_reader_connect(data->num))) {
		sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "ct_reader_connect socket failed\n");
		return SC_ERROR_CARD_NOT_PRESENT;
	}

	rc = ct_card_request(data->h, data->slot, 0, NULL,
				reader->atr.value, sizeof(reader->atr.value));
	if (rc < 0) {
		sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL,
				"openct_reader_connect read failed: %s\n",
				ct_strerror(rc));
		return SC_ERROR_CARD_NOT_PRESENT;
	}

	if (rc == 0) {
		sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "openct_reader_connect recved no data\n");
		return SC_ERROR_READER;
	}

	reader->atr.len = rc;
	return SC_SUCCESS;
}
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;
}