Check-in [a2ac84031e]
Overview
Comment:Updated to support determining key size from X.509 object (untested)

Updated to set HW TOKEN flag

Updated to pad sign/decrypt message to key size (untested)

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:a2ac84031e5bfbe46922adbdb12f8710a041dd03
User & Date: rkeene on 2010-05-17 19:37:43
Other Links: manifest | tags
Context
2010-05-17
19:43
Fixed issues with padding check-in: 66507306f5 user: rkeene tags: trunk
19:37
Updated to support determining key size from X.509 object (untested)

Updated to set HW TOKEN flag

Updated to pad sign/decrypt message to key size (untested) check-in: a2ac84031e user: rkeene tags: trunk

14:55
Added removable device flag to slot info check-in: b4a6b9d685 user: rkeene tags: trunk
Changes

Modified asn1-x509.c from [cf76aee3de] to [d808ad3525].

    39     39   		struct asn1_object certificate;
    40     40   			struct asn1_object version;
    41     41   			struct asn1_object serial_number;
    42     42   			struct asn1_object signature_algo;
    43     43   			struct asn1_object issuer;
    44     44   			struct asn1_object validity;
    45     45   			struct asn1_object subject;
    46         -		struct asn1_object signature;
           46  +			struct asn1_object pubkeyinfo;
           47  +				struct asn1_object pubkey_algoid;
           48  +					struct asn1_object pubkey_algo;
           49  +					struct asn1_object pubkey_algoparm;
           50  +				struct asn1_object pubkey;
    47     51   };
    48     52   
    49     53   static int _asn1_x509_read_asn1_object(unsigned char *buf, size_t buflen, va_list *args) {
    50     54   	unsigned char small_object_size;
    51     55   	unsigned char *buf_p;
    52     56   	struct asn1_object *outbuf;
    53     57   
................................................................................
    65     69   
    66     70   	outbuf->tag = *buf_p;
    67     71   	buf_p++;
    68     72   	buflen--;
    69     73   	if (buflen == 0) {
    70     74   		return(-1);
    71     75   	}
           76  +
           77  +	/* NULL Tag -- no size is required */
           78  +	if (outbuf->tag == 0x00) {
           79  +		return(_asn1_x509_read_asn1_object(buf_p, buflen, args));
           80  +	}
    72     81   
    73     82   	small_object_size = *buf_p;
    74     83   	buf_p++;
    75     84   	buflen--;
    76     85   	if (buflen == 0) {
    77     86   		return(-1);
    78     87   	}
................................................................................
   130    139   	}
   131    140   
   132    141   	read_ret = asn1_x509_read_asn1_object(outbuf->wholething.contents, outbuf->wholething.size, &outbuf->certificate, NULL);
   133    142   	if (read_ret != 0) {
   134    143   		return(-1);
   135    144   	}
   136    145   
   137         -	read_ret = asn1_x509_read_asn1_object(outbuf->certificate.contents, outbuf->certificate.size, &outbuf->version, &outbuf->serial_number, &outbuf->signature_algo, &outbuf->issuer, &outbuf->validity, &outbuf->subject, NULL);
          146  +	read_ret = asn1_x509_read_asn1_object(outbuf->certificate.contents, outbuf->certificate.size, &outbuf->version, &outbuf->serial_number, &outbuf->signature_algo, &outbuf->issuer, &outbuf->validity, &outbuf->subject, &outbuf->pubkeyinfo, NULL);
          147  +	if (read_ret != 0) {
          148  +		return(-1);
          149  +	}
          150  +
          151  +	read_ret = asn1_x509_read_asn1_object(outbuf->pubkeyinfo.contents, outbuf->pubkeyinfo.size, &outbuf->pubkey_algoid, &outbuf->pubkey, NULL);
   138    152   	if (read_ret != 0) {
   139    153   		return(-1);
   140    154   	}
   141    155   
   142    156   	return(0);
   143    157   }
   144    158   
