Diff

Differences From Artifact [f34f4e9e63]:

To Artifact [efb7accc6b]:


     1      1   #ifdef HAVE_CONFIG_H
     2      2   #include "config.h"
     3      3   #endif
     4      4   
     5      5   #ifdef HAVE_PCSCLITE_H
     6      6   #  include <pcsclite.h>
     7      7   #endif
            8  +#ifdef HAVE_WINSCARD_H
            9  +#  include <winscard.h>
           10  +#endif
     8     11   #ifdef HAVE_STDINT_H
     9     12   #  include <stdint.h>
    10     13   #endif
    11     14   #ifdef HAVE_INTTYPES_H
    12     15   #  include <inttypes.h>
    13     16   #endif
    14     17   #ifdef HAVE_STDLIB_H
................................................................................
   127    130   
   128    131   	int decrypt_active;
   129    132   	CK_MECHANISM_TYPE decrypt_mechanism;
   130    133   	CK_VOID_PTR decrypt_mech_parm;
   131    134   	CK_ULONG decrypt_mech_parmlen;
   132    135   };
   133    136   
          137  +/* CACKEY Global Handles */
   134    138   static void *cackey_biglock = NULL;
   135         -static struct cackey_session cackey_sessions[8];
          139  +static struct cackey_session cackey_sessions[128];
   136    140   static int cackey_initialized = 0;
   137    141   static int cackey_biglock_init = 0;
   138    142   CK_C_INITIALIZE_ARGS cackey_args;
   139    143   
          144  +/* PCSC Global Handles */
          145  +static LPSCARDCONTEXT cackey_pcsc_handle = NULL;
          146  +
   140    147   static unsigned long cackey_getversion(void) {
   141    148   	static unsigned long retval = 255;
   142    149   	unsigned long major = 0;
   143    150   	unsigned long minor = 0;
   144    151   	char *major_str = NULL;
   145    152   	char *minor_str = NULL;
   146    153   
................................................................................
   167    174   	retval = (major << 16) | (minor << 8);
   168    175   #endif
   169    176   
   170    177   	CACKEY_DEBUG_PRINTF("Returning 0x%lx", retval);
   171    178   
   172    179   	return(retval);
   173    180   }
          181  +
          182  +/* APDU Related Functions */
          183  +static int cackey_send_apdu(unsigned char class, unsigned char instruction, unsigned char p1, unsigned char p2, unsigned char lc, unsigned char *data, unsigned char *resp, unsigned char resplen) {
          184  +	LONG scard_est_context_ret;
          185  +#ifdef HAVE_SCARDISVALIDCONTEXT
          186  +	LONG scard_isvalid_ret;
          187  +#endif
          188  +
          189  +	CACKEY_DEBUG_PRINTF("Called.");
          190  +
          191  +	if (cackey_pcsc_handle == NULL) {
          192  +		cackey_pcsc_handle = malloc(sizeof(*cackey_pcsc_handle));
          193  +		if (cackey_pcsc_handle == NULL) {
          194  +			CACKEY_DEBUG_PRINTF("Call to malloc() failed, returning in failure");
          195  +
          196  +			return(-1);
          197  +		}
          198  +
          199  +		scard_est_context_ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, cackey_pcsc_handle);
          200  +		if (scard_est_context_ret != SCARD_S_SUCCESS) {
          201  +			CACKEY_DEBUG_PRINTF("Call to SCardEstablishContext failed (returned %li), returning in failure", (long) scard_est_context_ret);
          202  +
          203  +			free(cackey_pcsc_handle);
          204  +
          205  +			return(-1);
          206  +		}
          207  +	}
          208  +
          209  +#ifdef HAVE_SCARDISVALIDCONTEXT
          210  +	scard_isvalid_ret = SCardIsValidContext(*cackey_pcsc_handle);
          211  +	if (scard_isvalid_ret != SCARD_S_SUCCESS) {
          212  +		CACKEY_DEBUG_PRINTF("Handle has become invalid, trying to re-establish...");
          213  +
          214  +		scard_est_context_ret = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, cackey_pcsc_handle);
          215  +		if (scard_est_context_ret != SCARD_S_SUCCESS) {
          216  +			CACKEY_DEBUG_PRINTF("Call to SCardEstablishContext failed (returned %li), returning in failure", (long) scard_est_context_ret);
          217  +
          218  +			free(cackey_pcsc_handle);
          219  +
          220  +			return(-1);
          221  +		}
          222  +
          223  +		CACKEY_DEBUG_PRINTF("Handle has been re-established");
          224  +	}
          225  +#endif
          226  +
          227  +	/* Connect to a reader, if needed */
          228  +
          229  +	/* Transmit */
          230  +}
   174    231   
   175    232   /* Returns 0 on success */
   176    233   static int cackey_mutex_create(void **mutex) {
   177    234   	pthread_mutex_t *pthread_mutex;
   178    235   	int pthread_retval;
   179    236   	CK_RV custom_retval;
   180    237   
................................................................................
   290    347   	CK_VOID_PTR pValue;
   291    348   	CK_ULONG ulValueLen;
   292    349   	CK_OBJECT_CLASS ck_object_class;
   293    350   	CK_CERTIFICATE_TYPE ck_certificate_type;
   294    351   	CK_KEY_TYPE ck_key_type;
   295    352   	CK_UTF8CHAR ucTmpBuf[1024];
   296    353   	unsigned char certificate[16384];
   297         -	ssize_t getcert_ret, certificate_len = -1, x509_read_ret;
   298         -	int fd;
          354  +	ssize_t certificate_len = -1, x509_read_ret;
   299    355   	int pValue_free;
   300    356   
   301    357   	CACKEY_DEBUG_PRINTF("Called (objectClass = %lu, identity_num = %lu).", (unsigned long) objectclass, identity_num);
   302    358   
   303    359   	if (objectclass != CKO_CERTIFICATE && objectclass != CKO_PUBLIC_KEY && objectclass != CKO_PRIVATE_KEY) {
   304    360   		CACKEY_DEBUG_PRINTF("Returning 0 objects (NULL), invalid object class");
   305    361   
................................................................................
   695    751   	CACKEY_DEBUG_PRINTF("Returning CKR_OK (%i)", CKR_OK);
   696    752   
   697    753   	return(CKR_OK);
   698    754   }
   699    755   
   700    756   CK_DEFINE_FUNCTION(CK_RV, C_GetInfo)(CK_INFO_PTR pInfo) {
   701    757   	static CK_UTF8CHAR manufacturerID[] = "U.S. Government";
   702         -	static CK_UTF8CHAR libraryDescription[] = "SSH Agent PKCS#11";
          758  +	static CK_UTF8CHAR libraryDescription[] = "CACKey";
   703    759   
   704    760   	CACKEY_DEBUG_PRINTF("Called.");
   705    761   
   706    762   	if (pInfo == NULL) {
   707    763   		CACKEY_DEBUG_PRINTF("Error. pInfo is NULL.");
   708    764   
   709    765   		return(CKR_ARGUMENTS_BAD);
................................................................................
   733    789   
   734    790   	return(CKR_OK);
   735    791   }
   736    792   
   737    793   /* We only support 1 slot.  If the slot exists, the token exists. */
   738    794   CK_DEFINE_FUNCTION(CK_RV, C_GetSlotList)(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) {
   739    795   	CK_ULONG count, slot_present = 0, currslot;
   740         -	int fd;
   741    796   
   742    797   	CACKEY_DEBUG_PRINTF("Called.");
   743    798   
   744    799   	if (pulCount == NULL) {
   745    800   		CACKEY_DEBUG_PRINTF("Error. pulCount is NULL.");
   746    801   
   747    802   		return(CKR_ARGUMENTS_BAD);
................................................................................
   781    836   	return(CKR_OK);
   782    837   
   783    838   	tokenPresent = tokenPresent; /* Supress unused variable warning */
   784    839   }
   785    840   
   786    841   CK_DEFINE_FUNCTION(CK_RV, C_GetSlotInfo)(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
   787    842   	static CK_UTF8CHAR manufacturerID[] = "U.S. Government";
   788         -	static CK_UTF8CHAR slotDescription[] = "SSH Agent Slot";
          843  +	static CK_UTF8CHAR slotDescription[] = "CACKey Slot";
   789    844   
   790    845   	CACKEY_DEBUG_PRINTF("Called.");
   791    846   
   792    847   	if (pInfo == NULL) {
   793    848   		CACKEY_DEBUG_PRINTF("Error. pInfo is NULL.");
   794    849   
   795    850   		return(CKR_ARGUMENTS_BAD);
................................................................................
   826    881   
   827    882   	return(CKR_OK);
   828    883   }
   829    884   
   830    885   CK_DEFINE_FUNCTION(CK_RV, C_GetTokenInfo)(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) {
   831    886   	static CK_UTF8CHAR manufacturerID[] = "U.S. Government";
   832    887   	static CK_UTF8CHAR defaultLabel[] = "Unknown Token";
   833         -	static CK_UTF8CHAR model[] = "SSH Agent Token";
   834         -	int fd, bytestocopy;
          888  +	static CK_UTF8CHAR model[] = "CAC Token";
   835    889   
   836    890   	CACKEY_DEBUG_PRINTF("Called.");
   837    891   
   838    892   	if (pInfo == NULL) {
   839    893   		CACKEY_DEBUG_PRINTF("Error. pInfo is NULL.");
   840    894   
   841    895   		return(CKR_ARGUMENTS_BAD);
................................................................................
   852    906   		CACKEY_DEBUG_PRINTF("Error.  Not initialized.");
   853    907   
   854    908   		return(CKR_CRYPTOKI_NOT_INITIALIZED);
   855    909   	}
   856    910   
   857    911   	/* XXX: Verify connection is valid */
   858    912   	if (0) {
   859         -		CACKEY_DEBUG_PRINTF("Error. Tried to connect to slot, but failed.  fd = %i", fd);
          913  +		CACKEY_DEBUG_PRINTF("Error. Tried to connect to slot, but failed.");
   860    914   
   861    915   		return(CKR_SLOT_ID_INVALID);
   862    916   	}
   863    917   
   864    918   	/* XXX: Get list of identities */
   865    919   	if (0) {
   866    920   		CACKEY_DEBUG_PRINTF("Error. No identities found in slot.");
................................................................................
  1055   1109   	CACKEY_DEBUG_PRINTF("Returning CKR_FUNCTION_NOT_SUPPORTED (%i)", CKR_FUNCTION_NOT_SUPPORTED);
  1056   1110   
  1057   1111   	return(CKR_FUNCTION_NOT_SUPPORTED);
  1058   1112   }
  1059   1113   
  1060   1114   CK_DEFINE_FUNCTION(CK_RV, C_OpenSession)(CK_SLOT_ID slotID, CK_FLAGS flags, CK_VOID_PTR pApplication, CK_NOTIFY notify, CK_SESSION_HANDLE_PTR phSession) {
  1061   1115   	struct cackey_identity *identities;
  1062         -	unsigned long idx, num_ids, id_idx, curr_id_type, curr_ssh_id_idx;
         1116  +	unsigned long idx, num_ids, id_idx, curr_id_type;
  1063   1117   	CK_BYTE sigbuf[1024];
  1064   1118   	ssize_t sigbuflen;
  1065   1119   	int mutex_retval;
  1066   1120   	int found_session = 0;
  1067         -	int fd;
  1068   1121   
  1069   1122   	CACKEY_DEBUG_PRINTF("Called.");
  1070   1123   
  1071   1124   	if (slotID != 0) {
  1072   1125   		/* We only support one slot -- slot 0 */
  1073   1126   		CACKEY_DEBUG_PRINTF("Error. Invalid slot requested (%lu), only one slot available: 0", slotID);
  1074   1127   
................................................................................
  2124   2177   }
  2125   2178   
  2126   2179   CK_DEFINE_FUNCTION(CK_RV, C_DecryptUpdate)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedPart, CK_ULONG ulEncryptedPartLen, CK_BYTE_PTR pPart, CK_ULONG_PTR pulPartLen) {
  2127   2180   	static CK_BYTE buf[16384];
  2128   2181   	ssize_t buflen;
  2129   2182   	CK_RV retval = CKR_GENERAL_ERROR;
  2130   2183   	int mutex_retval;
  2131         -	int fd;
  2132   2184   
  2133   2185   	CACKEY_DEBUG_PRINTF("Called.");
  2134   2186   
  2135   2187   	if (!cackey_initialized) {
  2136   2188   		CACKEY_DEBUG_PRINTF("Error.  Not initialized.");
  2137   2189   
  2138   2190   		return(CKR_CRYPTOKI_NOT_INITIALIZED);
................................................................................
  2577   2629   
  2578   2630   CK_DEFINE_FUNCTION(CK_RV, C_SignFinal)(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pSignature, CK_ULONG_PTR pulSignatureLen) {
  2579   2631   	static CK_BYTE sigbuf[1024];
  2580   2632   	ssize_t sigbuflen;
  2581   2633   	CK_RV retval = CKR_GENERAL_ERROR;
  2582   2634   	int terminate_sign = 1;
  2583   2635   	int mutex_retval;
  2584         -	int fd;
  2585   2636   
  2586   2637   	CACKEY_DEBUG_PRINTF("Called.");
  2587   2638   
  2588   2639   	if (!cackey_initialized) {
  2589   2640   		CACKEY_DEBUG_PRINTF("Error.  Not initialized.");
  2590   2641   
  2591   2642   		return(CKR_CRYPTOKI_NOT_INITIALIZED);