Beispiel #1
0
CK_RV
card_detect_all(void)
{
	unsigned int i;

	sc_log(context, "Detect all cards");
	/* Detect cards in all initialized readers */
	for (i=0; i< sc_ctx_get_reader_count(context); i++) {
		sc_reader_t *reader = sc_ctx_get_reader(context, i);
		if (reader->flags & SC_READER_REMOVED) {
			struct sc_pkcs11_slot *slot;
			card_removed(reader);
			while ((slot = reader_get_slot(reader))) {
				empty_slot(slot);
			}
			_sc_delete_reader(context, reader);
			i--;
		} else {
			if (!reader_get_slot(reader))
				initialize_reader(reader);
			else
				card_detect(sc_ctx_get_reader(context, i));
		}
	}
	sc_log(context, "All cards detected");
	return CKR_OK;
}
Beispiel #2
0
CK_RV C_Finalize(CK_VOID_PTR pReserved)
{
	int i;
	void *p;
	sc_pkcs11_slot_t *slot;
	CK_RV rv;

	if (pReserved != NULL_PTR)
		return CKR_ARGUMENTS_BAD;

#if !defined(_WIN32)
	sc_notify_close();
#endif

	if (context == NULL)
		return CKR_CRYPTOKI_NOT_INITIALIZED;

	rv = sc_pkcs11_lock();
	if (rv != CKR_OK)
		return rv;

	sc_log(context, "C_Finalize()");

	/* cancel pending calls */
	in_finalize = 1;
	sc_cancel(context);
	/* remove all cards from readers */
	for (i=0; i < (int)sc_ctx_get_reader_count(context); i++)
		card_removed(sc_ctx_get_reader(context, i));

	while ((p = list_fetch(&sessions)))
		free(p);
	list_destroy(&sessions);

	while ((slot = list_fetch(&virtual_slots))) {
		list_destroy(&slot->objects);
		list_destroy(&slot->logins);
		free(slot);
	}
	list_destroy(&virtual_slots);

	sc_release_context(context);
	context = NULL;

	/* Release and destroy the mutex */
	sc_pkcs11_free_lock();

	return rv;
}
Beispiel #3
0
CK_RV card_detect(sc_reader_t *reader)
{
	struct sc_pkcs11_card *p11card = NULL;
	int free_p11card = 0;
	int rc;
	CK_RV rv;
	unsigned int i;
	int j;

	sc_log(context, "%s: Detecting smart card", reader->name);
	/* Check if someone inserted a card */
again:
	rc = sc_detect_card_presence(reader);
	if (rc < 0) {
		sc_log(context, "%s: failed, %s", reader->name, sc_strerror(rc));
		return sc_to_cryptoki_error(rc, NULL);
	}
	if (rc == 0) {
		sc_log(context, "%s: card absent", reader->name);
		card_removed(reader);	/* Release all resources */
		return CKR_TOKEN_NOT_PRESENT;
	}

	/* If the card was changed, disconnect the current one */
	if (rc & SC_READER_CARD_CHANGED) {
		sc_log(context, "%s: Card changed", reader->name);
		/* The following should never happen - but if it
		 * does we'll be stuck in an endless loop.
		 * So better be fussy.
		if (!retry--)
			return CKR_TOKEN_NOT_PRESENT; */
		card_removed(reader);
		goto again;
	}

	/* Locate a slot related to the reader */
	for (i=0; i<list_size(&virtual_slots); i++) {
		sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i);
		if (slot->reader == reader) {
			p11card = slot->p11card;
			break;
		}
	}

	/* Detect the card if it's not known already */
	if (p11card == NULL) {
		sc_log(context, "%s: First seen the card ", reader->name);
		p11card = (struct sc_pkcs11_card *)calloc(1, sizeof(struct sc_pkcs11_card));
		if (!p11card)
			return CKR_HOST_MEMORY;
		free_p11card = 1;
		p11card->reader = reader;
	}

	if (p11card->card == NULL) {
		sc_log(context, "%s: Connecting ... ", reader->name);
		rc = sc_connect_card(reader, &p11card->card);
		if (rc != SC_SUCCESS) {
			sc_log(context, "%s: SC connect card error %i", reader->name, rc);
			rv = sc_to_cryptoki_error(rc, NULL);
			goto fail;
		}

		/* escape commands are only guaranteed to be working with a card
		 * inserted. That's why by now, after sc_connect_card() the reader's
		 * metadata may have changed. We re-initialize the metadata for every
		 * slot of this reader here. */
		if (reader->flags & SC_READER_ENABLE_ESCAPE) {
			for (i = 0; i<list_size(&virtual_slots); i++) {
				sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i);
				if (slot->reader == reader)
					init_slot_info(&slot->slot_info, reader);
			}
		}

		sc_log(context, "%s: Connected SC card %p", reader->name, p11card->card);
	}

	/* Detect the framework */
	if (p11card->framework == NULL) {
		struct sc_app_info *app_generic = sc_pkcs15_get_application_by_type(p11card->card, "generic");

		sc_log(context, "%s: Detecting Framework. %i on-card applications", reader->name, p11card->card->app_count);
		sc_log(context, "%s: generic application %s", reader->name, app_generic ? app_generic->label : "<none>");

		for (i = 0; frameworks[i]; i++)
			if (frameworks[i]->bind != NULL)
				break;
		/*TODO: only first framework is used: pkcs15init framework is not reachable here */
		if (frameworks[i] == NULL) {
			rv = CKR_GENERAL_ERROR;
			goto fail;
		}

		p11card->framework = frameworks[i];

		/* Initialize framework */
		sc_log(context, "%s: Detected framework %d. Creating tokens.", reader->name, i);
		/* Bind 'generic' application or (emulated?) card without applications */
		if (app_generic || !p11card->card->app_count)   {
			scconf_block *conf_block = NULL;
			int enable_InitToken = 0;

			conf_block = sc_match_atr_block(p11card->card->ctx, NULL,
				&p11card->reader->atr);
			if (!conf_block) /* check default block */
				conf_block = sc_get_conf_block(context,
					"framework", "pkcs15", 1);

			enable_InitToken = scconf_get_bool(conf_block,
				"pkcs11_enable_InitToken", 0);

			sc_log(context, "%s: Try to bind 'generic' token.", reader->name);
			rv = frameworks[i]->bind(p11card, app_generic);
			if (rv == CKR_TOKEN_NOT_RECOGNIZED && enable_InitToken)   {
				sc_log(context, "%s: 'InitToken' enabled -- accept non-binded card", reader->name);
				rv = CKR_OK;
			}
			if (rv != CKR_OK)   {
				sc_log(context,
				       "%s: cannot bind 'generic' token: rv 0x%lX",
				       reader->name, rv);
				goto fail;
			}

			sc_log(context, "%s: Creating 'generic' token.", reader->name);
			rv = frameworks[i]->create_tokens(p11card, app_generic);
			if (rv != CKR_OK)   {
				sc_log(context,
				       "%s: create 'generic' token error 0x%lX",
				       reader->name, rv);
				goto fail;
			}
		}

		/* Now bind the rest of applications that are not 'generic' */
		for (j = 0; j < p11card->card->app_count; j++)   {
			struct sc_app_info *app_info = p11card->card->app[j];
			char *app_name = app_info ? app_info->label : "<anonymous>";

			if (app_generic && app_generic == p11card->card->app[j])
				continue;

			sc_log(context, "%s: Binding %s token.", reader->name, app_name);
			rv = frameworks[i]->bind(p11card, app_info);
			if (rv != CKR_OK)   {
				sc_log(context, "%s: bind %s token error Ox%lX",
				       reader->name, app_name, rv);
				continue;
			}

			sc_log(context, "%s: Creating %s token.", reader->name, app_name);
			rv = frameworks[i]->create_tokens(p11card, app_info);
			if (rv != CKR_OK)   {
				sc_log(context,
				       "%s: create %s token error 0x%lX",
				       reader->name, app_name, rv);
				goto fail;
			}
		}
	}

	sc_log(context, "%s: Detection ended", reader->name);
	return CKR_OK;

