110
ccid/src/ccid.c
110
ccid/src/ccid.c
@@ -36,6 +36,53 @@
|
|||||||
#include <npa/boxing.h>
|
#include <npa/boxing.h>
|
||||||
#include <npa/iso-sm.h>
|
#include <npa/iso-sm.h>
|
||||||
#include <npa/npa.h>
|
#include <npa/npa.h>
|
||||||
|
|
||||||
|
static int
|
||||||
|
perform_pseudo_apdu_EstablishPACEChannel(sc_apdu_t *apdu)
|
||||||
|
{
|
||||||
|
struct establish_pace_channel_input pace_input;
|
||||||
|
struct establish_pace_channel_output pace_output;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
memset(&pace_input, 0, sizeof pace_input);
|
||||||
|
memset(&pace_output, 0, sizeof pace_output);
|
||||||
|
|
||||||
|
r = boxing_buf_to_pace_input(reader->ctx, apdu->data, apdu->datalen,
|
||||||
|
&pace_input);
|
||||||
|
if (r < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
r = perform_pace(card, pace_input, &pace_output,
|
||||||
|
EAC_TR_VERSION_2_02);
|
||||||
|
if (r < 0)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
r = boxing_pace_output_to_buf(reader->ctx, &pace_output, &apdu->resp,
|
||||||
|
&apdu->resplen);
|
||||||
|
|
||||||
|
err:
|
||||||
|
free((unsigned char *) pace_input.chat);
|
||||||
|
free((unsigned char *) pace_input.certificate_description);
|
||||||
|
free((unsigned char *) pace_input.pin);
|
||||||
|
free(pace_output.ef_cardaccess);
|
||||||
|
free(pace_output.recent_car);
|
||||||
|
free(pace_output.previous_car);
|
||||||
|
free(pace_output.id_icc);
|
||||||
|
free(pace_output.id_pcd);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
perform_pseudo_apdu_GetReaderPACECapabilities(sc_apdu_t *apdu)
|
||||||
|
{
|
||||||
|
unsigned long sc_reader_t_capabilities = SC_READER_CAP_PACE_GENERIC
|
||||||
|
| SC_READER_CAP_PACE_EID | SC_READER_CAP_PACE_ESIGN;
|
||||||
|
|
||||||
|
|
||||||
|
return boxing_pace_capabilities_to_buf(reader->ctx,
|
||||||
|
sc_reader_t_capabilities, &apdu->resp, &apdu->resplen);
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
int sm_stop(struct sc_card *card) { return SC_SUCCESS; }
|
int sm_stop(struct sc_card *card) { return SC_SUCCESS; }
|
||||||
#endif
|
#endif
|
||||||
@@ -47,10 +94,6 @@ perform_PC_to_RDR_IccPowerOn(const __u8 *in, size_t inlen, __u8 **out, size_t *o
|
|||||||
static int
|
static int
|
||||||
perform_PC_to_RDR_IccPowerOff(const __u8 *in, size_t inlen, __u8 **out, size_t *outlen);
|
perform_PC_to_RDR_IccPowerOff(const __u8 *in, size_t inlen, __u8 **out, size_t *outlen);
|
||||||
static int
|
static int
|
||||||
perform_pseudo_apdu_EstablishPACEChannel(sc_apdu_t *apdu);
|
|
||||||
static int
|
|
||||||
perform_pseudo_apdu_GetReaderPACECapabilities(sc_apdu_t *apdu);
|
|
||||||
static int
|
|
||||||
perform_pseudo_apdu(sc_reader_t *reader, sc_apdu_t *apdu);
|
perform_pseudo_apdu(sc_reader_t *reader, sc_apdu_t *apdu);
|
||||||
static int
|
static int
|
||||||
perform_PC_to_RDR_XfrBlock(const u8 *in, size_t inlen, __u8** out, size_t *outlen);
|
perform_PC_to_RDR_XfrBlock(const u8 *in, size_t inlen, __u8** out, size_t *outlen);
|
||||||
@@ -424,8 +467,10 @@ perform_PC_to_RDR_IccPowerOn(const __u8 *in, size_t inlen, __u8 **out, size_t *o
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sc_result >= 0) {
|
if (sc_result >= 0) {
|
||||||
|
#ifdef WITH_PACE
|
||||||
#ifndef DISABLE_GLOBAL_BOXING_INITIALIZATION
|
#ifndef DISABLE_GLOBAL_BOXING_INITIALIZATION
|
||||||
sc_initialize_boxing_cmds(ctx);
|
sc_initialize_boxing_cmds(ctx);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
return get_RDR_to_PC_SlotStatus(request->bSeq,
|
return get_RDR_to_PC_SlotStatus(request->bSeq,
|
||||||
sc_result, out, outlen, card->atr.value, card->atr.len);
|
sc_result, out, outlen, card->atr.value, card->atr.len);
|
||||||
@@ -473,53 +518,6 @@ static const struct sw iso_sw_inconsistent_data = {0x6A, 0x87};
|
|||||||
static const struct sw iso_sw_func_not_supported = {0x6A, 0x81};
|
static const struct sw iso_sw_func_not_supported = {0x6A, 0x81};
|
||||||
static const struct sw iso_sw_ins_not_supported = {0x6D, 0x00};
|
static const struct sw iso_sw_ins_not_supported = {0x6D, 0x00};
|
||||||
|
|
||||||
static int
|
|
||||||
perform_pseudo_apdu_EstablishPACEChannel(sc_apdu_t *apdu)
|
|
||||||
{
|
|
||||||
struct establish_pace_channel_input pace_input;
|
|
||||||
struct establish_pace_channel_output pace_output;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
memset(&pace_input, 0, sizeof pace_input);
|
|
||||||
memset(&pace_output, 0, sizeof pace_output);
|
|
||||||
|
|
||||||
r = boxing_buf_to_pace_input(reader->ctx, apdu->data, apdu->datalen,
|
|
||||||
&pace_input);
|
|
||||||
if (r < 0)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
r = perform_pace(card, pace_input, &pace_output,
|
|
||||||
EAC_TR_VERSION_2_02);
|
|
||||||
if (r < 0)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
r = boxing_pace_output_to_buf(reader->ctx, &pace_output, &apdu->resp,
|
|
||||||
&apdu->resplen);
|
|
||||||
|
|
||||||
err:
|
|
||||||
free((unsigned char *) pace_input.chat);
|
|
||||||
free((unsigned char *) pace_input.certificate_description);
|
|
||||||
free((unsigned char *) pace_input.pin);
|
|
||||||
free(pace_output.ef_cardaccess);
|
|
||||||
free(pace_output.recent_car);
|
|
||||||
free(pace_output.previous_car);
|
|
||||||
free(pace_output.id_icc);
|
|
||||||
free(pace_output.id_pcd);
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
perform_pseudo_apdu_GetReaderPACECapabilities(sc_apdu_t *apdu)
|
|
||||||
{
|
|
||||||
unsigned long sc_reader_t_capabilities = SC_READER_CAP_PACE_GENERIC
|
|
||||||
| SC_READER_CAP_PACE_EID | SC_READER_CAP_PACE_ESIGN;
|
|
||||||
|
|
||||||
|
|
||||||
return boxing_pace_capabilities_to_buf(reader->ctx,
|
|
||||||
sc_reader_t_capabilities, &apdu->resp, &apdu->resplen);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define min(a,b) (a<b?a:b)
|
#define min(a,b) (a<b?a:b)
|
||||||
static int
|
static int
|
||||||
perform_pseudo_apdu(sc_reader_t *reader, sc_apdu_t *apdu)
|
perform_pseudo_apdu(sc_reader_t *reader, sc_apdu_t *apdu)
|
||||||
@@ -581,19 +579,29 @@ perform_pseudo_apdu(sc_reader_t *reader, sc_apdu_t *apdu)
|
|||||||
break;
|
break;
|
||||||
case 0x01:
|
case 0x01:
|
||||||
/* GetReaderPACECapabilities */
|
/* GetReaderPACECapabilities */
|
||||||
|
#ifdef WITH_PACE
|
||||||
LOG_TEST_RET(ctx,
|
LOG_TEST_RET(ctx,
|
||||||
perform_pseudo_apdu_GetReaderPACECapabilities(apdu),
|
perform_pseudo_apdu_GetReaderPACECapabilities(apdu),
|
||||||
"Could not get reader's PACE Capabilities");
|
"Could not get reader's PACE Capabilities");
|
||||||
apdu->sw1 = iso_sw_ok.sw1;
|
apdu->sw1 = iso_sw_ok.sw1;
|
||||||
apdu->sw2 = iso_sw_ok.sw2;
|
apdu->sw2 = iso_sw_ok.sw2;
|
||||||
|
#else
|
||||||
|
apdu->sw1 = 0x6D;
|
||||||
|
apdu->sw2 = 0x00;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case 0x02:
|
case 0x02:
|
||||||
/* EstablishPACEChannel */
|
/* EstablishPACEChannel */
|
||||||
|
#ifdef WITH_PACE
|
||||||
LOG_TEST_RET(ctx,
|
LOG_TEST_RET(ctx,
|
||||||
perform_pseudo_apdu_EstablishPACEChannel(apdu),
|
perform_pseudo_apdu_EstablishPACEChannel(apdu),
|
||||||
"Could not perform PACE");
|
"Could not perform PACE");
|
||||||
apdu->sw1 = iso_sw_ok.sw1;
|
apdu->sw1 = iso_sw_ok.sw1;
|
||||||
apdu->sw2 = iso_sw_ok.sw2;
|
apdu->sw2 = iso_sw_ok.sw2;
|
||||||
|
#else
|
||||||
|
apdu->sw1 = 0x6D;
|
||||||
|
apdu->sw2 = 0x00;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case 0x03:
|
case 0x03:
|
||||||
/* DestroyPACEChannel */
|
/* DestroyPACEChannel */
|
||||||
|
|||||||
@@ -222,13 +222,16 @@ int write_binary_rec(sc_card_t *card, unsigned char sfid,
|
|||||||
int r;
|
int r;
|
||||||
size_t write = MAX_SM_APDU_DATA_SIZE, wrote = 0;
|
size_t write = MAX_SM_APDU_DATA_SIZE, wrote = 0;
|
||||||
sc_apdu_t apdu;
|
sc_apdu_t apdu;
|
||||||
|
#ifdef ENABLE_SM
|
||||||
struct iso_sm_ctx *iso_sm_ctx = card->sm_ctx.info.cmd_data;
|
struct iso_sm_ctx *iso_sm_ctx = card->sm_ctx.info.cmd_data;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!card) {
|
if (!card) {
|
||||||
r = SC_ERROR_INVALID_ARGUMENTS;
|
r = SC_ERROR_INVALID_ARGUMENTS;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SM
|
||||||
if (write > SC_MAX_APDU_BUFFER_SIZE-2
|
if (write > SC_MAX_APDU_BUFFER_SIZE-2
|
||||||
|| (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT
|
|| (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT
|
||||||
&& write > (((SC_MAX_APDU_BUFFER_SIZE-2
|
&& write > (((SC_MAX_APDU_BUFFER_SIZE-2
|
||||||
@@ -241,6 +244,7 @@ int write_binary_rec(sc_card_t *card, unsigned char sfid,
|
|||||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_EXT,
|
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_EXT,
|
||||||
ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0);
|
ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0);
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT,
|
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT,
|
||||||
ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0);
|
ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user