- made debugging of openssl errors human readable
- removed debugging of return values, added human readable messages instead git-svn-id: https://vsmartcard.svn.sourceforge.net/svnroot/vsmartcard@161 96b47cad-a561-4643-ad3b-153ac7d7599c
This commit is contained in:
@@ -97,7 +97,7 @@ detect_card_presence(int slot)
|
|||||||
int sc_result;
|
int sc_result;
|
||||||
|
|
||||||
if (slot >= sizeof *card_in_slot)
|
if (slot >= sizeof *card_in_slot)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
if (card_in_slot[slot] && sc_card_valid(card_in_slot[slot])) {
|
if (card_in_slot[slot] && sc_card_valid(card_in_slot[slot])) {
|
||||||
sc_result = SC_SLOT_CARD_PRESENT;
|
sc_result = SC_SLOT_CARD_PRESENT;
|
||||||
@@ -121,7 +121,7 @@ detect_card_presence(int slot)
|
|||||||
sc_debug(ctx, "Unused card in slot %d", slot);
|
sc_debug(ctx, "Unused card in slot %d", slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_VERBOSE, sc_result);
|
return sc_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -190,7 +190,8 @@ static int get_rapdu(sc_apdu_t *apdu, size_t slot, __u8 **buf, size_t *resplen)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apdu->sw1 > 0xff || apdu->sw2 > 0xff) {
|
if (apdu->sw1 > 0xff || apdu->sw2 > 0xff || apdu->sw1 < 0 || apdu->sw2 < 0) {
|
||||||
|
sc_error(ctx, "Received invalid status bytes SW1=%d SW2=%d", apdu->sw1, apdu->sw2);
|
||||||
sc_result = SC_ERROR_INVALID_DATA;
|
sc_result = SC_ERROR_INVALID_DATA;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -208,7 +209,7 @@ static int get_rapdu(sc_apdu_t *apdu, size_t slot, __u8 **buf, size_t *resplen)
|
|||||||
sc_result = SC_SUCCESS;
|
sc_result = SC_SUCCESS;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_VERBOSE, sc_result);
|
return sc_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __u8 get_bError(int sc_result)
|
static __u8 get_bError(int sc_result)
|
||||||
@@ -290,11 +291,11 @@ static int
|
|||||||
get_RDR_to_PC_SlotStatus(__u8 bSlot, __u8 bSeq, int sc_result, RDR_to_PC_SlotStatus_t **out)
|
get_RDR_to_PC_SlotStatus(__u8 bSlot, __u8 bSeq, int sc_result, RDR_to_PC_SlotStatus_t **out)
|
||||||
{
|
{
|
||||||
if (!out)
|
if (!out)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_ARGUMENTS);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
RDR_to_PC_SlotStatus_t *result = realloc(*out, sizeof *result);
|
RDR_to_PC_SlotStatus_t *result = realloc(*out, sizeof *result);
|
||||||
if (!result)
|
if (!result)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_OUT_OF_MEMORY);
|
return SC_ERROR_OUT_OF_MEMORY;
|
||||||
*out = result;
|
*out = result;
|
||||||
|
|
||||||
result->bMessageType = 0x81;
|
result->bMessageType = 0x81;
|
||||||
@@ -305,18 +306,18 @@ get_RDR_to_PC_SlotStatus(__u8 bSlot, __u8 bSeq, int sc_result, RDR_to_PC_SlotSta
|
|||||||
result->bError = get_bError(sc_result);
|
result->bError = get_bError(sc_result);
|
||||||
result->bClockStatus = 0;
|
result->bClockStatus = 0;
|
||||||
|
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS);
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
get_RDR_to_PC_DataBlock(__u8 bSlot, __u8 bSeq, int sc_result, RDR_to_PC_DataBlock_t **out)
|
get_RDR_to_PC_DataBlock(__u8 bSlot, __u8 bSeq, int sc_result, RDR_to_PC_DataBlock_t **out)
|
||||||
{
|
{
|
||||||
if (!out)
|
if (!out)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_ARGUMENTS);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
RDR_to_PC_DataBlock_t *result = realloc(*out, sizeof *result);
|
RDR_to_PC_DataBlock_t *result = realloc(*out, sizeof *result);
|
||||||
if (!result)
|
if (!result)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_OUT_OF_MEMORY);
|
return SC_ERROR_OUT_OF_MEMORY;
|
||||||
*out = result;
|
*out = result;
|
||||||
|
|
||||||
result->bMessageType = 0x80;
|
result->bMessageType = 0x80;
|
||||||
@@ -327,7 +328,7 @@ get_RDR_to_PC_DataBlock(__u8 bSlot, __u8 bSeq, int sc_result, RDR_to_PC_DataBloc
|
|||||||
result->bError = get_bError(sc_result);
|
result->bError = get_bError(sc_result);
|
||||||
result->bChainParameter = 0;
|
result->bChainParameter = 0;
|
||||||
|
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS);
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -336,7 +337,7 @@ perform_PC_to_RDR_GetSlotStatus(const __u8 *in, size_t inlen, __u8 **out, size_t
|
|||||||
const PC_to_RDR_GetSlotStatus_t *request = (PC_to_RDR_GetSlotStatus_t *) in;
|
const PC_to_RDR_GetSlotStatus_t *request = (PC_to_RDR_GetSlotStatus_t *) in;
|
||||||
|
|
||||||
if (!out || !outlen || !in)
|
if (!out || !outlen || !in)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_ARGUMENTS);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
if (inlen < sizeof *request)
|
if (inlen < sizeof *request)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_DATA);
|
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_DATA);
|
||||||
@@ -349,9 +350,8 @@ perform_PC_to_RDR_GetSlotStatus(const __u8 *in, size_t inlen, __u8 **out, size_t
|
|||||||
request->abRFU2 != 0)
|
request->abRFU2 != 0)
|
||||||
sc_debug(ctx, "warning: malformed PC_to_RDR_GetSlotStatus");
|
sc_debug(ctx, "warning: malformed PC_to_RDR_GetSlotStatus");
|
||||||
|
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR,
|
return get_RDR_to_PC_SlotStatus(request->bSlot, request->bSeq, SC_SUCCESS,
|
||||||
get_RDR_to_PC_SlotStatus(request->bSlot, request->bSeq, SC_SUCCESS,
|
(RDR_to_PC_SlotStatus_t **) out);
|
||||||
(RDR_to_PC_SlotStatus_t **) out));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -362,7 +362,7 @@ perform_PC_to_RDR_IccPowerOn(const __u8 *in, size_t inlen, __u8 **out, size_t *o
|
|||||||
RDR_to_PC_SlotStatus_t *result;
|
RDR_to_PC_SlotStatus_t *result;
|
||||||
|
|
||||||
if (!out || !outlen || !in)
|
if (!out || !outlen || !in)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_ARGUMENTS);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
if (inlen < sizeof *request)
|
if (inlen < sizeof *request)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_DATA);
|
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_DATA);
|
||||||
@@ -412,7 +412,7 @@ perform_PC_to_RDR_IccPowerOn(const __u8 *in, size_t inlen, __u8 **out, size_t *o
|
|||||||
*outlen = sizeof *result;
|
*outlen = sizeof *result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_SUCCESS);
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -422,7 +422,7 @@ perform_PC_to_RDR_IccPowerOff(const __u8 *in, size_t inlen, __u8 **out, size_t *
|
|||||||
int sc_result;
|
int sc_result;
|
||||||
|
|
||||||
if (!in || !out || !outlen)
|
if (!in || !out || !outlen)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_ARGUMENTS);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
if (inlen < sizeof *request)
|
if (inlen < sizeof *request)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_DATA);
|
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_DATA);
|
||||||
@@ -445,7 +445,7 @@ perform_PC_to_RDR_IccPowerOff(const __u8 *in, size_t inlen, __u8 **out, size_t *
|
|||||||
|
|
||||||
*outlen = sizeof(RDR_to_PC_SlotStatus_t);
|
*outlen = sizeof(RDR_to_PC_SlotStatus_t);
|
||||||
|
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_SUCCESS);
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -460,7 +460,7 @@ perform_PC_to_RDR_XfrBlock(const u8 *in, size_t inlen, __u8** out, size_t *outle
|
|||||||
RDR_to_PC_DataBlock_t *result;
|
RDR_to_PC_DataBlock_t *result;
|
||||||
|
|
||||||
if (!in || !out || !outlen)
|
if (!in || !out || !outlen)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_ARGUMENTS);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
if (inlen < sizeof *request)
|
if (inlen < sizeof *request)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_DATA);
|
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_DATA);
|
||||||
@@ -483,7 +483,7 @@ perform_PC_to_RDR_XfrBlock(const u8 *in, size_t inlen, __u8** out, size_t *outle
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (sc_result >= 0)
|
if (sc_result >= 0)
|
||||||
free(abDataOut);
|
free(abDataOut);
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc_result >= 0) {
|
if (sc_result >= 0) {
|
||||||
@@ -507,7 +507,7 @@ perform_PC_to_RDR_XfrBlock(const u8 *in, size_t inlen, __u8** out, size_t *outle
|
|||||||
result->bError = get_bError(sc_result);
|
result->bError = get_bError(sc_result);
|
||||||
result->bStatus = get_bStatus(sc_result, request->bSlot);
|
result->bStatus = get_bStatus(sc_result, request->bSlot);
|
||||||
|
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_SUCCESS);
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -520,7 +520,7 @@ perform_PC_to_RDR_GetParamters(const __u8 *in, size_t inlen, __u8** out, size_t
|
|||||||
int sc_result;
|
int sc_result;
|
||||||
|
|
||||||
if (!in || !out || !outlen)
|
if (!in || !out || !outlen)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_ARGUMENTS);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
if (inlen < sizeof *request)
|
if (inlen < sizeof *request)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_DATA);
|
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_DATA);
|
||||||
@@ -534,7 +534,7 @@ perform_PC_to_RDR_GetParamters(const __u8 *in, size_t inlen, __u8** out, size_t
|
|||||||
case SC_PROTO_T0:
|
case SC_PROTO_T0:
|
||||||
result = realloc(*out, sizeof *result + sizeof *t0);
|
result = realloc(*out, sizeof *result + sizeof *t0);
|
||||||
if (!result)
|
if (!result)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_OUT_OF_MEMORY);
|
return SC_ERROR_OUT_OF_MEMORY;
|
||||||
*out = (__u8 *) result;
|
*out = (__u8 *) result;
|
||||||
|
|
||||||
result->bProtocolNum = 0;
|
result->bProtocolNum = 0;
|
||||||
@@ -557,7 +557,7 @@ perform_PC_to_RDR_GetParamters(const __u8 *in, size_t inlen, __u8** out, size_t
|
|||||||
case SC_PROTO_T1:
|
case SC_PROTO_T1:
|
||||||
result = realloc(*out, sizeof *result + sizeof *t1);
|
result = realloc(*out, sizeof *result + sizeof *t1);
|
||||||
if (!result)
|
if (!result)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_OUT_OF_MEMORY);
|
return SC_ERROR_OUT_OF_MEMORY;
|
||||||
*out = (__u8 *) result;
|
*out = (__u8 *) result;
|
||||||
|
|
||||||
result->bProtocolNum = 1;
|
result->bProtocolNum = 1;
|
||||||
@@ -591,7 +591,7 @@ perform_PC_to_RDR_GetParamters(const __u8 *in, size_t inlen, __u8** out, size_t
|
|||||||
invaliddata:
|
invaliddata:
|
||||||
result = realloc(*out, sizeof *result);
|
result = realloc(*out, sizeof *result);
|
||||||
if (!result)
|
if (!result)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_OUT_OF_MEMORY);
|
return SC_ERROR_OUT_OF_MEMORY;
|
||||||
*out = (__u8 *) result;
|
*out = (__u8 *) result;
|
||||||
|
|
||||||
sc_result = SC_ERROR_INVALID_DATA;
|
sc_result = SC_ERROR_INVALID_DATA;
|
||||||
@@ -606,7 +606,7 @@ invaliddata:
|
|||||||
if (sc_result < 0)
|
if (sc_result < 0)
|
||||||
debug_sc_result(sc_result);
|
debug_sc_result(sc_result);
|
||||||
|
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_SUCCESS);
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -647,7 +647,9 @@ write_pin_length(sc_apdu_t *apdu, const struct sc_pin_cmd_pin *pin,
|
|||||||
|
|
||||||
if (length_size) {
|
if (length_size) {
|
||||||
if (length_size != 8) {
|
if (length_size != 8) {
|
||||||
/* only write pin length if it fits into a full byte */
|
sc_error(ctx, "Writing PIN length only if it fits into "
|
||||||
|
"a full byte (length of PIN size was %u bits)",
|
||||||
|
length_size);
|
||||||
*sc_result = SC_ERROR_NOT_SUPPORTED;
|
*sc_result = SC_ERROR_NOT_SUPPORTED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -723,6 +725,7 @@ encode_pin(u8 *buf, size_t buf_len, struct sc_pin_cmd_pin *pin,
|
|||||||
else if (encoding == CCID_PIN_ENCODING_ASCII)
|
else if (encoding == CCID_PIN_ENCODING_ASCII)
|
||||||
pin->encoding = SC_PIN_ENCODING_ASCII;
|
pin->encoding = SC_PIN_ENCODING_ASCII;
|
||||||
else {
|
else {
|
||||||
|
sc_error(ctx, "PIN encoding not supported (0x%02x)", encoding);
|
||||||
*sc_result = SC_ERROR_NOT_SUPPORTED;
|
*sc_result = SC_ERROR_NOT_SUPPORTED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -752,7 +755,9 @@ write_pin(sc_apdu_t *apdu, struct sc_pin_cmd_pin *pin, uint8_t blocksize,
|
|||||||
if (justify_right) {
|
if (justify_right) {
|
||||||
if (encoding == CCID_PIN_ENCODING_BCD) {
|
if (encoding == CCID_PIN_ENCODING_BCD) {
|
||||||
if (pin->len % 2) {
|
if (pin->len % 2) {
|
||||||
/* only do right aligned BCD which fits into full bytes */
|
sc_error(ctx, "Right aligning BCD encoded PIN only if it fits "
|
||||||
|
"into a full byte (length of encoded PIN was %u bits)",
|
||||||
|
(pin->len)*4);
|
||||||
*sc_result = SC_ERROR_NOT_SUPPORTED;
|
*sc_result = SC_ERROR_NOT_SUPPORTED;
|
||||||
return 0;
|
return 0;
|
||||||
} else
|
} else
|
||||||
@@ -782,7 +787,7 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle
|
|||||||
RDR_to_PC_DataBlock_t *result;
|
RDR_to_PC_DataBlock_t *result;
|
||||||
|
|
||||||
if (!in || !out || !outlen)
|
if (!in || !out || !outlen)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_ARGUMENTS);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
if (inlen < sizeof *request + 1)
|
if (inlen < sizeof *request + 1)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_DATA);
|
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_DATA);
|
||||||
@@ -794,11 +799,14 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle
|
|||||||
memset(&curr_pin, 0, sizeof(curr_pin));
|
memset(&curr_pin, 0, sizeof(curr_pin));
|
||||||
memset(&new_pin, 0, sizeof(new_pin));
|
memset(&new_pin, 0, sizeof(new_pin));
|
||||||
|
|
||||||
if (request->bSlot > sizeof *card_in_slot)
|
if (request->bSlot > sizeof *card_in_slot) {
|
||||||
|
sc_error(ctx, "Received request to invalid slot (bSlot=0x%02x)", request->bSlot);
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
if (request->wLevelParameter != CCID_WLEVEL_DIRECT) {
|
if (request->wLevelParameter != CCID_WLEVEL_DIRECT) {
|
||||||
sc_error(ctx, "Chained security commands not supported.");
|
sc_error(ctx, "Received request with unsupported wLevelParameter (0x%04x)",
|
||||||
|
__le16_to_cpu(request->wLevelParameter));
|
||||||
sc_result = SC_ERROR_NOT_SUPPORTED;
|
sc_result = SC_ERROR_NOT_SUPPORTED;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -878,7 +886,7 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle
|
|||||||
case 0x04:
|
case 0x04:
|
||||||
// Cancel PIN function
|
// Cancel PIN function
|
||||||
default:
|
default:
|
||||||
sc_error(ctx, "PIN operation not supported (bPINOperation=%02x).",
|
sc_error(ctx, "Received request with unsupported PIN operation (bPINOperation=0x%02x)",
|
||||||
*abData);
|
*abData);
|
||||||
sc_result = SC_ERROR_NOT_SUPPORTED;
|
sc_result = SC_ERROR_NOT_SUPPORTED;
|
||||||
goto err;
|
goto err;
|
||||||
@@ -959,12 +967,14 @@ perform_PC_to_RDR_Secure(const __u8 *in, size_t inlen, __u8** out, size_t *outle
|
|||||||
if ((curr_pin.max_length && curr_pin.len > curr_pin.max_length)
|
if ((curr_pin.max_length && curr_pin.len > curr_pin.max_length)
|
||||||
|| curr_pin.len < curr_pin.min_length) {
|
|| curr_pin.len < curr_pin.min_length) {
|
||||||
sc_result = SC_ERROR_PIN_CODE_INCORRECT;
|
sc_result = SC_ERROR_PIN_CODE_INCORRECT;
|
||||||
|
sc_error(ctx, "PIN request required a longer or shorter PIN");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (modify) {
|
if (modify) {
|
||||||
new_pin.len = strlen((char *) new_pin.data);
|
new_pin.len = strlen((char *) new_pin.data);
|
||||||
if ((new_pin.max_length && new_pin.len > new_pin.max_length)
|
if ((new_pin.max_length && new_pin.len > new_pin.max_length)
|
||||||
|| new_pin.len < new_pin.min_length) {
|
|| new_pin.len < new_pin.min_length) {
|
||||||
|
sc_error(ctx, "PIN request required a longer or shorter PIN");
|
||||||
sc_result = SC_ERROR_PIN_CODE_INCORRECT;
|
sc_result = SC_ERROR_PIN_CODE_INCORRECT;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -1013,7 +1023,7 @@ err:
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
if (sc_result >= 0)
|
if (sc_result >= 0)
|
||||||
free(abDataOut);
|
free(abDataOut);
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc_result >= 0) {
|
if (sc_result >= 0) {
|
||||||
@@ -1037,7 +1047,7 @@ err:
|
|||||||
result->bError = get_bError(sc_result);
|
result->bError = get_bError(sc_result);
|
||||||
result->bStatus = get_bStatus(sc_result, request->bSlot);
|
result->bStatus = get_bStatus(sc_result, request->bSlot);
|
||||||
|
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -1059,11 +1069,11 @@ get_RDR_to_PC_NotifySlotChange(RDR_to_PC_NotifySlotChange_t **out)
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (!out)
|
if (!out)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_ARGUMENTS);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
RDR_to_PC_NotifySlotChange_t *result = realloc(*out, sizeof *result);
|
RDR_to_PC_NotifySlotChange_t *result = realloc(*out, sizeof *result);
|
||||||
if (!result)
|
if (!result)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_OUT_OF_MEMORY);
|
return SC_ERROR_OUT_OF_MEMORY;
|
||||||
*out = result;
|
*out = result;
|
||||||
|
|
||||||
result->bMessageType = 0x50;
|
result->bMessageType = 0x50;
|
||||||
@@ -1085,7 +1095,7 @@ get_RDR_to_PC_NotifySlotChange(RDR_to_PC_NotifySlotChange_t **out)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS);
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -1095,14 +1105,14 @@ perform_unknown(const __u8 *in, size_t inlen, __u8 **out, size_t *outlen)
|
|||||||
RDR_to_PC_SlotStatus_t *result;
|
RDR_to_PC_SlotStatus_t *result;
|
||||||
|
|
||||||
if (!in || !out || !outlen)
|
if (!in || !out || !outlen)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_ARGUMENTS);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
if (inlen < sizeof *request)
|
if (inlen < sizeof *request)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_DATA);
|
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_INVALID_DATA);
|
||||||
|
|
||||||
result = realloc(*out, sizeof *result);
|
result = realloc(*out, sizeof *result);
|
||||||
if (!result)
|
if (!result)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_ERROR_OUT_OF_MEMORY);
|
return SC_ERROR_OUT_OF_MEMORY;
|
||||||
*out = (__u8 *) result;
|
*out = (__u8 *) result;
|
||||||
|
|
||||||
switch (request->bMessageType) {
|
switch (request->bMessageType) {
|
||||||
@@ -1146,7 +1156,7 @@ perform_unknown(const __u8 *in, size_t inlen, __u8 **out, size_t *outlen)
|
|||||||
|
|
||||||
*outlen = sizeof *result;
|
*outlen = sizeof *result;
|
||||||
|
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_ERROR, SC_SUCCESS);
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ccid_parse_bulkin(const __u8* inbuf, size_t inlen, __u8** outbuf)
|
int ccid_parse_bulkin(const __u8* inbuf, size_t inlen, __u8** outbuf)
|
||||||
|
|||||||
@@ -163,15 +163,11 @@ const size_t maxresp = SC_MAX_APDU_BUFFER_SIZE - 2;
|
|||||||
int GetReadersPACECapabilities(sc_card_t *card,
|
int GetReadersPACECapabilities(sc_card_t *card,
|
||||||
const __u8 *in, size_t inlen, __u8 **out, size_t *outlen) {
|
const __u8 *in, size_t inlen, __u8 **out, size_t *outlen) {
|
||||||
if (!out || !outlen)
|
if (!out || !outlen)
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_ARGUMENTS);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
__u8 *result = realloc(*out, 2);
|
__u8 *result = realloc(*out, 2);
|
||||||
if (!result) {
|
if (!result)
|
||||||
if (card)
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_OUT_OF_MEMORY);
|
|
||||||
else
|
|
||||||
return SC_ERROR_OUT_OF_MEMORY;
|
return SC_ERROR_OUT_OF_MEMORY;
|
||||||
}
|
|
||||||
*out = result;
|
*out = result;
|
||||||
*outlen = 2;
|
*outlen = 2;
|
||||||
|
|
||||||
@@ -181,9 +177,6 @@ int GetReadersPACECapabilities(sc_card_t *card,
|
|||||||
/* BitMap */
|
/* BitMap */
|
||||||
*result = PACE_BITMAP_PACE|PACE_BITMAP_EID;
|
*result = PACE_BITMAP_PACE|PACE_BITMAP_EID;
|
||||||
|
|
||||||
if (card)
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_SUCCESS);
|
|
||||||
else
|
|
||||||
return SC_SUCCESS;
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,6 +238,8 @@ static int get_ef_card_access(sc_card_t *card,
|
|||||||
/* test cards only return an empty FCI template,
|
/* test cards only return an empty FCI template,
|
||||||
* so we can't determine any file proberties */
|
* so we can't determine any file proberties */
|
||||||
if (*length_ef_cardaccess < file->size) {
|
if (*length_ef_cardaccess < file->size) {
|
||||||
|
sc_error(card->ctx, "Actual filesize differs from the size in file "
|
||||||
|
"proberties (%u!=%u).", *length_ef_cardaccess, file->size);
|
||||||
r = SC_ERROR_FILE_TOO_SMALL;
|
r = SC_ERROR_FILE_TOO_SMALL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -256,7 +251,7 @@ err:
|
|||||||
free(file);
|
free(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pace_mse_set_at(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
static int pace_mse_set_at(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||||
@@ -305,7 +300,7 @@ static int pace_mse_set_at(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
|||||||
if (length_chat) {
|
if (length_chat) {
|
||||||
if (!d2i_PACE_CHAT(&data->cha_template, (const unsigned char **) &chat,
|
if (!d2i_PACE_CHAT(&data->cha_template, (const unsigned char **) &chat,
|
||||||
length_chat)) {
|
length_chat)) {
|
||||||
sc_error(card->ctx, "Error decoding card holder authorization template (CHAT)");
|
sc_error(card->ctx, "Could not parse card holder authorization template (CHAT).");
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -335,7 +330,8 @@ static int pace_mse_set_at(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
|||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
if (apdu.resplen) {
|
if (apdu.resplen) {
|
||||||
sc_error(card->ctx, "MSE:Set AT response data should be empty");
|
sc_error(card->ctx, "MSE:Set AT response data should be empty "
|
||||||
|
"(contains %u bytes)", apdu.resplen);
|
||||||
r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
r = SC_ERROR_UNKNOWN_DATA_RECEIVED;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -383,7 +379,7 @@ err:
|
|||||||
if (d)
|
if (d)
|
||||||
free(d);
|
free(d);
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pace_gen_auth(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
static int pace_gen_auth(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||||
@@ -586,7 +582,7 @@ err:
|
|||||||
/*if (apdu.resp)*/
|
/*if (apdu.resp)*/
|
||||||
/*free(apdu.resp);*/
|
/*free(apdu.resp);*/
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -610,7 +606,7 @@ pace_reset_retry_counter(struct sm_ctx *ctx, sc_card_t *card,
|
|||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
sc_error(card->ctx, "Could not read new %s (%s).\n",
|
sc_error(card->ctx, "Could not read new %s (%s).\n",
|
||||||
hints.obj_label, sc_strerror(r));
|
hints.obj_label, sc_strerror(r));
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r);
|
return r;
|
||||||
}
|
}
|
||||||
new_len = strlen(p);
|
new_len = strlen(p);
|
||||||
new = p;
|
new = p;
|
||||||
@@ -639,7 +635,7 @@ pace_reset_retry_counter(struct sm_ctx *ctx, sc_card_t *card,
|
|||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PACE_SEC *
|
static PACE_SEC *
|
||||||
@@ -677,11 +673,13 @@ get_psec(sc_card_t *card, const char *pin, size_t length_pin, enum s_type pin_id
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void debug_ossl(sc_context_t *ctx) {
|
void ssl_error(sc_context_t *ctx) {
|
||||||
unsigned long r;
|
unsigned long r;
|
||||||
|
ERR_load_crypto_strings();
|
||||||
for (r = ERR_get_error(); r; r = ERR_get_error()) {
|
for (r = ERR_get_error(); r; r = ERR_get_error()) {
|
||||||
sc_error(ctx, ERR_error_string(r, NULL));
|
sc_error(ctx, ERR_error_string(r, NULL));
|
||||||
}
|
}
|
||||||
|
ERR_free_strings();
|
||||||
}
|
}
|
||||||
|
|
||||||
int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
||||||
@@ -704,7 +702,7 @@ int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
|||||||
if (!card)
|
if (!card)
|
||||||
return SC_ERROR_CARD_NOT_PRESENT;
|
return SC_ERROR_CARD_NOT_PRESENT;
|
||||||
if (!in || !out || !outlen)
|
if (!in || !out || !outlen)
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, SC_ERROR_INVALID_ARGUMENTS);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
if (inlen < 1) {
|
if (inlen < 1) {
|
||||||
sc_error(card->ctx, "Buffer too small, could not get PinID");
|
sc_error(card->ctx, "Buffer too small, could not get PinID");
|
||||||
@@ -786,9 +784,9 @@ int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
|||||||
|
|
||||||
if (!parse_ef_card_access(ef_cardaccess, length_ef_cardaccess,
|
if (!parse_ef_card_access(ef_cardaccess, length_ef_cardaccess,
|
||||||
&info, &static_dp)) {
|
&info, &static_dp)) {
|
||||||
r = SC_ERROR_INTERNAL;
|
|
||||||
debug_ossl(card->ctx);
|
|
||||||
sc_error(card->ctx, "Could not parse EF.CardAccess.");
|
sc_error(card->ctx, "Could not parse EF.CardAccess.");
|
||||||
|
ssl_error(card->ctx);
|
||||||
|
r = SC_ERROR_INTERNAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -801,7 +799,6 @@ int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
|||||||
enc_nonce = BUF_MEM_new();
|
enc_nonce = BUF_MEM_new();
|
||||||
if (!enc_nonce) {
|
if (!enc_nonce) {
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
debug_ossl(card->ctx);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
r = pace_gen_auth(oldpacectx, card, 1, NULL, 0, (u8 **) &enc_nonce->data,
|
r = pace_gen_auth(oldpacectx, card, 1, NULL, 0, (u8 **) &enc_nonce->data,
|
||||||
@@ -817,14 +814,14 @@ int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
|||||||
|
|
||||||
sec = get_psec(card, (char *) pin, length_pin, pin_id);
|
sec = get_psec(card, (char *) pin, length_pin, pin_id);
|
||||||
if (!sec) {
|
if (!sec) {
|
||||||
|
sc_error(card->ctx, "Could not encode PACE secret.");
|
||||||
|
ssl_error(card->ctx);
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
debug_ossl(card->ctx);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
pctx = PACE_CTX_new();
|
pctx = PACE_CTX_new();
|
||||||
if (!pctx || !PACE_CTX_init(pctx, info)) {
|
if (!pctx || !PACE_CTX_init(pctx, info)) {
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
debug_ossl(card->ctx);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
pctx->tr_version = PACE_TR_VERSION_2_01;
|
pctx->tr_version = PACE_TR_VERSION_2_01;
|
||||||
@@ -834,8 +831,9 @@ int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
|||||||
mdata_opp = BUF_MEM_new();
|
mdata_opp = BUF_MEM_new();
|
||||||
mdata = PACE_STEP3A_generate_mapping_data(static_dp, pctx);
|
mdata = PACE_STEP3A_generate_mapping_data(static_dp, pctx);
|
||||||
if (!nonce || !mdata || !mdata_opp) {
|
if (!nonce || !mdata || !mdata_opp) {
|
||||||
|
sc_error(card->ctx, "Could not generate mapping data.");
|
||||||
|
ssl_error(card->ctx);
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
debug_ossl(card->ctx);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
r = pace_gen_auth(oldpacectx, card, 2, (u8 *) mdata->data, mdata->length,
|
r = pace_gen_auth(oldpacectx, card, 2, (u8 *) mdata->data, mdata->length,
|
||||||
@@ -853,8 +851,10 @@ int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
|||||||
pub = PACE_STEP3B_generate_ephemeral_key(eph_dp, pctx);
|
pub = PACE_STEP3B_generate_ephemeral_key(eph_dp, pctx);
|
||||||
pub_opp = BUF_MEM_new();
|
pub_opp = BUF_MEM_new();
|
||||||
if (!eph_dp || !pub || !pub_opp) {
|
if (!eph_dp || !pub || !pub_opp) {
|
||||||
|
sc_error(card->ctx, "Could not generate ephemeral domain parameter or "
|
||||||
|
"ephemeral key pair.");
|
||||||
|
ssl_error(card->ctx);
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
debug_ossl(card->ctx);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
r = pace_gen_auth(oldpacectx, card, 3, (u8 *) pub->data, pub->length,
|
r = pace_gen_auth(oldpacectx, card, 3, (u8 *) pub->data, pub->length,
|
||||||
@@ -871,16 +871,19 @@ int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
|||||||
key = PACE_STEP3B_compute_ephemeral_key(eph_dp, pctx, pub_opp);
|
key = PACE_STEP3B_compute_ephemeral_key(eph_dp, pctx, pub_opp);
|
||||||
if (!key ||
|
if (!key ||
|
||||||
!PACE_STEP3C_derive_keys(key, pctx, info, &k_mac, &k_enc)) {
|
!PACE_STEP3C_derive_keys(key, pctx, info, &k_mac, &k_enc)) {
|
||||||
|
sc_error(card->ctx, "Could not compute ephemeral shared secret or "
|
||||||
|
"derive keys for encryption and authentication.");
|
||||||
|
ssl_error(card->ctx);
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
debug_ossl(card->ctx);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
token = PACE_STEP3D_compute_authentication_token(pctx,
|
token = PACE_STEP3D_compute_authentication_token(pctx,
|
||||||
eph_dp, info, pub_opp, k_mac);
|
eph_dp, info, pub_opp, k_mac);
|
||||||
token_opp = BUF_MEM_new();
|
token_opp = BUF_MEM_new();
|
||||||
if (!token || !token_opp) {
|
if (!token || !token_opp) {
|
||||||
|
sc_error(card->ctx, "Could not compute authentication token.");
|
||||||
|
ssl_error(card->ctx);
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
debug_ossl(card->ctx);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
r = pace_gen_auth(oldpacectx, card, 4, (u8 *) token->data, token->length,
|
r = pace_gen_auth(oldpacectx, card, 4, (u8 *) token->data, token->length,
|
||||||
@@ -894,8 +897,9 @@ int EstablishPACEChannel(const struct sm_ctx *oldpacectx, sc_card_t *card,
|
|||||||
|
|
||||||
if (!PACE_STEP3D_verify_authentication_token(pctx,
|
if (!PACE_STEP3D_verify_authentication_token(pctx,
|
||||||
eph_dp, info, k_mac, token_opp)) {
|
eph_dp, info, k_mac, token_opp)) {
|
||||||
|
sc_error(card->ctx, "Could not verify authentication token.");
|
||||||
|
ssl_error(card->ctx);
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
debug_ossl(card->ctx);
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -970,7 +974,7 @@ err:
|
|||||||
pace_sm_ctx_free(sctx->authentication_ctx);
|
pace_sm_ctx_free(sctx->authentication_ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *MRZ_name = "MRZ";
|
static const char *MRZ_name = "MRZ";
|
||||||
@@ -1042,11 +1046,8 @@ int pace_sm_encrypt(sc_card_t *card, const struct sm_ctx *ctx,
|
|||||||
databuf = BUF_MEM_create_init(data, datalen);
|
databuf = BUF_MEM_create_init(data, datalen);
|
||||||
encbuf = PACE_encrypt(psmctx->ctx, psmctx->ssc, psmctx->key_enc, databuf);
|
encbuf = PACE_encrypt(psmctx->ctx, psmctx->ssc, psmctx->key_enc, databuf);
|
||||||
if (!databuf || !encbuf) {
|
if (!databuf || !encbuf) {
|
||||||
r = SC_ERROR_INTERNAL;
|
sc_error(card->ctx, "Could not encrypt data.");
|
||||||
goto err;
|
ssl_error(card->ctx);
|
||||||
}
|
|
||||||
|
|
||||||
if (!encbuf) {
|
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -1068,7 +1069,7 @@ err:
|
|||||||
if (encbuf)
|
if (encbuf)
|
||||||
BUF_MEM_free(encbuf);
|
BUF_MEM_free(encbuf);
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pace_sm_decrypt(sc_card_t *card, const struct sm_ctx *ctx,
|
int pace_sm_decrypt(sc_card_t *card, const struct sm_ctx *ctx,
|
||||||
@@ -1087,6 +1088,8 @@ int pace_sm_decrypt(sc_card_t *card, const struct sm_ctx *ctx,
|
|||||||
encbuf = BUF_MEM_create_init(enc, enclen);
|
encbuf = BUF_MEM_create_init(enc, enclen);
|
||||||
databuf = PACE_decrypt(psmctx->ctx, psmctx->ssc, psmctx->key_enc, encbuf);
|
databuf = PACE_decrypt(psmctx->ctx, psmctx->ssc, psmctx->key_enc, encbuf);
|
||||||
if (!encbuf || !databuf) {
|
if (!encbuf || !databuf) {
|
||||||
|
sc_error(card->ctx, "Could not decrypt data.");
|
||||||
|
ssl_error(card->ctx);
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -1108,7 +1111,7 @@ err:
|
|||||||
if (encbuf)
|
if (encbuf)
|
||||||
BUF_MEM_free(encbuf);
|
BUF_MEM_free(encbuf);
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pace_sm_authenticate(sc_card_t *card, const struct sm_ctx *ctx,
|
int pace_sm_authenticate(sc_card_t *card, const struct sm_ctx *ctx,
|
||||||
@@ -1127,7 +1130,9 @@ int pace_sm_authenticate(sc_card_t *card, const struct sm_ctx *ctx,
|
|||||||
macbuf = PACE_authenticate(psmctx->ctx, psmctx->ssc, psmctx->key_mac,
|
macbuf = PACE_authenticate(psmctx->ctx, psmctx->ssc, psmctx->key_mac,
|
||||||
data, datalen);
|
data, datalen);
|
||||||
if (!macbuf) {
|
if (!macbuf) {
|
||||||
sc_error(card->ctx, "Could not get MAC\n");
|
sc_error(card->ctx, "Could not compute message authentication code "
|
||||||
|
"(MAC).");
|
||||||
|
ssl_error(card->ctx);
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -1147,7 +1152,7 @@ err:
|
|||||||
if (ssc)
|
if (ssc)
|
||||||
free(ssc);
|
free(ssc);
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pace_sm_verify_authentication(sc_card_t *card, const struct sm_ctx *ctx,
|
int pace_sm_verify_authentication(sc_card_t *card, const struct sm_ctx *ctx,
|
||||||
@@ -1167,6 +1172,9 @@ int pace_sm_verify_authentication(sc_card_t *card, const struct sm_ctx *ctx,
|
|||||||
my_mac = PACE_authenticate(psmctx->ctx, psmctx->ssc, psmctx->key_mac,
|
my_mac = PACE_authenticate(psmctx->ctx, psmctx->ssc, psmctx->key_mac,
|
||||||
macdata, macdatalen);
|
macdata, macdatalen);
|
||||||
if (!my_mac) {
|
if (!my_mac) {
|
||||||
|
sc_error(card->ctx, "Could not compute message authentication code "
|
||||||
|
"(MAC) for verification.");
|
||||||
|
ssl_error(card->ctx);
|
||||||
r = SC_ERROR_INTERNAL;
|
r = SC_ERROR_INTERNAL;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@@ -1187,7 +1195,7 @@ err:
|
|||||||
if (my_mac)
|
if (my_mac)
|
||||||
BUF_MEM_free(my_mac);
|
BUF_MEM_free(my_mac);
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pace_sm_pre_transmit(sc_card_t *card, const struct sm_ctx *ctx,
|
int pace_sm_pre_transmit(sc_card_t *card, const struct sm_ctx *ctx,
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ int initialize(int reader_id, const char *cdriver, int verbose,
|
|||||||
reader_count = sc_ctx_get_reader_count(*ctx);
|
reader_count = sc_ctx_get_reader_count(*ctx);
|
||||||
|
|
||||||
if (reader_count == 0)
|
if (reader_count == 0)
|
||||||
SC_FUNC_RETURN((*ctx), SC_LOG_TYPE_ERROR, SC_ERROR_NO_READERS_FOUND);
|
return SC_ERROR_NO_READERS_FOUND;
|
||||||
|
|
||||||
if (reader_id < 0) {
|
if (reader_id < 0) {
|
||||||
/* Automatically try to skip to a reader with a card if reader not specified */
|
/* Automatically try to skip to a reader with a card if reader not specified */
|
||||||
@@ -67,11 +67,11 @@ int initialize(int reader_id, const char *cdriver, int verbose,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (reader_id >= reader_count)
|
if (reader_id >= reader_count)
|
||||||
SC_FUNC_RETURN((*ctx), SC_LOG_TYPE_ERROR, SC_ERROR_NO_READERS_FOUND);
|
return SC_ERROR_NO_READERS_FOUND;
|
||||||
|
|
||||||
*reader = sc_ctx_get_reader(*ctx, reader_id);
|
*reader = sc_ctx_get_reader(*ctx, reader_id);
|
||||||
|
|
||||||
SC_FUNC_RETURN((*ctx), SC_LOG_TYPE_ERROR, SC_SUCCESS);
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -81,12 +81,12 @@ int build_apdu(sc_context_t *ctx, const u8 *buf, size_t len, sc_apdu_t *apdu)
|
|||||||
size_t len0;
|
size_t len0;
|
||||||
|
|
||||||
if (!buf || !apdu)
|
if (!buf || !apdu)
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_VERBOSE, SC_ERROR_INVALID_ARGUMENTS);
|
return SC_ERROR_INVALID_ARGUMENTS;
|
||||||
|
|
||||||
len0 = len;
|
len0 = len;
|
||||||
if (len < 4) {
|
if (len < 4) {
|
||||||
sc_error(ctx, "APDU too short (must be at least 4 bytes)");
|
sc_error(ctx, "APDU too short (must be at least 4 bytes)");
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_VERBOSE, SC_ERROR_INVALID_DATA);
|
return SC_ERROR_INVALID_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(apdu, 0, sizeof(*apdu));
|
memset(apdu, 0, sizeof(*apdu));
|
||||||
@@ -104,7 +104,7 @@ int build_apdu(sc_context_t *ctx, const u8 *buf, size_t len, sc_apdu_t *apdu)
|
|||||||
if (len < apdu->lc) {
|
if (len < apdu->lc) {
|
||||||
sc_error(ctx, "APDU too short (need %lu bytes)\n",
|
sc_error(ctx, "APDU too short (need %lu bytes)\n",
|
||||||
(unsigned long) apdu->lc - len);
|
(unsigned long) apdu->lc - len);
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_VERBOSE, SC_ERROR_INVALID_DATA);
|
return SC_ERROR_INVALID_DATA;
|
||||||
}
|
}
|
||||||
len -= apdu->lc;
|
len -= apdu->lc;
|
||||||
p += apdu->lc;
|
p += apdu->lc;
|
||||||
@@ -120,7 +120,7 @@ int build_apdu(sc_context_t *ctx, const u8 *buf, size_t len, sc_apdu_t *apdu)
|
|||||||
if (len) {
|
if (len) {
|
||||||
sc_error(ctx, "APDU too long (%lu bytes extra)\n",
|
sc_error(ctx, "APDU too long (%lu bytes extra)\n",
|
||||||
(unsigned long) len);
|
(unsigned long) len);
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_VERBOSE, SC_ERROR_INVALID_DATA);
|
return SC_ERROR_INVALID_DATA;
|
||||||
}
|
}
|
||||||
} else if (len == 1) {
|
} else if (len == 1) {
|
||||||
apdu->le = *p++;
|
apdu->le = *p++;
|
||||||
@@ -137,7 +137,7 @@ int build_apdu(sc_context_t *ctx, const u8 *buf, size_t len, sc_apdu_t *apdu)
|
|||||||
sc_debug(ctx, "APDU, %d bytes:\tins=%02x p1=%02x p2=%02x",
|
sc_debug(ctx, "APDU, %d bytes:\tins=%02x p1=%02x p2=%02x",
|
||||||
(unsigned int) len0, apdu->ins, apdu->p1, apdu->p2);
|
(unsigned int) len0, apdu->ins, apdu->p1, apdu->p2);
|
||||||
|
|
||||||
SC_FUNC_RETURN(ctx, SC_LOG_TYPE_VERBOSE, SC_SUCCESS);
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _bin_log(sc_context_t *ctx, int type, const char *file, int line,
|
void _bin_log(sc_context_t *ctx, int type, const char *file, int line,
|
||||||
|
|||||||
@@ -191,8 +191,11 @@ static int format_data(sc_card_t *card, const struct sm_ctx *ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
r = add_padding(ctx, data, datalen, &pad_data);
|
r = add_padding(ctx, data, datalen, &pad_data);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
|
sc_error(card->ctx, "Could not add padding to data: %s",
|
||||||
|
sc_strerror(r));
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
pad_data_len = r;
|
pad_data_len = r;
|
||||||
|
|
||||||
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
if (card->ctx->debug > SC_LOG_TYPE_DEBUG)
|
||||||
@@ -206,8 +209,11 @@ static int format_data(sc_card_t *card, const struct sm_ctx *ctx,
|
|||||||
bin_log(card->ctx, "Cryptogram", *formatted_data, r);
|
bin_log(card->ctx, "Cryptogram", *formatted_data, r);
|
||||||
|
|
||||||
r = prefix_buf(ctx->padding_indicator, *formatted_data, r, formatted_data);
|
r = prefix_buf(ctx->padding_indicator, *formatted_data, r, formatted_data);
|
||||||
if (r < 0)
|
if (r < 0) {
|
||||||
|
sc_error(card->ctx, "Could not prepend padding indicator to formatted "
|
||||||
|
"data: %s", sc_strerror(r));
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
*formatted_data_len = r;
|
*formatted_data_len = r;
|
||||||
sc_format_asn1_entry(formatted_encrypted_data_entry,
|
sc_format_asn1_entry(formatted_encrypted_data_entry,
|
||||||
@@ -221,7 +227,7 @@ err:
|
|||||||
free(pad_data);
|
free(pad_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int format_head(const struct sm_ctx *ctx, const sc_apdu_t *apdu,
|
static int format_head(const struct sm_ctx *ctx, const sc_apdu_t *apdu,
|
||||||
@@ -450,7 +456,7 @@ err:
|
|||||||
if (sm_data)
|
if (sm_data)
|
||||||
free(sm_data);
|
free(sm_data);
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sm_decrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
static int sm_decrypt(const struct sm_ctx *ctx, sc_card_t *card,
|
||||||
@@ -564,7 +570,7 @@ err:
|
|||||||
free(mac_data);
|
free(mac_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, r);
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sm_transmit_apdu(const struct sm_ctx *sctx, sc_card_t *card,
|
int sm_transmit_apdu(const struct sm_ctx *sctx, sc_card_t *card,
|
||||||
@@ -580,12 +586,12 @@ int sm_transmit_apdu(const struct sm_ctx *sctx, sc_card_t *card,
|
|||||||
|
|
||||||
if ((apdu->cla & 0x0C) == 0x0C) {
|
if ((apdu->cla & 0x0C) == 0x0C) {
|
||||||
sc_debug(card->ctx, "Given APDU is already protected with some secure messaging.");
|
sc_debug(card->ctx, "Given APDU is already protected with some secure messaging.");
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, sc_transmit_apdu(card, apdu));
|
return sc_transmit_apdu(card, apdu);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sctx || !sctx->active) {
|
if (!sctx || !sctx->active) {
|
||||||
sc_debug(card->ctx, "Secure messaging disabled.");
|
sc_debug(card->ctx, "Secure messaging disabled.");
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_DEBUG, sc_transmit_apdu(card, apdu));
|
return sc_transmit_apdu(card, apdu);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sctx->pre_transmit)
|
if (sctx->pre_transmit)
|
||||||
@@ -601,5 +607,5 @@ int sm_transmit_apdu(const struct sm_ctx *sctx, sc_card_t *card,
|
|||||||
SC_TEST_RET(card->ctx, sm_decrypt(sctx, card, &sm_apdu, apdu),
|
SC_TEST_RET(card->ctx, sm_decrypt(sctx, card, &sm_apdu, apdu),
|
||||||
"Could not decrypt APDU");
|
"Could not decrypt APDU");
|
||||||
|
|
||||||
SC_FUNC_RETURN(card->ctx, SC_LOG_TYPE_ERROR, SC_SUCCESS);
|
return SC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user