Skip to content

Commit bacab1a

Browse files
committed
Check if PIN is locked and hint CKF_USER_PIN_TO_BE_CHANGED
Signed-off-by: Raul Metsma <raul@metsma.ee>
1 parent 22484d9 commit bacab1a

4 files changed

Lines changed: 20 additions & 16 deletions

File tree

src/libopensc/card-esteid2025.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,9 @@ esteid_compute_signature(sc_card_t *card, const u8 *data, size_t datalen, u8 *ou
157157
}
158158

159159
static int
160-
esteid_get_pin_remaining_tries(sc_card_t *card, int pin_reference)
160+
esteid_get_pin_info(sc_card_t *card, struct sc_pin_cmd_data *data)
161161
{
162-
const u8 get_pin_info[] = {0xA0, 0x03, 0x83, 0x01, pin_reference};
162+
const u8 get_pin_info[] = {0xA0, 0x03, 0x83, 0x01, data->pin_reference};
163163
struct sc_apdu apdu;
164164
u8 apdu_resp[SC_MAX_APDU_RESP_SIZE];
165165
size_t taglen;
@@ -173,26 +173,26 @@ esteid_get_pin_remaining_tries(sc_card_t *card, int pin_reference)
173173
const u8 *tag = sc_asn1_find_tag(card->ctx, apdu_resp + 2, apdu.resplen - 2, 0xDF21, &taglen);
174174
if (tag == NULL || taglen == 0)
175175
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INTERNAL);
176-
return tag[0];
176+
data->pin1.tries_left = tag[0];
177+
data->pin1.max_tries = -1; // "no support, which means the one set in PKCS#15 emulation sticks
178+
data->pin1.logged_in = SC_PIN_STATE_UNKNOWN;
179+
tag += taglen;
180+
tag = sc_asn1_find_tag(card->ctx, tag, apdu.resplen - (tag - apdu_resp), 0xDF2F, &taglen);
181+
if (tag != NULL && taglen == 1 && tag[0] == 0x00) {
182+
data->pin1.logged_in |= SC_PIN_STATE_NEEDS_CHANGE;
183+
}
184+
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
177185
}
178186

179187
static int
180188
esteid_pin_cmd(sc_card_t *card, struct sc_pin_cmd_data *data, int *tries_left)
181189
{
182-
int r;
183190
LOG_FUNC_CALLED(card->ctx);
184191
sc_log(card->ctx, "PIN CMD is %d", data->cmd);
185192
if (data->cmd == SC_PIN_CMD_GET_INFO) {
186193
sc_log(card->ctx, "SC_PIN_CMD_GET_INFO for %d", data->pin_reference);
187-
r = esteid_get_pin_remaining_tries(card, data->pin_reference);
188-
LOG_TEST_RET(card->ctx, r, "GET DATA(pin info) failed");
189-
190-
data->pin1.tries_left = r;
191-
data->pin1.max_tries = -1; // "no support, which means the one set in PKCS#15 emulation sticks
192-
data->pin1.logged_in = SC_PIN_STATE_UNKNOWN;
193-
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
194+
LOG_FUNC_RETURN(card->ctx, esteid_get_pin_info(card, data));
194195
}
195-
196196
LOG_FUNC_RETURN(card->ctx, iso_ops->pin_cmd(card, data, tries_left));
197197
}
198198

src/libopensc/opensc.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -433,10 +433,11 @@ typedef struct sc_reader {
433433
#define SC_PIN_ENCODING_BCD 1
434434
#define SC_PIN_ENCODING_GLP 2 /* Global Platform - Card Specification v2.0.1 */
435435

436-
/** Values for sc_pin_cmd_pin.logged_in */
436+
/** Values for sc_pin_cmd_pin.logged_in, can be ored together */
437437
#define SC_PIN_STATE_UNKNOWN -1
438438
#define SC_PIN_STATE_LOGGED_OUT 0
439439
#define SC_PIN_STATE_LOGGED_IN 1
440+
#define SC_PIN_STATE_NEEDS_CHANGE 2
440441

441442
/* A card driver receives the sc_pin_cmd_data and sc_pin_cmd_pin structures filled in by the
442443
* caller, with the exception of the fields returned by the driver for SC_PIN_CMD_GET_INFO.

src/pkcs11/framework-pkcs15.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
575575
goto out;
576576
}
577577
/* User PIN flags are cleared before re-calculation */
578-
slot->token_info.flags &= ~(CKF_USER_PIN_COUNT_LOW|CKF_USER_PIN_FINAL_TRY|CKF_USER_PIN_LOCKED);
578+
slot->token_info.flags &= ~(CKF_USER_PIN_COUNT_LOW | CKF_USER_PIN_FINAL_TRY | CKF_USER_PIN_LOCKED | CKF_USER_PIN_TO_BE_CHANGED);
579579
auth = slot_data_auth(slot->fw_data);
580580
sc_log(context,
581581
"C_GetTokenInfo() auth. object %p, token-info flags 0x%lX", auth,
@@ -602,6 +602,9 @@ CK_RV C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo)
602602
else if (pin_info->max_tries > 1 && pin_info->tries_left < pin_info->max_tries)
603603
slot->token_info.flags |= CKF_USER_PIN_COUNT_LOW;
604604
}
605+
if (pin_info->logged_in & SC_PIN_STATE_NEEDS_CHANGE) {
606+
slot->token_info.flags |= CKF_USER_PIN_TO_BE_CHANGED;
607+
}
605608
}
606609
memcpy(pInfo, &slot->token_info, sizeof(CK_TOKEN_INFO));
607610

@@ -1401,7 +1404,7 @@ int slot_get_logged_in_state(struct sc_pkcs11_slot *slot)
14011404
if (!pin_info)
14021405
goto out;
14031406
sc_pkcs15_get_pin_info(p15card, pin_obj);
1404-
logged_in = pin_info->logged_in;
1407+
logged_in = pin_info->logged_in & ~SC_PIN_STATE_NEEDS_CHANGE;
14051408
out:
14061409
return logged_in;
14071410
}

src/pkcs15init/pkcs15-lib.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4026,7 +4026,7 @@ sc_pkcs15init_verify_secret(struct sc_profile *profile, struct sc_pkcs15_card *p
40264026
/* update local copy of auth info */
40274027
memcpy(&auth_info, pin_obj->data, sizeof(auth_info));
40284028

4029-
if (r == SC_SUCCESS && auth_info.logged_in == SC_PIN_STATE_LOGGED_IN)
4029+
if (r == SC_SUCCESS && auth_info.logged_in & SC_PIN_STATE_LOGGED_IN)
40304030
LOG_FUNC_RETURN(ctx, r);
40314031
}
40324032

0 commit comments

Comments
 (0)