Check-in [2d8b4030f7]
Overview
Comment:Updated PC/SC error messages to include text return value as well as numeric value

Minor reorganization

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:2d8b4030f7aec2af6494d01cb9765ccadd671e8b
User & Date: rkeene on 2010-05-12 17:25:06
Other Links: manifest | tags
Context
2010-05-12
19:35
Updated ignores

Updated read_tlv to return a list

Added a free_tlv function

Updated value->str conversion functions to be more flexible/direct

Added sample code to select all PKI applets/files

Simplified TLV entity check-in: 330efa4f3b user: rkeene tags: trunk

17:25
Updated PC/SC error messages to include text return value as well as numeric value

Minor reorganization check-in: 2d8b4030f7 user: rkeene tags: trunk

14:52
Added test driver (from libssh-agent-pkcs11-provider)

Added basic ASN.1 X.509 BER decoder (from libssh-agent-pkcs11-provider)

Work towards updating CACKey to talk to CAC using PC/SC check-in: a3d727289c user: rkeene tags: trunk

Changes

Modified cackey.c from [c365c15fc9] to [d5b94d106d].

   336    336   
   337    337   	if (retval == NULL) {
   338    338   		retval = "UNKNOWN";
   339    339   	}
   340    340   
   341    341   	return(retval);
   342    342   }
          343  +
          344  +static const char *CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(LONG retcode) {
          345  +	const char *retval = NULL;
          346  +
          347  +	switch (retcode) {
          348  +		case SCARD_S_SUCCESS:
          349  +			retval = "SCARD_S_SUCCESS";
          350  +			break;
          351  +		case SCARD_E_CANCELLED:
          352  +			retval = "SCARD_E_CANCELLED";
          353  +			break;
          354  +		case SCARD_E_CANT_DISPOSE:
          355  +			retval = "SCARD_E_CANT_DISPOSE";
          356  +			break;
          357  +		case SCARD_E_INSUFFICIENT_BUFFER:
          358  +			retval = "SCARD_E_INSUFFICIENT_BUFFER";
          359  +			break;
          360  +		case SCARD_E_INVALID_ATR:
          361  +			retval = "SCARD_E_INVALID_ATR";
          362  +			break;
          363  +		case SCARD_E_INVALID_HANDLE:
          364  +			retval = "SCARD_E_INVALID_HANDLE";
          365  +			break;
          366  +		case SCARD_E_INVALID_PARAMETER:
          367  +			retval = "SCARD_E_INVALID_PARAMETER";
          368  +			break;
          369  +		case SCARD_E_INVALID_TARGET:
          370  +			retval = "SCARD_E_INVALID_TARGET";
          371  +			break;
          372  +		case SCARD_E_INVALID_VALUE:
          373  +			retval = "SCARD_E_INVALID_VALUE";
          374  +			break;
          375  +		case SCARD_E_NO_MEMORY:
          376  +			retval = "SCARD_E_NO_MEMORY";
          377  +			break;
          378  +		case SCARD_E_UNKNOWN_READER:
          379  +			retval = "SCARD_E_UNKNOWN_READER";
          380  +			break;
          381  +		case SCARD_E_TIMEOUT:
          382  +			retval = "SCARD_E_TIMEOUT";
          383  +			break;
          384  +		case SCARD_E_SHARING_VIOLATION:
          385  +			retval = "SCARD_E_SHARING_VIOLATION";
          386  +			break;
          387  +		case SCARD_E_NO_SMARTCARD:
          388  +			retval = "SCARD_E_NO_SMARTCARD";
          389  +			break;
          390  +		case SCARD_E_UNKNOWN_CARD:
          391  +			retval = "SCARD_E_UNKNOWN_CARD";
          392  +			break;
          393  +		case SCARD_E_PROTO_MISMATCH:
          394  +			retval = "SCARD_E_PROTO_MISMATCH";
          395  +			break;
          396  +		case SCARD_E_NOT_READY:
          397  +			retval = "SCARD_E_NOT_READY";
          398  +			break;
          399  +		case SCARD_E_SYSTEM_CANCELLED:
          400  +			retval = "SCARD_E_SYSTEM_CANCELLED";
          401  +			break;
          402  +		case SCARD_E_NOT_TRANSACTED:
          403  +			retval = "SCARD_E_NOT_TRANSACTED";
          404  +			break;
          405  +		case SCARD_E_READER_UNAVAILABLE:
          406  +			retval = "SCARD_E_READER_UNAVAILABLE";
          407  +			break;
          408  +		case SCARD_W_UNSUPPORTED_CARD:
          409  +			retval = "SCARD_W_UNSUPPORTED_CARD";
          410  +			break;
          411  +		case SCARD_W_UNRESPONSIVE_CARD:
          412  +			retval = "SCARD_W_UNRESPONSIVE_CARD";
          413  +			break;
          414  +		case SCARD_W_UNPOWERED_CARD:
          415  +			retval = "SCARD_W_UNPOWERED_CARD";
          416  +			break;
          417  +		case SCARD_W_RESET_CARD:
          418  +			retval = "SCARD_W_RESET_CARD";
          419  +			break;
          420  +		case SCARD_W_REMOVED_CARD:
          421  +			retval = "SCARD_W_REMOVED_CARD";
          422  +			break;
          423  +		case SCARD_E_PCI_TOO_SMALL:
          424  +			retval = "SCARD_E_PCI_TOO_SMALL";
          425  +			break;
          426  +		case SCARD_E_READER_UNSUPPORTED:
          427  +			retval = "SCARD_E_READER_UNSUPPORTED";
          428  +			break;
          429  +		case SCARD_E_DUPLICATE_READER:
          430  +			retval = "SCARD_E_DUPLICATE_READER";
          431  +			break;
          432  +		case SCARD_E_CARD_UNSUPPORTED:
          433  +			retval = "SCARD_E_CARD_UNSUPPORTED";
          434  +			break;
          435  +		case SCARD_E_NO_SERVICE:
          436  +			retval = "SCARD_E_NO_SERVICE";
          437  +			break;
          438  +		case SCARD_E_SERVICE_STOPPED:
          439  +			retval = "SCARD_E_SERVICE_STOPPED";
          440  +			break;
          441  +		case SCARD_W_INSERTED_CARD:
          442  +			retval = "SCARD_W_INSERTED_CARD";
          443  +			break;
          444  +		case SCARD_E_UNSUPPORTED_FEATURE:
          445  +			retval = "SCARD_E_UNSUPPORTED_FEATURE";
          446  +			break;
          447  +	}
          448  +
          449  +	if (retval == NULL) {
          450  +		retval = "UNKNOWN";
          451  +	}
          452  +
          453  +	return(retval);
          454  +}
   343    455   
   344    456   #  define malloc(x) CACKEY_DEBUG_FUNC_MALLOC(x, __func__)
   345    457   #  define realloc(x, y) CACKEY_DEBUG_FUNC_REALLOC(x, y, __func__)
   346    458   #else
   347    459   #  define CACKEY_DEBUG_PRINTF(x...) /**/
   348    460   #  define CACKEY_DEBUG_PRINTBUF(f, x, y) /**/
   349    461   #  define CACKEY_DEBUG_PERROR(x) /**/
   350    462   #  define CACKEY_DEBUG_FUNC_TAG_TO_STR(x) "DEBUG_DISABLED"
          463  +#  define CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(x) "DEBUG_DISABLED"
   351    464   #endif
   352    465   
   353    466   struct cackey_identity {
   354    467   	CK_ATTRIBUTE *attributes;
   355    468   	CK_ULONG attributes_count;
   356    469   };
   357    470   
