Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix receive buffer management in CCID_Receive for ICCD B #5

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Fix receive buffer management in CCID_Receive for ICCD B
  • Loading branch information
Mironenko committed May 21, 2015
commit e9ea9b5dd207305a75a97911503990007489441e
62 changes: 27 additions & 35 deletions src/commands.c
Original file line number Diff line number Diff line change
Expand Up @@ -1398,46 +1398,30 @@ RESPONSECODE CCID_Receive(unsigned int reader_index, unsigned int *rx_length,
if (PROTOCOL_ICCD_B == ccid_descriptor->bInterfaceProtocol)
{
int r;
unsigned char rx_tmp[4];
unsigned char *old_rx_buffer = NULL;
int old_rx_length = 0;

/* read a nul block. buffer need to be at least 4-bytes */
if (NULL == rx_buffer)
{
rx_buffer = rx_tmp;
*rx_length = sizeof(rx_tmp);
}
unsigned char *new_rx_buffer = NULL;
int new_rx_length = *rx_length + 1; /* DATA_BLOCK is length of data + 1 */

/* the buffer must be 4 bytes minimum for ICCD-B */
if (*rx_length < 4)
{
old_rx_buffer = rx_buffer;
old_rx_length = *rx_length;
rx_buffer = rx_tmp;
*rx_length = sizeof(rx_tmp);
}
if (new_rx_length < 4 || NULL == rx_buffer)
new_rx_length = 4;

if (NULL == (new_rx_buffer = malloc(new_rx_length)))
return IFD_COMMUNICATION_ERROR;

time_request_ICCD_B:
/* Data Block */
r = ControlUSB(reader_index, 0xA1, 0x6F, 0, rx_buffer, *rx_length);
r = ControlUSB(reader_index, 0xA1, 0x6F, 0, new_rx_buffer, new_rx_length);

/* we got an error? */
if (r < 0)
{
DEBUG_INFO2("ICC Data Block failed: %s", strerror(errno));
return IFD_COMMUNICATION_ERROR;
}

/* copy from the 4 bytes buffer if used */
if (old_rx_buffer)
{
memcpy(old_rx_buffer, rx_buffer, min(r, old_rx_length));
rx_buffer = old_rx_buffer;
return_value = IFD_COMMUNICATION_ERROR;
goto end_ICCD_B;
}

/* bResponseType */
switch (rx_buffer[0])
switch (new_rx_buffer[0])
{
case 0x00:
/* the abData field contains the information created by the
Expand All @@ -1446,15 +1430,16 @@ RESPONSECODE CCID_Receive(unsigned int reader_index, unsigned int *rx_length,

case 0x40:
/* Status Information */
ccid_error(PCSC_LOG_ERROR, rx_buffer[2], __FILE__, __LINE__, __FUNCTION__);
return IFD_COMMUNICATION_ERROR;
ccid_error(PCSC_LOG_ERROR, new_rx_buffer[2], __FILE__, __LINE__, __FUNCTION__);
return_value = IFD_COMMUNICATION_ERROR;
goto end_ICCD_B;

case 0x80:
/* Polling */
{
int delay;

delay = (rx_buffer[2] << 8) + rx_buffer[1];
delay = (new_rx_buffer[2] << 8) + new_rx_buffer[1];
DEBUG_COMM2("Pooling delay: %d", delay);

if (0 == delay)
Expand All @@ -1471,18 +1456,25 @@ RESPONSECODE CCID_Receive(unsigned int reader_index, unsigned int *rx_length,
/* Extended case
* Only valid for Data Block frames */
if (chain_parameter)
*chain_parameter = rx_buffer[0];
*chain_parameter = new_rx_buffer[0];
break;

default:
DEBUG_CRITICAL2("Unknown bResponseType: 0x%02X", rx_buffer[0]);
return IFD_COMMUNICATION_ERROR;
DEBUG_CRITICAL2("Unknown bResponseType: 0x%02X", new_rx_buffer[0]);
return_value = IFD_COMMUNICATION_ERROR;
goto end_ICCD_B;
}

memmove(rx_buffer, rx_buffer+1, r-1);
*rx_length = r-1;

return IFD_SUCCESS;
/* copy from the extended buffer if not read a nul block */
if (rx_buffer)
memcpy(rx_buffer, new_rx_buffer+1, min(*rx_length, new_rx_length - 1));

end_ICCD_B:
free(new_rx_buffer);

return return_value;
}
#endif

Expand Down