Diff

Differences From Artifact [4ec2269ed9]:

To Artifact [1aac84790e]:


    25     25   #endif
    26     26   #ifdef HAVE_PTHREAD_H
    27     27   #  include <pthread.h>
    28     28   #endif
    29     29   #ifdef HAVE_LIMITS_H
    30     30   #  include <limits.h>
    31     31   #endif
           32  +#ifdef HAVE_STDIO_H
           33  +#  include <stdio.h>
           34  +#endif
    32     35   #ifdef HAVE_ZLIB_H
    33     36   #  ifdef HAVE_LIBZ
    34     37   #    include <zlib.h>
    35     38   #  endif
    36     39   #else
    37     40   #  ifdef HAVE_LIBZ
    38     41   #    undef HAVE_LIBZ
................................................................................
   154    157   #define GSCIS_TAG_CERT_ISSUE_DATE     0x71
   155    158   #define GSCIS_TAG_CERT_EXPIRE_DATE    0x72
   156    159   
   157    160   /** Applet IDs **/
   158    161   #define GSCIS_AID_CCC                 0xA0, 0x00, 0x00, 0x01, 0x16, 0xDB, 0x00
   159    162   
   160    163   #ifdef CACKEY_DEBUG
   161         -#  ifdef HAVE_STDIO_H
   162         -#    include <stdio.h>
   163         -#  endif
   164    164   
   165    165   #  define CACKEY_DEBUG_PRINTF(x...) { fprintf(stderr, "%s():%i: ", __func__, __LINE__); fprintf(stderr, x); fprintf(stderr, "\n"); fflush(stderr); }
   166    166   #  define CACKEY_DEBUG_PRINTBUF(f, x, y) { unsigned char *TMPBUF; unsigned long idx; TMPBUF = (unsigned char *) (x); fprintf(stderr, "%s():%i: %s  (%s/%lu = {%02x", __func__, __LINE__, f, #x, (unsigned long) (y), TMPBUF[0]); for (idx = 1; idx < (y); idx++) { fprintf(stderr, ", %02x", TMPBUF[idx]); }; fprintf(stderr, "})\n"); fflush(stderr); }
   167    167   #  define CACKEY_DEBUG_PERROR(x) { fprintf(stderr, "%s():%i: ", __func__, __LINE__); perror(x); fflush(stderr); }
   168    168   #  define free(x) { CACKEY_DEBUG_PRINTF("FREE(%p) (%s)", x, #x); free(x); }
   169    169   
   170    170   static void *CACKEY_DEBUG_FUNC_MALLOC(size_t size, const char *func, int line) {
................................................................................
  1846   1846    *     ...
  1847   1847    *
  1848   1848    * NOTES
  1849   1849    *     ...
  1850   1850    *
  1851   1851    */
  1852   1852   static ssize_t cackey_signdecrypt(struct cackey_slot *slot, struct cackey_identity *identity, unsigned char *buf, size_t buflen, unsigned char *outbuf, size_t outbuflen, int padInput, int unpadOutput) {
  1853         -	unsigned char *tmpbuf, *tmpbuf_s;
         1853  +	unsigned char *tmpbuf, *tmpbuf_s, *outbuf_s;
  1854   1854   	unsigned char bytes_to_send, p1;
  1855   1855   	unsigned char blocktype;
  1856   1856   	cackey_ret send_ret;
  1857   1857   	uint16_t respcode;
  1858   1858   	ssize_t retval = 0, unpadoffset;
  1859   1859   	size_t tmpbuflen, padlen, tmpoutbuflen;
  1860         -	int free_tmpbuf = 0, sepByte = -1;
         1860  +	int free_tmpbuf = 0;
  1861   1861   	int le;
  1862   1862   
  1863   1863   	CACKEY_DEBUG_PRINTF("Called.");
  1864   1864   
  1865         -	if (buflen > 255) {
  1866         -		CACKEY_DEBUG_PRINTF("Error.  buflen is greater than 255 (buflen = %lu)", (unsigned long) buflen);
  1867         -
  1868         -		return(-1);
  1869         -	}
  1870         -
  1871   1865   	if (slot == NULL) {
  1872   1866   		CACKEY_DEBUG_PRINTF("Error.  slot is NULL");
  1873   1867   
  1874   1868   		return(-1);
  1875   1869   	}
  1876   1870   
  1877   1871   	if (buf == NULL) {
................................................................................
  1915   1909   
  1916   1910   				tmpbuflen = identity->pcsc_identity->keysize;
  1917   1911   				tmpbuf = malloc(tmpbuflen);
  1918   1912   				free_tmpbuf = 1;
  1919   1913   
  1920   1914   				padlen = tmpbuflen - buflen - 3;
  1921   1915   
         1916  +				/* RSA PKCS#1 EMSA-PKCS1-v1_5 Padding */
  1922   1917   				tmpbuf[0] = 0x00;
  1923   1918   				tmpbuf[1] = 0x01;
  1924   1919   				memset(&tmpbuf[2], 0xFF, padlen);
  1925   1920   				tmpbuf[padlen + 2]= 0x00;
  1926   1921   				memcpy(&tmpbuf[padlen + 3], buf, buflen);
  1927   1922   
  1928   1923   				CACKEY_DEBUG_PRINTBUF("Unpadded:", buf, buflen);
................................................................................
  1955   1950   	CACKEY_DEBUG_PRINTF("Selecting applet found at %p ...", identity->pcsc_identity->applet);
  1956   1951   	cackey_select_applet(slot, identity->pcsc_identity->applet, sizeof(identity->pcsc_identity->applet));
  1957   1952   
  1958   1953   	/* Select correct file */
  1959   1954   	cackey_select_file(slot, identity->pcsc_identity->file);
  1960   1955   
  1961   1956   	tmpbuf_s = tmpbuf;
         1957  +	outbuf_s = outbuf;
  1962   1958   	while (tmpbuflen) {
  1963   1959   		if (tmpbuflen > 245) {
  1964   1960   			bytes_to_send = 245;
  1965   1961   			p1 = 0x80;
  1966   1962   			le = 0x00;
  1967   1963   		} else {
  1968   1964   			bytes_to_send = tmpbuflen;
................................................................................
  2001   1997   	}
  2002   1998   
  2003   1999   	if (free_tmpbuf) {
  2004   2000   		if (tmpbuf_s) {
  2005   2001   			free(tmpbuf_s);
  2006   2002   		}
  2007   2003   	}
         2004  +
         2005  +	outbuf = outbuf_s;
  2008   2006   
  2009   2007   	/* End transaction */
  2010   2008   	cackey_end_transaction(slot);
  2011   2009   
  2012   2010   #ifdef CACKEY_PARANOID
  2013   2011   #  ifdef _POSIX_SSIZE_MAX
  2014   2012   	if (outbuflen > _POSIX_SSIZE_MAX) {
................................................................................
  2017   2015   		return(-1);
  2018   2016   	}
  2019   2017   #  endif
  2020   2018   #endif
  2021   2019   
  2022   2020   	/* Unpad reply */
  2023   2021   	if (unpadOutput) {
  2024         -		if (retval < 2) {
         2022  +		if (retval < 3) {
  2025   2023   			CACKEY_DEBUG_PRINTF("Reply is too small, we are not able to unpad -- passing back and hoping for the best!");
  2026   2024   
         2025  +			CACKEY_DEBUG_PRINTF("Returning in success, retval = %li (bytes)", (long) retval);
         2026  +			return(retval);
         2027  +		}
         2028  +
         2029  +		if (outbuf[0] != 0x00) {
         2030  +			CACKEY_DEBUG_PRINTF("Unrecognized padding scheme -- passing back and hoping for the best!");
         2031  +
         2032  +			CACKEY_DEBUG_PRINTF("Returning in success, retval = %li (bytes)", (long) retval);
  2027   2033   			return(retval);
  2028   2034   		}
  2029   2035   
  2030         -		blocktype = outbuf[0];
         2036  +		blocktype = outbuf[1];
  2031   2037   		unpadoffset = 0;
  2032   2038   
  2033   2039   		switch (blocktype) {
  2034   2040   			case 0x00:
  2035   2041   				/* Padding Scheme 1, the first non-zero byte is the start of data */
  2036         -				for (unpadoffset = 1; unpadoffset < retval; unpadoffset++) {
         2042  +				for (unpadoffset = 2; unpadoffset < retval; unpadoffset++) {
  2037   2043   					if (outbuf[unpadoffset] != 0x00) {
  2038   2044   						break;
  2039   2045   					}
  2040   2046   				}
  2041   2047   				break;
  2042   2048   			case 0x01:
  2043   2049   				/* Padding Scheme 2, pad bytes are 0xFF followed by 0x00 */
  2044         -				for (unpadoffset = 1; unpadoffset < retval; unpadoffset++) {
         2050  +				for (unpadoffset = 2; unpadoffset < retval; unpadoffset++) {
  2045   2051   					if (outbuf[unpadoffset] != 0xFF) {
  2046   2052   						if (outbuf[unpadoffset] == 0x00) {
  2047   2053   							unpadoffset++;
  2048   2054   
  2049   2055   							break;
  2050   2056   						} else {
  2051   2057   							CACKEY_DEBUG_PRINTF("Invalid padding data found, returning in failure, should have been 0x00 found 0x%02x", (unsigned int) outbuf[unpadoffset]);
................................................................................
  2056   2062   						CACKEY_DEBUG_PRINTF("Invalid padding data found, returning in failure, should have been 0xFF found 0x%02x", (unsigned int) outbuf[unpadoffset]);
  2057   2063   
  2058   2064   						return(-1);
  2059   2065   					}
  2060   2066   				}
  2061   2067   				break;
  2062   2068   			case 0x02:
  2063         -				/* Padding Scheme 3, pad bytes are non-zero first non-zero byte found is the pad byte */
  2064         -				for (unpadoffset = 1; unpadoffset < retval; unpadoffset++) {
         2069  +				/* Padding Scheme 3, pad bytes are non-zero first zero byte found is the seperator byte */
         2070  +				for (unpadoffset = 2; unpadoffset < retval; unpadoffset++) {
  2065   2071   					if (outbuf[unpadoffset] == 0x00) {
  2066         -						continue;
  2067         -					}
  2068         -
  2069         -					if (sepByte == -1) {
  2070         -						sepByte = outbuf[unpadoffset];
  2071         -
  2072         -						continue;
  2073         -					}
  2074         -
  2075         -					if (outbuf[unpadoffset] == sepByte) {
  2076   2072   						unpadoffset++;
  2077   2073   
  2078   2074   						break;
  2079   2075   					}
  2080   2076   				}
  2081   2077   				break;
  2082   2078   		}
................................................................................
  2086   2082   
  2087   2083   			return(-1);
  2088   2084   		}
  2089   2085   
  2090   2086   		CACKEY_DEBUG_PRINTBUF("Padded:", outbuf, retval);
  2091   2087   
  2092   2088   		retval -= unpadoffset;
  2093         -		memmove(outbuf + unpadoffset, outbuf, retval);
         2089  +		memmove(outbuf, outbuf + unpadoffset, retval);
  2094   2090   
  2095   2091   		CACKEY_DEBUG_PRINTBUF("Unpadded:", outbuf, retval);
  2096   2092   	}
  2097   2093   
  2098   2094   
  2099         -	CACKEY_DEBUG_PRINTF("Returning in success, signed %li bytes", (long) retval);
         2095  +	CACKEY_DEBUG_PRINTF("Returning in success, retval = %li (bytes)", (long) retval);
  2100   2096   
  2101   2097   	return(retval);
  2102   2098   }
  2103   2099   
  2104   2100   /*
  2105   2101    * SYNPOSIS
  2106   2102    *     ...
................................................................................
  2195   2191   	status_ret = SCardStatus(slot->pcsc_card, NULL, &reader_len, &state, &protocol, atr, &atr_len);
  2196   2192   	if (status_ret != SCARD_S_SUCCESS) {
  2197   2193   		slot->slot_reset = 1;
  2198   2194   		slot->token_flags = CKF_LOGIN_REQUIRED;
  2199   2195   
  2200   2196   		if (status_ret == SCARD_W_RESET_CARD) {
  2201   2197   			CACKEY_DEBUG_PRINTF("Reset required, please hold...");
  2202         -
  2203         -
  2204   2198   
  2205   2199   			scard_reconn_ret = SCardReconnect(slot->pcsc_card, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, SCARD_RESET_CARD, &protocol);
  2206   2200   			if (scard_reconn_ret == SCARD_S_SUCCESS) {
  2207   2201   				/* Re-establish transaction, if it was present */
  2208   2202   				if (slot->transaction_depth > 0) {
  2209   2203   					slot->transaction_depth--;
  2210   2204   					cackey_begin_transaction(slot);
................................................................................
  2491   2485   
  2492   2486   				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
  2493   2487   
  2494   2488   				break;
  2495   2489   			case CKA_LABEL:
  2496   2490   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_LABEL (0x%08lx) ...", (unsigned long) curr_attr_type);
  2497   2491   
  2498         -				/* Determine name */
  2499         -				x509_read_ret = cackey_pcsc_identity_to_label(identity, ucTmpBuf, sizeof(ucTmpBuf));
  2500         -				if (x509_read_ret > 0) {
  2501         -					pValue = ucTmpBuf;
  2502         -					ulValueLen = x509_read_ret;
         2492  +				/* XXX: Determine name */
         2493  +				ulValueLen = snprintf(ucTmpBuf, sizeof(ucTmpBuf), "Identity #%lu", (unsigned long) identity_num);
         2494  +				pValue = ucTmpBuf;
         2495  +
         2496  +				if (ulValueLen >= sizeof(ucTmpBuf)) {
         2497  +					ulValueLen = 0;
         2498  +					pValue = NULL;
  2503   2499   				}
  2504   2500   
  2505   2501   				CACKEY_DEBUG_PRINTF(" ... returning (%p/%lu)", pValue, (unsigned long) ulValueLen);
  2506   2502   
  2507   2503   				break;
  2508   2504   			case CKA_VALUE:
  2509   2505   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_VALUE (0x%08lx) ...", (unsigned long) curr_attr_type);
................................................................................
  2651   2647   
  2652   2648   				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
  2653   2649   
  2654   2650   				break;
  2655   2651   			case CKA_SIGN_RECOVER:
  2656   2652   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_SIGN_RECOVER (0x%08lx) ...", (unsigned long) curr_attr_type);
  2657   2653   
         2654  +				/* We currently only support "Sign with Appendix" */
  2658   2655   				pValue = &ck_false;
  2659   2656   				ulValueLen = sizeof(ck_false);
  2660   2657   
  2661   2658   				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
  2662   2659   
  2663   2660   				break;
  2664   2661   			case CKA_DECRYPT:
................................................................................
  2670   2667   				} else {
  2671   2668   					pValue = &ck_false;
  2672   2669   					ulValueLen = sizeof(ck_false);
  2673   2670   				}
  2674   2671   
  2675   2672   				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
  2676   2673   
         2674  +				break;
         2675  +			case CKA_SENSITIVE:
         2676  +				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_SENSITIVE (0x%08lx) ...", (unsigned long) curr_attr_type);
         2677  +
         2678  +				if (objectclass == CKO_PRIVATE_KEY) {
         2679  +					pValue = &ck_true;
         2680  +					ulValueLen = sizeof(ck_true);
         2681  +				} else {
         2682  +					pValue = &ck_false;
         2683  +					ulValueLen = sizeof(ck_false);
         2684  +				}
         2685  +
         2686  +				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
         2687  +
         2688  +				break;
         2689  +			case CKA_EXTRACTABLE:
         2690  +				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_EXTRACTABLE (0x%08lx) ...", (unsigned long) curr_attr_type);
         2691  +
         2692  +				if (objectclass == CKO_PRIVATE_KEY) {
         2693  +					pValue = &ck_false;
         2694  +					ulValueLen = sizeof(ck_true);
         2695  +				} else {
         2696  +					pValue = &ck_true;
         2697  +					ulValueLen = sizeof(ck_false);
         2698  +				}
         2699  +
         2700  +				CACKEY_DEBUG_PRINTF(" ... returning %lu (%p/%lu)", (unsigned long) *((CK_BBOOL *) pValue), pValue, (unsigned long) ulValueLen);
         2701  +
         2702  +				break;
         2703  +			case CKA_MODULUS:
         2704  +				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_MODULUS (0x%08lx) ...", (unsigned long) curr_attr_type);
         2705  +
         2706  +				if (certificate_len >= 0) {
         2707  +					x509_read_ret = x509_to_modulus(certificate, certificate_len, &pValue);
         2708  +					if (x509_read_ret < 0) {
         2709  +						pValue = NULL;
         2710  +					} else {
         2711  +						ulValueLen = x509_read_ret;
         2712  +					}
         2713  +				}
         2714  +
         2715  +				CACKEY_DEBUG_PRINTF(" ... returning (%p/%lu)", pValue, (unsigned long) ulValueLen);
         2716  +
         2717  +				break;
         2718  +			case CKA_PUBLIC_EXPONENT:
         2719  +				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_PUBLIC_EXPONENT (0x%08lx) ...", (unsigned long) curr_attr_type);
         2720  +
         2721  +				if (certificate_len >= 0) {
         2722  +					x509_read_ret = x509_to_exponent(certificate, certificate_len, &pValue);
         2723  +					if (x509_read_ret < 0) {
         2724  +						pValue = NULL;
         2725  +					} else {
         2726  +						ulValueLen = x509_read_ret;
         2727  +					}
         2728  +				}
         2729  +
         2730  +				CACKEY_DEBUG_PRINTF(" ... returning (%p/%lu)", pValue, (unsigned long) ulValueLen);
         2731  +
  2677   2732   				break;
  2678   2733   			case CKA_TRUST_SERVER_AUTH:
  2679   2734   				CACKEY_DEBUG_PRINTF("Requesting attribute CKA_TRUST_SERVER_AUTH (0x%08lx) ...", (unsigned long) curr_attr_type);
  2680   2735   
  2681   2736   				pValue = &ck_true;
  2682   2737   				ulValueLen = sizeof(ck_true);
  2683   2738