@@ -217,11 +217,11 @@ buf_user[sizeof(buf_user) - 1] = '\0'; \ fprintf(cackey_debug_fd(), "[%lu]: %s():%i: %s\n", CACKEY_DEBUG_GETTIME(), __func__, __LINE__, buf_user); \ fflush(cackey_debug_fd()); \ } # define CACKEY_DEBUG_PRINTBUF(f, x, y) { \ - static char buf_user[8192] = {0}, *buf_user_p, *buf_user_print; \ + static char buf_user[65536] = {0}, *buf_user_p, *buf_user_print; \ unsigned long buf_user_size; \ unsigned char *TMPBUF; \ unsigned long idx; \ int snprintf_ret; \ TMPBUF = (unsigned char *) (x); \ @@ -1733,11 +1733,11 @@ if (recv_len < bytes_to_copy) { bytes_to_copy = recv_len; } - CACKEY_DEBUG_PRINTF("Copying %lu bytes to the buffer (recv'd %lu bytes, but only %lu bytes left in our buffer)", (unsigned long) bytes_to_copy, (unsigned long) recv_len, (unsigned long) *respdata_len); + CACKEY_DEBUG_PRINTF("Copying %lu bytes to the buffer (recv'd %lu bytes, with %lu bytes left in our buffer)", (unsigned long) bytes_to_copy, (unsigned long) recv_len, (unsigned long) *respdata_len); memcpy(respdata, recv_buf, bytes_to_copy); respdata += bytes_to_copy; *respdata_len = bytes_to_copy; @@ -1747,18 +1747,20 @@ CACKEY_DEBUG_PRINTF("Throwing away %lu bytes, nowhere to put them!", (unsigned long) recv_len); } } if (major_rc == 0x61) { + unsigned int read_le; /* We need to READ */ CACKEY_DEBUG_PRINTF("Buffer read required"); - if (minor_rc == 0x00) { - minor_rc = CACKEY_APDU_MTU; + read_le = minor_rc; + if (read_le == 0x00) { + read_le = 256; } - pcsc_getresp_ret = cackey_send_apdu(slot, GSCIS_CLASS_ISO7816, GSCIS_INSTR_GET_RESPONSE, 0x00, 0x00, 0, NULL, minor_rc, respcode, respdata, &tmp_respdata_len); + pcsc_getresp_ret = cackey_send_apdu(slot, GSCIS_CLASS_ISO7816, GSCIS_INSTR_GET_RESPONSE, 0x00, 0x00, 0, NULL, read_le, respcode, respdata, &tmp_respdata_len); if (pcsc_getresp_ret != CACKEY_PCSC_S_OK) { CACKEY_DEBUG_PRINTF("Buffer read failed! Returning in failure"); /* End Smartcard Transaction */ @@ -2599,17 +2601,18 @@ */ static struct cackey_pcsc_identity *cackey_read_certs(struct cackey_slot *slot, struct cackey_pcsc_identity *certs, unsigned long *count) { cackey_pcsc_id_type check_id_type; struct cackey_pcsc_identity *curr_id; struct cackey_tlv_entity *ccc_tlv, *ccc_curr, *app_tlv, *app_curr; + struct x509_object check_certificate; unsigned char *piv_oid, piv_oid_pivauth[] = {NISTSP800_73_3_OID_PIVAUTH}, piv_oid_signature[] = {NISTSP800_73_3_OID_SIGNATURE}, piv_oid_keymgt[] = {NISTSP800_73_3_OID_KEYMGT}; unsigned char curr_aid[7]; unsigned char buffer[1024 * 32], *buffer_p, *tmpbuf; unsigned long outidx = 0; char *piv_label; cackey_ret transaction_ret; - ssize_t read_ret; + ssize_t read_ret, x509te_ret, x509tk_ret; size_t buffer_len, tmpbuflen; int certs_resizable; int send_ret, select_ret; int piv_key, piv = 0; int cached_certs_valid; @@ -2818,16 +2821,48 @@ curr_id->certificate_len = tmpbuflen; } else { CACKEY_DEBUG_PRINTF("Decompressing failed! uncompress() returned %i", uncompress_ret); free(tmpbuf); + + curr_id->certificate = NULL; + + outidx--; + + continue; } #else CACKEY_DEBUG_PRINTF("Error. We got a compressed certificate but we do not have zlib. Hoping for the best."); + + curr_id->certificate = NULL; + + outidx--; + + continue; #endif + } else { + CACKEY_DEBUG_PRINTF("We got an uncompressed certificate"); } } + + /* + * Fit the length of the certificate appropriately + */ + x509te_ret = x509_to_exponent(curr_id->certificate, curr_id->certificate_len, NULL); + x509tk_ret = x509_to_keysize(curr_id->certificate, curr_id->certificate_len); + if (x509tk_ret < 0 || x509te_ret < 0) { + CACKEY_DEBUG_PRINTF("We got an unparsable certificate, skipping (exponent size is %lli, public key size is %lli)", (long long) x509te_ret, (long long) x509tk_ret); + + curr_id->certificate = NULL; + + outidx--; + + continue; + } + + + CACKEY_DEBUG_PRINTF("Size of certificate %llu read, size of actual object %llu", (unsigned long long) curr_id->certificate_len, (unsigned long long) check_certificate.wholething.size); } } else { /* Read all the applets from the CCC's TLV */ ccc_tlv = cackey_read_tlv(slot);