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;
}
Пример #3
0
            /* 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));
}
Пример #4
0
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;
}