Check-in [4d4946cc1f]
Overview
Comment:First work towards implementing C_WaitForSlotEvent
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wait-for-slot-event
Files: files | file ages | folders
SHA1:4d4946cc1f43c645d209764a87a574822191b3c8
User & Date: rkeene on 2013-08-18 06:53:18
Other Links: manifest | tags
Context
2013-08-18
07:02
Added support for CKF_DONT_BLOCK check-in: 0058a3b41b user: rkeene tags: wait-for-slot-event
06:53
First work towards implementing C_WaitForSlotEvent check-in: 4d4946cc1f user: rkeene tags: wait-for-slot-event
2013-08-14
04:54
Added support for enabling the PROTECTED_AUTHENTICATION_PATH flag for the token if a command to provide the PIN is configured check-in: 8a76f09a85 user: rkeene tags: piv
Changes

Modified cackey.c from [ce38432e82] to [0817c7d1f8].

   782    782   	CK_MECHANISM_TYPE decrypt_mechanism;
   783    783   	CK_VOID_PTR decrypt_mech_parm;
   784    784   	CK_ULONG decrypt_mech_parmlen;
   785    785   	struct cackey_identity *decrypt_identity;
   786    786   };
   787    787   
   788    788   struct cackey_slot {
          789  +	unsigned int id;
          790  +
   789    791   	int active;
   790    792   	int internal;
   791    793   
   792    794   	char *pcsc_reader;
   793    795   
   794    796   	int pcsc_card_connected;
   795    797   	SCARDHANDLE pcsc_card;
          798  +	DWORD pcsc_state;
   796    799   
   797    800   	int transaction_depth;
   798    801   	int transaction_need_hw_lock;
   799    802   
   800    803   	int slot_reset;
   801    804   
   802    805   	CK_FLAGS token_flags;
................................................................................
  1115   1118   	if (slot->pcsc_card_connected) {
  1116   1119   		SCardDisconnect(slot->pcsc_card, SCARD_LEAVE_CARD);
  1117   1120   	}
  1118   1121   
  1119   1122   	slot->slot_reset = 1;
  1120   1123   	slot->pcsc_card_connected = 0;
  1121   1124   	slot->token_flags = CKF_LOGIN_REQUIRED;
         1125  +	slot->pcsc_state = SCARD_STATE_UNAWARE;
  1122   1126   
  1123   1127   	CACKEY_DEBUG_PRINTF("Returning.");
  1124   1128   
  1125   1129   	return;
  1126   1130   }
  1127   1131   
  1128   1132   /*
................................................................................
  4109   4113   	}
  4110   4114   
  4111   4115   	for (idx = 0; idx < (sizeof(cackey_sessions) / sizeof(cackey_sessions[0])); idx++) {
  4112   4116   		cackey_sessions[idx].active = 0;
  4113   4117   	}
  4114   4118   
  4115   4119   	for (idx = 0; idx < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); idx++) {
         4120  +		cackey_slots[idx].id = idx;
  4116   4121   		cackey_slots[idx].active = 0;
  4117   4122   		cackey_slots[idx].pcsc_reader = NULL;
         4123  +		cackey_slots[idx].pcsc_state = SCARD_STATE_UNAWARE;
  4118   4124   		cackey_slots[idx].transaction_depth = 0;
  4119   4125   		cackey_slots[idx].transaction_need_hw_lock = 0;
  4120   4126   		cackey_slots[idx].slot_reset = 0;
  4121   4127   		cackey_slots[idx].token_flags = 0;
  4122   4128   		cackey_slots[idx].label = NULL;
  4123   4129   		cackey_slots[idx].internal = 0;
  4124   4130   	}
................................................................................
  4720   4726   
  4721   4727   	CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);
  4722   4728   
  4723   4729   	return(CKR_OK);
  4724   4730   }
  4725   4731   
  4726   4732   CK_DEFINE_FUNCTION(CK_RV, C_WaitForSlotEvent)(CK_FLAGS flags, CK_SLOT_ID_PTR pSlotID, CK_VOID_PTR pReserved) {
         4733  +	SCARD_READERSTATE reader_states[(sizeof(cackey_slots) / sizeof(cackey_slots[0])) + 1];
         4734  +	SCARDCONTEXT pcsc_handle;
         4735  +	LONG scard_getstatchng_ret;
         4736  +	LONG scard_est_context_ret;
         4737  +	struct cackey_slot *cackey_slot;
         4738  +	unsigned int currslot, reader_state_slot;
         4739  +	int pcsc_connect_ret;
         4740  +
  4727   4741   	CACKEY_DEBUG_PRINTF("Called.");
  4728   4742   
  4729   4743   	if (pReserved != NULL) {
  4730   4744   		CACKEY_DEBUG_PRINTF("Error. pReserved is not NULL.");
  4731   4745   
  4732   4746   		return(CKR_ARGUMENTS_BAD);
  4733   4747   	}
  4734   4748   
  4735         -	if (!cackey_initialized) {
  4736         -		CACKEY_DEBUG_PRINTF("Error.  Not initialized.");
  4737         -
  4738         -		return(CKR_CRYPTOKI_NOT_INITIALIZED);
  4739         -	}
  4740         -
  4741         -	/* XXX: TODO: Implement this... */
         4749  +	if (pSlotID == NULL) {
         4750  +		CACKEY_DEBUG_PRINTF("Error. pSlotID is NULL.");
         4751  +
         4752  +		return(CKR_ARGUMENTS_BAD);
         4753  +	}
         4754  +
         4755  +	if (!cackey_initialized) {
         4756  +		CACKEY_DEBUG_PRINTF("Error.  Not initialized.");
         4757  +
         4758  +		return(CKR_CRYPTOKI_NOT_INITIALIZED);
         4759  +	}
         4760  +
         4761  +	pcsc_connect_ret = cackey_pcsc_connect();
         4762  +	if (pcsc_connect_ret != CACKEY_PCSC_S_OK) {
         4763  +		CACKEY_DEBUG_PRINTF("Connection to PC/SC failed, returning in failure");
         4764  +
         4765  +		return(CKR_GENERAL_ERROR);
         4766  +	}
         4767  +
         4768  +	if ((flags & CKF_DONT_BLOCK) == CKF_DONT_BLOCK) {
         4769  +		/* XXX TODO */
         4770  +		CACKEY_DEBUG_PRINTF("Returning CKR_GENERAL_ERROR (%i) because we were asked to not block", CKR_GENERAL_ERROR);
         4771  +
         4772  +		return(CKR_GENERAL_ERROR);
         4773  +	} else {
         4774  +		for (reader_state_slot = currslot = 0; currslot < (sizeof(cackey_slots) / sizeof(cackey_slots[0])); currslot++) {
         4775  +			if (cackey_slots[currslot].internal) {
         4776  +				continue;
         4777  +			}
         4778  +
         4779  +			if (cackey_slots[currslot].active == 0) {
         4780  +				continue;
         4781  +			}
         4782  +
         4783  +			reader_states[reader_state_slot].szReader = cackey_slots[currslot].pcsc_reader;
         4784  +			reader_states[reader_state_slot].pvUserData = &cackey_slots[currslot];
         4785  +
         4786  +			reader_states[reader_state_slot].dwCurrentState = cackey_slots[currslot].pcsc_state;
         4787  +
         4788  +			reader_state_slot++;
         4789  +		}
         4790  +
         4791  +		reader_states[reader_state_slot].szReader = "\\\\?PnP?\\Notification";
         4792  +		reader_states[reader_state_slot].pvUserData = NULL;
         4793  +		reader_states[reader_state_slot].dwCurrentState = SCARD_STATE_UNAWARE;
         4794  +		reader_state_slot++;
         4795  +
         4796  +		scard_est_context_ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &pcsc_handle);
         4797  +		if (scard_est_context_ret != SCARD_S_SUCCESS) {
         4798  +			CACKEY_DEBUG_PRINTF("Returning CKR_GENERAL_ERROR (%i) because SCardEstablishContext failed: %lx", CKR_GENERAL_ERROR, scard_est_context_ret);
         4799  +
         4800  +			return(CKR_GENERAL_ERROR);
         4801  +		}
         4802  +
         4803  +		scard_getstatchng_ret = SCardGetStatusChange(pcsc_handle, INFINITE, reader_states, reader_state_slot);
         4804  +
         4805  +		SCardReleaseContext(pcsc_handle);
         4806  +
         4807  +		if (scard_getstatchng_ret != SCARD_S_SUCCESS) {
         4808  +			CACKEY_DEBUG_PRINTF("Returning CKR_GENERAL_ERROR (%i) because SCardGetStatusChange failed: %lx", CKR_GENERAL_ERROR, scard_getstatchng_ret);
         4809  +
         4810  +			return(CKR_GENERAL_ERROR);
         4811  +		}
         4812  +
         4813  +		for (currslot = 0; currslot < reader_state_slot; currslot++) {
         4814  +			CACKEY_DEBUG_PRINTF("[slot = %u] CurrentState = %lx, EventState = %lx",
         4815  +			    currslot,
         4816  +			    reader_states[currslot].dwCurrentState & 0xffff,
         4817  +			    reader_states[currslot].dwEventState & 0xffff
         4818  +			);
         4819  +
         4820  +			if (reader_states[currslot].dwCurrentState != reader_states[currslot].dwEventState) {
         4821  +				cackey_slot = (struct cackey_slot *) reader_states[currslot].pvUserData;
         4822  +
         4823  +				if (cackey_slot == NULL) {
         4824  +					/* XXX: TODO: Someone plugged in a new slot */
         4825  +					continue;
         4826  +				}
         4827  +
         4828  +				CACKEY_DEBUG_PRINTF("Returning slot changed: %u", (unsigned int) cackey_slot->id);
         4829  +
         4830  +				cackey_slot->pcsc_state = reader_states[currslot].dwEventState;
         4831  +				*pSlotID = (CK_SLOT_ID) cackey_slot->id;
         4832  +
         4833  +				CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);
         4834  +
         4835  +				return(CKR_OK);
         4836  +			}
         4837  +		}
         4838  +	}
         4839  +
  4742   4840   	CACKEY_DEBUG_PRINTF("Returning CKR_FUNCTION_NOT_SUPPORTED (%i)", CKR_FUNCTION_NOT_SUPPORTED);
  4743   4841   
  4744   4842   	return(CKR_FUNCTION_NOT_SUPPORTED);
  4745   4843   }
  4746   4844   
  4747   4845   CK_DEFINE_FUNCTION(CK_RV, C_GetMechanismList)(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount) {
  4748   4846   	CACKEY_DEBUG_PRINTF("Called.");

Modified test.c from [47338c5b52] to [1ccfa3a69d].

   225    225   
   226    226   	slots = malloc(sizeof(*slots) * numSlots);
   227    227   
   228    228   	chk_rv = C_GetSlotList(FALSE, slots, &numSlots);
   229    229   	if (chk_rv != CKR_OK) {
   230    230   		return(1);
   231    231   	}
          232  +
          233  +	currSlot = 0;
          234  +	printf("Please insert a card now.\n");
          235  +	chk_rv = C_WaitForSlotEvent(0, &currSlot, NULL);
          236  +	if (chk_rv != CKR_OK) {
          237  +		printf("Failed to wait for slot event.\n");
          238  +	}
   232    239   
   233    240   	for (currSlot = 0; currSlot < numSlots; currSlot++) {
   234    241   		printf("  Slot %lu:\n", currSlot);
   235    242   
   236    243   		chk_rv = C_GetSlotInfo(slots[currSlot], &slotInfo);
   237    244   		if (chk_rv != CKR_OK) {
   238    245   			return(1);