................................................................................
   391    504   	int active;
   392    505   
   393    506   	char *pcsc_reader;
   394    507   
   395    508   	int pcsc_card_connected;
   396    509   	SCARDHANDLE pcsc_card;
   397    510   };
          511  +
          512  +struct cackey_tlv_cardurl {
          513  +};
   398    514   
   399    515   struct cackey_tlv_entity {
   400    516   	uint8_t tag;
   401    517   	size_t length;
   402    518   	unsigned char *value_buf; /* Raw buffer */
          519  +	void *value;
   403    520   };
   404    521   
   405    522   /* CACKEY Global Handles */
   406    523   static void *cackey_biglock = NULL;
   407    524   static struct cackey_session cackey_sessions[128];
   408    525   static struct cackey_slot cackey_slots[128];
   409    526   static int cackey_initialized = 0;
................................................................................
   486    603   
   487    604   			return(-1);
   488    605   		}
   489    606   
   490    607   		CACKEY_DEBUG_PRINTF("SCardEstablishContext() called");
   491    608   		scard_est_context_ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, cackey_pcsc_handle);
   492    609   		if (scard_est_context_ret != SCARD_S_SUCCESS) {
   493         -			CACKEY_DEBUG_PRINTF("Call to SCardEstablishContext failed (returned %li), returning in failure", (long) scard_est_context_ret);
          610  +			CACKEY_DEBUG_PRINTF("Call to SCardEstablishContext failed (returned %s/%li), returning in failure", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_est_context_ret), (long) scard_est_context_ret);
   494    611   
   495    612   			free(cackey_pcsc_handle);
   496    613   
   497    614   			cackey_slots_disconnect_all();
   498    615   
   499    616   			return(-1);
   500    617   		}
   501    618   	}
   502    619   
   503    620   #ifdef HAVE_SCARDISVALIDCONTEXT
   504    621   	CACKEY_DEBUG_PRINTF("SCardIsValidContext() called");
   505    622   	scard_isvalid_ret = SCardIsValidContext(*cackey_pcsc_handle);
   506    623   	if (scard_isvalid_ret != SCARD_S_SUCCESS) {
   507         -		CACKEY_DEBUG_PRINTF("Handle has become invalid (SCardIsValidContext = %li), trying to re-establish...", (long) scard_isvalid_ret);
          624  +		CACKEY_DEBUG_PRINTF("Handle has become invalid (SCardIsValidContext = %s/%li), trying to re-establish...", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_isvalid_ret), (long) scard_isvalid_ret);
   508    625   
   509    626   		CACKEY_DEBUG_PRINTF("SCardEstablishContext() called");
   510    627   		scard_est_context_ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, cackey_pcsc_handle);
   511    628   		if (scard_est_context_ret != SCARD_S_SUCCESS) {
   512         -			CACKEY_DEBUG_PRINTF("Call to SCardEstablishContext failed (returned %li), returning in failure", (long) scard_est_context_ret);
          629  +			CACKEY_DEBUG_PRINTF("Call to SCardEstablishContext failed (returned %s/%li), returning in failure", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_est_context_ret), (long) scard_est_context_ret);
   513    630   
   514    631   			free(cackey_pcsc_handle);
   515    632   
   516    633   			cackey_slots_disconnect_all();
   517    634   
   518    635   			return(-1);
   519    636   		}
