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 entersafe_transmit_apdu(sc_card_t *card, sc_apdu_t *apdu, u8 * key, size_t keylen, int cipher,int mac) { u8 *cipher_data=0,*mac_data=0; size_t cipher_data_size,mac_data_size; int blocks; int r=SC_SUCCESS; SC_FUNC_CALLED(card->ctx, 1); assert(card); assert(apdu); if((cipher||mac) && (!key||(keylen!=8 && keylen!=16))) SC_FUNC_RETURN(card->ctx, 3, SC_ERROR_INVALID_ARGUMENTS); if (card->ctx->debug >= 6) { u8 *sbuf=NULL; size_t ssize=0; r = sc_apdu_get_octets(card->ctx, apdu, &sbuf, &ssize, SC_PROTO_RAW); if (r == SC_SUCCESS) sc_apdu_log(card->ctx, sbuf, ssize, 1); free(sbuf); } if(cipher) { blocks=(apdu->lc+2)/8+1; cipher_data_size=blocks*8; cipher_data=malloc(cipher_data_size); if(!cipher) { r = SC_ERROR_OUT_OF_MEMORY; goto out; } if((r = entersafe_cipher_apdu(card,apdu,key,keylen,cipher_data,cipher_data_size))<0) goto out; } if(mac) { mac_data_size=apdu->lc+4; mac_data=malloc(mac_data_size); r = entersafe_mac_apdu(card,apdu,key,keylen,mac_data,mac_data_size); if(r<0) goto out; } r = sc_transmit_apdu(card,apdu); out: if(cipher_data) free(cipher_data); if(mac_data) free(mac_data); SC_FUNC_RETURN(card->ctx, 3, 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; }
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; }