diff --git a/src/libopensc/card-sc-hsm.c b/src/libopensc/card-sc-hsm.c index 8ac9b6fa..94482458 100644 --- a/src/libopensc/card-sc-hsm.c +++ b/src/libopensc/card-sc-hsm.c @@ -169,6 +169,8 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left) { sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data; + sc_apdu_t apdu; + u8 cmdbuff[16]; int r; if ((data->cmd == SC_PIN_CMD_VERIFY) && (data->pin_reference == 0x88)) { @@ -182,6 +184,24 @@ static int sc_hsm_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, LOG_FUNC_RETURN(card->ctx, SC_SUCCESS); } + if ((data->cmd == SC_PIN_CMD_CHANGE) && (data->pin_reference == 0x88)) { + if ((data->pin1.len != 16) || (data->pin2.len != 16)) + return SC_ERROR_INVALID_PIN_LENGTH; + + r = sc_hsm_encode_sopin(data->pin1.data, cmdbuff); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + + r = sc_hsm_encode_sopin(data->pin2.data, cmdbuff + 8); + LOG_TEST_RET(card->ctx, r, "APDU transmit failed"); + + sc_format_apdu(card, &apdu, SC_APDU_CASE_3_SHORT, 0x24, 0x00, data->pin_reference); + apdu.data = cmdbuff; + apdu.datalen = sizeof(cmdbuff); + apdu.lc = 16; + apdu.resplen = 0; + data->apdu = &apdu; + } + data->pin1.offset = 5; data->pin1.length_offset = 4; data->pin2.offset = 5; @@ -196,7 +216,7 @@ static int sc_hsm_logout(sc_card_t * card) { sc_path_t path; sc_hsm_private_data_t *priv = (sc_hsm_private_data_t *) card->drv_data; - memset(priv->sopin, sizeof(priv->sopin), 0); + memset(priv->sopin, 0, sizeof(priv->sopin)); sc_path_set(&path, SC_PATH_TYPE_DF_NAME, sc_hsm_aid.value, sc_hsm_aid.len, 0, 0);