................................................................................
   556    673   
   557    674   	/* Connect to reader, if needed */
   558    675   	if (!slot->pcsc_card_connected) {
   559    676   		CACKEY_DEBUG_PRINTF("SCardConnect(%s) called", slot->pcsc_reader);
   560    677   		scard_conn_ret = SCardConnect(*cackey_pcsc_handle, slot->pcsc_reader, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, &slot->pcsc_card, &protocol);
   561    678   
   562    679   		if (scard_conn_ret != SCARD_S_SUCCESS) {
   563         -			CACKEY_DEBUG_PRINTF("Connection to card failed, returning in failure (SCardConnect() = %li)", (long) scard_conn_ret);
          680  +			CACKEY_DEBUG_PRINTF("Connection to card failed, returning in failure (SCardConnect() = %s/%li)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_conn_ret), (long) scard_conn_ret);
   564    681   
   565    682   			return(-1);
   566    683   		}
   567    684   
   568    685   		slot->pcsc_card_connected = 1;
   569    686   	}
   570    687   
................................................................................
   586    703   	}
   587    704   
   588    705   	CACKEY_DEBUG_PRINTBUF("Sending APDU:", xmit_buf, xmit_len);
   589    706   
   590    707   	recv_len = sizeof(recv_buf);
   591    708   	scard_xmit_ret = SCardTransmit(slot->pcsc_card, SCARD_PCI_T0, xmit_buf, xmit_len, SCARD_PCI_T1, recv_buf, &recv_len);
   592    709   	if (scard_xmit_ret != SCARD_S_SUCCESS) {
   593         -		CACKEY_DEBUG_PRINTF("Failed to send APDU to card (SCardTransmit() = %lx)", (unsigned long) scard_xmit_ret);
          710  +		CACKEY_DEBUG_PRINTF("Failed to send APDU to card (SCardTransmit() = %s/%lx)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_xmit_ret), (unsigned long) scard_xmit_ret);
   594    711   
   595    712   		if (scard_xmit_ret == SCARD_W_RESET_CARD) {
   596    713   			CACKEY_DEBUG_PRINTF("Reset required, please hold...");
   597    714   
   598    715   			scard_reconn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, &protocol);
   599    716   			if (scard_reconn_ret == SCARD_S_SUCCESS) {
   600    717   				CACKEY_DEBUG_PRINTF("Reset successful, retransmitting");
   601    718   				scard_xmit_ret = SCardTransmit(slot->pcsc_card, SCARD_PCI_T0, xmit_buf, xmit_len, SCARD_PCI_T0, recv_buf, &recv_len);
   602    719   
   603    720   				if (scard_xmit_ret != SCARD_S_SUCCESS) {
   604         -					CACKEY_DEBUG_PRINTF("Retransmit failed, returning in failure after disconnecting the card");
          721  +					CACKEY_DEBUG_PRINTF("Retransmit failed, returning in failure after disconnecting the card (SCardTransmit = %s/%li)", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_xmit_ret), (long) scard_xmit_ret);
   605    722   
   606    723   					SCardDisconnect(slot->pcsc_card, SCARD_RESET_CARD);
   607    724   					slot->pcsc_card_connected = 0;
   608    725   
   609    726   					return(-1);
   610    727   				}
   611    728   			} else {
................................................................................
   775    892   		return(-1);
   776    893   	}
   777    894   
   778    895   	CACKEY_DEBUG_PRINTF("Successfully selected file");
   779    896   
   780    897   	return(0);
   781    898   }
          899  +
          900  +static int cackey_select_file(struct cackey_slot *slot, uint16_t ef) {
          901  +	unsigned char fid_buf[2];
          902  +	int send_ret;
          903  +
          904  +	CACKEY_DEBUG_PRINTF("Called");
          905  +
          906  +	/* Open the elementary file */
          907  +	fid_buf[0] = (ef >> 8) & 0xff;
          908  +	fid_buf[1] = ef & 0xff;
          909  +
          910  +	send_ret = cackey_send_apdu(slot, GSCIS_CLASS_ISO7816, GSCIS_INSTR_SELECT, 0x02, 0x0C, sizeof(fid_buf), fid_buf, 0x00, NULL, NULL, NULL);
          911  +	if (send_ret < 0) {
          912  +		CACKEY_DEBUG_PRINTF("Failed to open file, returning in failure");
          913  +
          914  +		return(-1);
          915  +	}
          916  +
          917  +	CACKEY_DEBUG_PRINTF("Successfully selected file");
          918  +
          919  +	return(0);
          920  +}
   782    921   
   783    922   static int cackey_read_tlv(struct cackey_slot *slot, int follow_url) {
   784    923   	struct cackey_tlv_entity curr_entity;
   785    924   	unsigned char tlen_buf[2], tval_buf[1024], *tval;
   786    925   	unsigned char vlen_buf[2], vval_buf[8192], *vval;
   787    926   	ssize_t tlen, vlen;
   788    927   	ssize_t read_ret;
................................................................................
   880   1019   
   881   1020   					cackey_read_tlv(slot, 0);
   882   1021   				}
   883   1022   				break;
   884   1023   		}
   885   1024   	}
   886   1025   
   887         -	return(0);
   888         -}
   889         -
   890         -static int cackey_select_file(struct cackey_slot *slot, uint16_t ef) {
   891         -	unsigned char fid_buf[2];
   892         -	int send_ret;
   893         -
   894         -	CACKEY_DEBUG_PRINTF("Called");
   895         -
   896         -	/* Open the elementary file */
   897         -	fid_buf[0] = (ef >> 8) & 0xff;
   898         -	fid_buf[1] = ef & 0xff;
   899         -
   900         -	send_ret = cackey_send_apdu(slot, GSCIS_CLASS_ISO7816, GSCIS_INSTR_SELECT, 0x02, 0x0C, sizeof(fid_buf), fid_buf, 0x00, NULL, NULL, NULL);
   901         -	if (send_ret < 0) {
   902         -		CACKEY_DEBUG_PRINTF("Failed to open file, returning in failure");
   903         -
   904         -		return(-1);
   905         -	}
   906         -
   907         -	CACKEY_DEBUG_PRINTF("Successfully selected file");
   908         -
   909   1026   	return(0);
   910   1027   }
   911   1028   
   912   1029   /* Returns 1 if a token is in the specified slot, 0 otherwise */
   913   1030   static int cackey_token_present(struct cackey_slot *slot) {
   914   1031   	unsigned char ccc_aid[] = {0xa0, 0x00, 0x00, 0x01, 0x16, 0xdb, 0x00};
   915   1032   	int send_ret;
................................................................................
  1596   1713   
  1597   1714   					pcsc_readers += curr_reader_len + 1;
  1598   1715   				}
  1599   1716   
  1600   1717   				if (currslot > 0) {
  1601   1718   					slot_count = currslot;
  1602   1719   				}
         1720  +			} else {
         1721  +				CACKEY_DEBUG_PRINTF("Second call to SCardListReaders failed, return %s/%li", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_listreaders_ret), (long) scard_listreaders_ret);
  1603   1722   			}
  1604   1723   
  1605   1724   			free(pcsc_readers_s);
         1725  +		} else {
         1726  +			CACKEY_DEBUG_PRINTF("First call to SCardListReaders failed, return %s/%li", CACKEY_DEBUG_FUNC_SCARDERR_TO_STR(scard_listreaders_ret), (long) scard_listreaders_ret);
  1606   1727   		}
  1607   1728   	}
  1608   1729   
  1609   1730   	mutex_retval = cackey_mutex_unlock(cackey_biglock);
  1610   1731   	if (mutex_retval != 0) {
  1611   1732   		CACKEY_DEBUG_PRINTF("Error.  Unlocking failed.");
  1612   1733