110
ccid/src/ccid.c
110
ccid/src/ccid.c
@@ -36,6 +36,53 @@
|
||||
#include <npa/boxing.h>
|
||||
#include <npa/iso-sm.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
|
||||
int sm_stop(struct sc_card *card) { return SC_SUCCESS; }
|
||||
#endif
|
||||
@@ -47,10 +94,6 @@ perform_PC_to_RDR_IccPowerOn(const __u8 *in, size_t inlen, __u8 **out, size_t *o
|
||||
static int
|
||||
perform_PC_to_RDR_IccPowerOff(const __u8 *in, size_t inlen, __u8 **out, size_t *outlen);
|
||||
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);
|
||||
static int
|
||||
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) {
|
||||
#ifdef WITH_PACE
|
||||
#ifndef DISABLE_GLOBAL_BOXING_INITIALIZATION
|
||||
sc_initialize_boxing_cmds(ctx);
|
||||
#endif
|
||||
#endif
|
||||
return get_RDR_to_PC_SlotStatus(request->bSeq,
|
||||
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_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)
|
||||
static int
|
||||
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;
|
||||
case 0x01:
|
||||
/* GetReaderPACECapabilities */
|
||||
#ifdef WITH_PACE
|
||||
LOG_TEST_RET(ctx,
|
||||
perform_pseudo_apdu_GetReaderPACECapabilities(apdu),
|
||||
"Could not get reader's PACE Capabilities");
|
||||
apdu->sw1 = iso_sw_ok.sw1;
|
||||
apdu->sw2 = iso_sw_ok.sw2;
|
||||
#else
|
||||
apdu->sw1 = 0x6D;
|
||||
apdu->sw2 = 0x00;
|
||||
#endif
|
||||
break;
|
||||
case 0x02:
|
||||
/* EstablishPACEChannel */
|
||||
#ifdef WITH_PACE
|
||||
LOG_TEST_RET(ctx,
|
||||
perform_pseudo_apdu_EstablishPACEChannel(apdu),
|
||||
"Could not perform PACE");
|
||||
apdu->sw1 = iso_sw_ok.sw1;
|
||||
apdu->sw2 = iso_sw_ok.sw2;
|
||||
#else
|
||||
apdu->sw1 = 0x6D;
|
||||
apdu->sw2 = 0x00;
|
||||
#endif
|
||||
break;
|
||||
case 0x03:
|
||||
/* DestroyPACEChannel */
|
||||
|
||||
@@ -222,13 +222,16 @@ int write_binary_rec(sc_card_t *card, unsigned char sfid,
|
||||
int r;
|
||||
size_t write = MAX_SM_APDU_DATA_SIZE, wrote = 0;
|
||||
sc_apdu_t apdu;
|
||||
#ifdef ENABLE_SM
|
||||
struct iso_sm_ctx *iso_sm_ctx = card->sm_ctx.info.cmd_data;
|
||||
#endif
|
||||
|
||||
if (!card) {
|
||||
r = SC_ERROR_INVALID_ARGUMENTS;
|
||||
goto err;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SM
|
||||
if (write > SC_MAX_APDU_BUFFER_SIZE-2
|
||||
|| (card->sm_ctx.sm_mode == SM_MODE_TRANSMIT
|
||||
&& 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,
|
||||
ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0);
|
||||
else
|
||||
#endif
|
||||
sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT,
|
||||
ISO_WRITE_BINARY, ISO_P1_FLAG_SFID|sfid, 0);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user