fail:
	if (free_p11card) {
		if (p11card->framework)
			p11card->framework->unbind(p11card);
		if (p11card->card != NULL)
			sc_disconnect_card(p11card->card);
		free(p11card);
	}

	return rv;
}
Beispiel #4
0
CK_RV card_detect(sc_reader_t *reader)
{
	struct sc_pkcs11_card *p11card = NULL;
	int rc, rv;
	unsigned int i;

	rv = CKR_OK;

	sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: Detecting smart card\n", reader->name);
      /* Check if someone inserted a card */
      again:rc = sc_detect_card_presence(reader);
	if (rc < 0) {
		sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: failed, %s\n", reader->name, sc_strerror(rc));
		return sc_to_cryptoki_error(rc, NULL);
	}
	if (rc == 0) {
		sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: card absent\n", reader->name);
		card_removed(reader);	/* Release all resources */
		return CKR_TOKEN_NOT_PRESENT;
	}

	/* If the card was changed, disconnect the current one */
	if (rc & SC_READER_CARD_CHANGED) {
		sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: Card changed\n", reader->name);
		/* The following should never happen - but if it
		 * does we'll be stuck in an endless loop.
		 * So better be fussy. 
		if (!retry--)
			return CKR_TOKEN_NOT_PRESENT; */
		card_removed(reader);
		goto again;
	}

	/* Locate a slot related to the reader */
	for (i=0; i<list_size(&virtual_slots); i++) {
		sc_pkcs11_slot_t *slot = (sc_pkcs11_slot_t *) list_get_at(&virtual_slots, i);
		if (slot->reader == reader) {
			p11card = slot->card;
			break;
		}
	}

	/* Detect the card if it's not known already */
	if (p11card == NULL) {
		sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: First seen the card ", reader->name);
		p11card = (struct sc_pkcs11_card *)calloc(1, sizeof(struct sc_pkcs11_card));
		if (!p11card)
			return CKR_HOST_MEMORY;
		p11card->reader = reader;
	}

	if (p11card->card == NULL) {
		sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: Connecting ... ", reader->name);
		rc = sc_connect_card(reader, &p11card->card);
		if (rc != SC_SUCCESS)
			return sc_to_cryptoki_error(rc, NULL);
	}

	/* Detect the framework */
	if (p11card->framework == NULL) {
		sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: Detecting Framework\n", reader->name);

		for (i = 0; frameworks[i]; i++) {
			if (frameworks[i]->bind == NULL)
				continue;
			rv = frameworks[i]->bind(p11card);
			if (rv == CKR_OK)
				break;
		}

		if (frameworks[i] == NULL)
			return CKR_TOKEN_NOT_RECOGNIZED;

		/* Initialize framework */
		sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: Detected framework %d. Creating tokens.\n", reader->name, i);
		rv = frameworks[i]->create_tokens(p11card);
		if (rv != CKR_OK)
			return rv;

		p11card->framework = frameworks[i];
	}
	sc_debug(context, SC_LOG_DEBUG_NORMAL, "%s: Detection ended\n", reader->name);
	return CKR_OK;
}