Fix #223: implement ctbcs_build_modify_verification_apdu.

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@4396 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
martin 2010-06-01 12:28:30 +00:00
parent 6f52711280
commit 073ad7a4c4
1 changed files with 68 additions and 2 deletions

View File

@ -150,8 +150,70 @@ ctbcs_build_perform_verification_apdu(sc_apdu_t *apdu, struct sc_pin_cmd_data *d
static int
ctbcs_build_modify_verification_apdu(sc_apdu_t *apdu, struct sc_pin_cmd_data *data)
{
/* to be implemented */
return SC_ERROR_NOT_IMPLEMENTED;
const char *prompt;
size_t buflen, count = 0, j = 0, len;
static u8 buf[254];
u8 control;
ctbcs_init_apdu(apdu,
SC_APDU_CASE_3_SHORT,
CTBCS_INS_MODIFY_VERIFICATION,
CTBCS_P1_INTERFACE1,
0);
buflen = sizeof(buf);
prompt = data->pin1.prompt;
if (prompt && *prompt) {
len = strlen(prompt);
if (count + len + 2 > buflen || len > 255)
return SC_ERROR_BUFFER_TOO_SMALL;
buf[count++] = CTBCS_TAG_PROMPT;
buf[count++] = len;
memcpy(buf + count, prompt, len);
count += len;
}
/* card apdu must be last in packet */
if (!data->apdu)
return SC_ERROR_INTERNAL;
if (count + 8 > buflen)
return SC_ERROR_BUFFER_TOO_SMALL;
j = count;
buf[j++] = CTBCS_TAG_VERIFY_CMD;
buf[j++] = 0x00;
/* Control byte - length of PIN, and encoding */
control = 0x00;
if (data->pin1.encoding == SC_PIN_ENCODING_ASCII)
control |= CTBCS_PIN_CONTROL_ENCODE_ASCII;
else if (data->pin1.encoding != SC_PIN_ENCODING_BCD)
return SC_ERROR_INVALID_ARGUMENTS;
if (data->pin1.min_length == data->pin1.max_length)
control |= data->pin1.min_length << CTBCS_PIN_CONTROL_LEN_SHIFT;
buf[j++] = control;
buf[j++] = data->pin1.offset+1; /* Looks like offset is 1-based in CTBCS */
buf[j++] = data->pin2.offset+1;
buf[j++] = data->apdu->cla;
buf[j++] = data->apdu->ins;
buf[j++] = data->apdu->p1;
buf[j++] = data->apdu->p2;
if (data->flags & SC_PIN_CMD_NEED_PADDING) {
len = data->pin1.pad_length + data->pin2.pad_length;
if (j + len > buflen || len > 256)
return SC_ERROR_BUFFER_TOO_SMALL;
buf[j++] = len;
memset(buf+j, data->pin1.pad_char, len);
j += len;
}
buf[count+1] = j - count - 2;
count = j;
apdu->lc = apdu->datalen = count;
apdu->data = buf;
return 0;
}
int
@ -165,10 +227,14 @@ ctbcs_pin_cmd(sc_reader_t *reader, struct sc_pin_cmd_data *data)
switch (data->cmd) {
case SC_PIN_CMD_VERIFY:
r = ctbcs_build_perform_verification_apdu(&apdu, data);
if (r != SC_SUCCESS)
return r;
break;
case SC_PIN_CMD_CHANGE:
case SC_PIN_CMD_UNBLOCK:
r = ctbcs_build_modify_verification_apdu(&apdu, data);
if (r != SC_SUCCESS)
return r;
break;
default:
sc_debug(reader->ctx, SC_LOG_DEBUG_NORMAL, "Unknown PIN command %d", data->cmd);