static int pcsc_transmit(sc_reader_t *reader, sc_slot_info_t *slot, sc_apdu_t *apdu) { size_t ssize, rsize, rbuflen = 0; u8 *sbuf = NULL, *rbuf = NULL; int r; /* we always use a at least 258 byte size big return buffer * to mimic the behaviour of the old implementation (some readers * seems to require a larger than necessary return buffer). * The buffer for the returned data needs to be at least 2 bytes * larger than the expected data length to store SW1 and SW2. */ rsize = rbuflen = apdu->resplen <= 256 ? 258 : apdu->resplen + 2; rbuf = malloc(rbuflen); if (rbuf == NULL) { r = SC_ERROR_MEMORY_FAILURE; goto out; } /* encode and log the APDU */ r = sc_apdu_get_octets(reader->ctx, apdu, &sbuf, &ssize, slot->active_protocol); if (r != SC_SUCCESS) goto out; if (reader->ctx->debug >= 6) sc_apdu_log(reader->ctx, sbuf, ssize, 1); r = pcsc_internal_transmit(reader, slot, sbuf, ssize, rbuf, &rsize, apdu->control); if (r < 0) { /* unable to transmit ... most likely a reader problem */ sc_error(reader->ctx, "unable to transmit"); goto out; } if (reader->ctx->debug >= 6) sc_apdu_log(reader->ctx, rbuf, rsize, 0); /* set response */ r = sc_apdu_set_resp(reader->ctx, apdu, rbuf, rsize); out: if (sbuf != NULL) { sc_mem_clear(sbuf, ssize); free(sbuf); } if (rbuf != NULL) { sc_mem_clear(rbuf, rbuflen); free(rbuf); } return r; }
static int openct_reader_transmit(sc_reader_t *reader, sc_slot_info_t *slot, sc_apdu_t *apdu) { size_t ssize, rsize, rbuflen = 0; u8 *sbuf = NULL, *rbuf = NULL; int r; rsize = rbuflen = apdu->resplen + 2; rbuf = malloc(rbuflen); if (rbuf == NULL) { r = SC_ERROR_MEMORY_FAILURE; goto out; } /* encode and log the APDU */ r = sc_apdu_get_octets(reader->ctx, apdu, &sbuf, &ssize, SC_PROTO_RAW); if (r != SC_SUCCESS) goto out; if (reader->ctx->debug >= 6) sc_apdu_log(reader->ctx, sbuf, ssize, 1); r = openct_reader_internal_transmit(reader, slot, sbuf, ssize, rbuf, &rsize, apdu->control); if (r < 0) { /* unable to transmit ... most likely a reader problem */ sc_error(reader->ctx, "unable to transmit"); goto out; } if (reader->ctx->debug >= 6) sc_apdu_log(reader->ctx, rbuf, rsize, 0); /* set response */ r = sc_apdu_set_resp(reader->ctx, apdu, rbuf, rsize); out: if (sbuf != NULL) { sc_mem_clear(sbuf, ssize); free(sbuf); } if (rbuf != NULL) { sc_mem_clear(rbuf, rbuflen); free(rbuf); } return r; }
/* bPINOperation */ *((*pc_to_rdr_secure) + sizeof *secure) = CCID_OPERATION_MODIFY; modify = (abPINDataStucture_Modification_t *) ((*pc_to_rdr_secure) + sizeof *secure + 1); modify->bTimeOut = bTimeOut; modify->bmFormatString = bmFormatString; modify->bmPINBlockString = bmPINBlockString; modify->bmPINLengthFormat = bmPINLengthFormat; if (!(data->flags & SC_PIN_CMD_IMPLICIT_CHANGE) && data->pin1.offset) { modify->bInsertionOffsetOld = data->pin1.offset - 5; } else { modify->bInsertionOffsetOld = 0; } modify->bInsertionOffsetNew = data->pin2.offset ? data->pin2.offset - 5 : 0; modify->wPINMaxExtraDigit = wPINMaxExtraDigit; modify->bConfirmPIN = CCID_PIN_CONFIRM_NEW | (data->flags & SC_PIN_CMD_IMPLICIT_CHANGE ? 0 : CCID_PIN_INSERT_OLD); modify->bEntryValidationCondition = bEntryValidationCondition; modify->bNumberMessage = bNumberMessage; modify->wLangId = wLangId; modify->bMsgIndex1 = bMsgIndex; *((*pc_to_rdr_secure) + sizeof *secure + 1 + sizeof *modify + 0) = bTeoPrologue1; *((*pc_to_rdr_secure) + sizeof *secure + 1 + sizeof *modify + 1) = bTeoPrologue1; *((*pc_to_rdr_secure) + sizeof *secure + 1 + sizeof *modify + 2) = bTeoPrologue1; memcpy((*pc_to_rdr_secure) + sizeof *secure + 1 + sizeof *modify + 3, pinapdu, pinapdu_len); break; default: r = SC_ERROR_INVALID_ARGUMENTS; goto err; } r = SC_SUCCESS; err: free(pinapdu); if (r < 0 && pc_to_rdr_secure && *pc_to_rdr_secure) { free(*pc_to_rdr_secure); *pc_to_rdr_secure = NULL; } return r; } #define CCID_BSTATUS_OK_ACTIVE 0x00 /** No error. An ICC is present and active */ static int boxing_buf_to_verify_result(sc_context_t *ctx, const unsigned char *rdr_to_pc_datablock, size_t rdr_to_pc_datablock_len, sc_apdu_t *apdu) { RDR_to_PC_DataBlock_t *datablock = (RDR_to_PC_DataBlock_t *) rdr_to_pc_datablock; if (!rdr_to_pc_datablock || rdr_to_pc_datablock_len < sizeof *datablock || datablock->bMessageType != 0x80) return SC_ERROR_UNKNOWN_DATA_RECEIVED; if (datablock->bStatus != CCID_BSTATUS_OK_ACTIVE) return SC_ERROR_TRANSMIT_FAILED; return sc_apdu_set_resp(ctx, apdu, rdr_to_pc_datablock + sizeof *datablock, htole32(datablock->dwLength)); }
static int ctapi_transmit(sc_reader_t *reader, sc_apdu_t *apdu) { size_t ssize, rsize, rbuflen = 0; u8 *sbuf = NULL, *rbuf = NULL; int r; rsize = rbuflen = apdu->resplen + 2; rbuf = malloc(rbuflen); if (rbuf == NULL) { r = SC_ERROR_OUT_OF_MEMORY; goto out; } /* encode and log the APDU */ r = sc_apdu_get_octets(reader->ctx, apdu, &sbuf, &ssize, SC_PROTO_RAW); if (r != SC_SUCCESS) goto out; sc_apdu_log(reader->ctx, SC_LOG_DEBUG_NORMAL, sbuf, ssize, 1); r = ctapi_internal_transmit(reader, sbuf, ssize, rbuf, &rsize, apdu->control); if (r < 0) { /* unable to transmit ... most likely a reader problem */ sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "unable to transmit"); goto out; } sc_apdu_log(reader->ctx, SC_LOG_DEBUG_NORMAL, rbuf, rsize, 0); /* set response */ r = sc_apdu_set_resp(reader->ctx, apdu, rbuf, rsize); out: if (sbuf != NULL) { sc_mem_clear(sbuf, ssize); free(sbuf); } if (rbuf != NULL) { sc_mem_clear(rbuf, rbuflen); free(rbuf); } return r; }