................................................................................
   185    199   
   186    200   	if (outbuf) {
   187    201   		*outbuf = x509.serial_number.asn1rep;
   188    202   	}
   189    203   
   190    204   	return(x509.serial_number.asn1rep_len);
   191    205   }
          206  +
          207  +ssize_t x509_to_keysize(void *x509_der_buf, size_t x509_der_buf_len) {
          208  +	struct asn1_object null, pubkey, modulus, exponent;
          209  +	struct x509_object x509;
          210  +	int read_ret;
          211  +
          212  +	read_ret = asn1_x509_read_object(x509_der_buf, x509_der_buf_len, &x509);
          213  +	if (read_ret != 0) {
          214  +		return(-1);
          215  +	}
          216  +
          217  +	/* The structure of "pubkey" is specified in PKCS #1 */
          218  +	read_ret = asn1_x509_read_asn1_object(x509.pubkey.contents, x509.pubkey.size, &null, &pubkey, NULL);
          219  +	if (read_ret != 0) {
          220  +		return(-1);
          221  +	}
          222  +
          223  +	read_ret = asn1_x509_read_asn1_object(pubkey.contents, pubkey.size, &modulus, &exponent, NULL);
          224  +	if (read_ret != 0) {
          225  +		return(-1);
          226  +	}
          227  +
          228  +	return(modulus.size - 1);
          229  +}
   192    230   
   193    231   /*
   194    232    * http://www.blackberry.com/developers/docs/4.6.0api/javax/microedition/pki/Certificate.html
   195    233    */
   196    234   static const char *_x509_objectid_to_label_string(void *buf, size_t buflen) {
   197    235   	switch (buflen) {
   198    236   		case 3:

Modified asn1-x509.h from [73df2a78e9] to [40a1fc466e].

    11     11   #endif
    12     12   
    13     13   ssize_t x509_to_subject(void *x509_der_buf, size_t x509_der_buf_len, void **outbuf);
    14     14   
    15     15   ssize_t x509_to_issuer(void *x509_der_buf, size_t x509_der_buf_len, void **outbuf);
    16     16   
    17     17   ssize_t x509_to_serial(void *x509_der_buf, size_t x509_der_buf_len, void **outbuf);
           18  +
           19  +ssize_t x509_to_keysize(void *x509_der_buf, size_t x509_der_buf_len);
    18     20   
    19     21   ssize_t x509_dn_to_string(void *asn1_der_buf, size_t asn1_der_buf_len, char *outbuf, size_t outbuf_len, char *matchlabel);
    20     22   
    21     23   #endif

Modified cackey.c from [6b8855e22d] to [e6d26b97df].

   461    461   	unsigned char applet[7];
   462    462   	uint16_t file;
   463    463   
   464    464   	unsigned char *label;
   465    465   
   466    466   	size_t certificate_len;
   467    467   	unsigned char *certificate;
          468  +
          469  +	ssize_t keysize;
   468    470   };
   469    471   
   470    472   struct cackey_identity {
   471    473   	struct cackey_pcsc_identity *pcsc_identity;
   472    474   
   473    475   	CK_ATTRIBUTE *attributes;
   474    476   	CK_ULONG attributes_count;
................................................................................
  1774   1776   
  1775   1777   			curr_id = &certs[outidx];
  1776   1778   			outidx++;
  1777   1779   
  1778   1780   			memcpy(curr_id->applet, curr_aid, sizeof(curr_id->applet));
  1779   1781   			curr_id->file = ccc_curr->value_cardurl->objectid;
  1780   1782   			curr_id->label = NULL;
         1783  +			curr_id->keysize = -1;
  1781   1784   
  1782   1785   			CACKEY_DEBUG_PRINTF("Filling curr_id->applet (%p) with %lu bytes:", curr_id->applet, (unsigned long) sizeof(curr_id->applet));
  1783   1786   			CACKEY_DEBUG_PRINTBUF("VAL:", curr_id->applet, sizeof(curr_id->applet));
  1784   1787   
  1785   1788   			curr_id->certificate_len = app_curr->length;
  1786   1789   
  1787   1790   			curr_id->certificate = malloc(curr_id->certificate_len);
................................................................................
  1829   1832    *     ...
  1830   1833    *
  1831   1834    * NOTES
  1832   1835    *     ...
  1833   1836    *
  1834   1837    */
  1835   1838   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) {
         1839  +	unsigned char *tmpbuf, *tmpbuf_s;
         1840  +	unsigned char bytes_to_send, p1;
  1836   1841   	cackey_ret send_ret;
         1842  +	size_t tmpbuflen, padlen;
         1843  +	int free_tmpbuf = 0;
  1837   1844   	int le;
  1838   1845   
  1839   1846   	CACKEY_DEBUG_PRINTF("Called.");
  1840   1847   
  1841   1848   	if (buflen > 255) {
  1842   1849   		CACKEY_DEBUG_PRINTF("Error.  buflen is greater than 255 (buflen = %lu)", (unsigned long) buflen);
  1843   1850   
................................................................................
  1875   1882   	}
  1876   1883   
  1877   1884   	if (identity->pcsc_identity == NULL) {
  1878   1885   		CACKEY_DEBUG_PRINTF("Error.  identity->pcsc_identity is NULL");
  1879   1886   
  1880   1887   		return(-1);
  1881   1888   	}
         1889  +
         1890  +	/* Determine identity Key size */
         1891  +	if (identity->pcsc_identity->keysize < 0) {
         1892  +		identity->pcsc_identity->keysize = x509_to_keysize(identity->pcsc_identity->certificate, identity->pcsc_identity->certificate_len);
         1893  +	}
         1894  +
         1895  +	/* Pad message to key size */
         1896  +	if (identity->pcsc_identity->keysize > 0) {
         1897  +		if (buflen != identity->pcsc_identity->keysize) {
         1898  +			if (buflen > (identity->pcsc_identity->keysize + 3)) {
         1899  +				CACKEY_DEBUG_PRINTF("Error.  Message is too large to sign/decrypt");
         1900  +
         1901  +				return(-1);
         1902  +			}
         1903  +
         1904  +			tmpbuflen = identity->pcsc_identity->keysize;
         1905  +			tmpbuf = malloc(tmpbuflen);
         1906  +			free_tmpbuf = 1;
         1907  +
         1908  +			padlen = tmpbuflen - buflen - 3;
         1909  +
         1910  +			tmpbuf[0] = 0x00;
         1911  +			tmpbuf[1] = 0x01;
         1912  +			memset(&tmpbuf[2], 0xFF, padlen);
         1913  +			tmpbuf[padlen]= 0x00;
         1914  +			memcpy(&tmpbuf[padlen + 1], buf, buflen);
         1915  +		} else {
         1916  +			tmpbuf = buf;
         1917  +			tmpbuflen = buflen;
         1918  +			free_tmpbuf = 0;
         1919  +			padlen = 0;
         1920  +		}
         1921  +	} else {
         1922  +		CACKEY_DEBUG_PRINTF("Unable to determine key size, hoping the message is properly padded!");
         1923  +
         1924  +		tmpbuf = buf;
         1925  +		tmpbuflen = buflen;
         1926  +		free_tmpbuf = 0;
         1927  +		padlen = 0;
         1928  +	}
  1882   1929   
  1883   1930   	/* Begin transaction */
  1884   1931   	cackey_begin_transaction(slot);
  1885   1932   
  1886   1933   	/* Select correct applet */
  1887   1934   	CACKEY_DEBUG_PRINTF("Selecting applet found at %p ...", identity->pcsc_identity->applet);
  1888   1935   	cackey_select_applet(slot, identity->pcsc_identity->applet, sizeof(identity->pcsc_identity->applet));
  1889   1936   
  1890   1937   	/* Select correct file */
  1891   1938   	cackey_select_file(slot, identity->pcsc_identity->file);
  1892   1939   
  1893         -	send_ret = cackey_send_apdu(slot, GSCIS_CLASS_GLOBAL_PLATFORM, GSCIS_INSTR_SIGNDECRYPT, 0x00, 0x00, buflen, buf, le, NULL, outbuf, &outbuflen);
  1894         -	if (send_ret != CACKEY_PCSC_S_OK) {
  1895         -		CACKEY_DEBUG_PRINTF("ADPU Sending Failed -- returning in error.");
         1940  +	tmpbuf_s = tmpbuf;
         1941  +	while (tmpbuflen) {
         1942  +		if (tmpbuflen > 245) {
         1943  +			bytes_to_send = 245;
         1944  +			p1 = 0x80;
         1945  +		} else {
         1946  +			bytes_to_send = tmpbuflen;
         1947  +			p1 = 0x00;
         1948  +		}
  1896   1949   
  1897         -		/* End transaction */
  1898         -		cackey_end_transaction(slot);
         1950  +		send_ret = cackey_send_apdu(slot, GSCIS_CLASS_GLOBAL_PLATFORM, GSCIS_INSTR_SIGNDECRYPT, p1, 0x00, bytes_to_send, tmpbuf, le, NULL, outbuf, &outbuflen);
         1951  +		if (send_ret != CACKEY_PCSC_S_OK) {
         1952  +			CACKEY_DEBUG_PRINTF("ADPU Sending Failed -- returning in error.");
  1899   1953   
  1900         -		return(-1);
         1954  +			if (free_tmpbuf) {
         1955  +				if (tmpbuf_s) {
         1956  +					free(tmpbuf_s);
         1957  +				}
         1958  +			}
         1959  +
         1960  +			/* End transaction */
         1961  +			cackey_end_transaction(slot);
         1962  +
         1963  +			return(-1);
         1964  +		}
         1965  +
         1966  +		tmpbuf += bytes_to_send;
         1967  +		tmpbuflen -= bytes_to_send;
         1968  +	}
         1969  +
         1970  +	if (free_tmpbuf) {
         1971  +		if (tmpbuf_s) {
         1972  +			free(tmpbuf_s);
         1973  +		}
  1901   1974   	}
  1902   1975   
  1903   1976   	/* End transaction */
  1904   1977   	cackey_end_transaction(slot);
  1905   1978   
  1906   1979   #ifdef CACKEY_PARANOID
  1907   1980   #  ifdef _POSIX_SSIZE_MAX
................................................................................
  2938   3011   
  2939   3012   	bytes_to_copy = strlen(cackey_slots[slotID].pcsc_reader);
  2940   3013   	if (sizeof(pInfo->manufacturerID) < bytes_to_copy) {
  2941   3014   		bytes_to_copy = sizeof(pInfo->manufacturerID);
  2942   3015   	}
  2943   3016   	memcpy(pInfo->manufacturerID, cackey_slots[slotID].pcsc_reader, bytes_to_copy);
  2944   3017   
  2945         -	pInfo->flags = CKF_REMOVABLE_DEVICE;
         3018  +	pInfo->flags = CKF_REMOVABLE_DEVICE | CKF_HW_SLOT;
  2946   3019   
  2947   3020   	if (cackey_token_present(&cackey_slots[slotID]) == CACKEY_PCSC_S_TOKENPRESENT) {
  2948   3021   		pInfo->flags |= CKF_TOKEN_PRESENT;
  2949   3022   	}
  2950   3023   
  2951   3024   	pInfo->hardwareVersion.major = (cackey_getversion() >> 16) & 0xff;
  2952   3025   	pInfo->hardwareVersion.minor = (cackey_getversion() >> 8) & 0xff;