From f740d8db6c1df2bedb50c12494a87477b83ea5e0 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 24 Oct 2024 11:21:59 -0400 Subject: [PATCH] Add code to prevent locking the token by mistake For tokens that properly report the status of the PIN authentication counter via token flags, check them out and refuse to attempt login if the token is on its last try. A token should never be on its last try and finding this flags set is an indication that someone may have hardocded an in correct pin in the configuration or an URI. Proceeding would have a high chance of ending up blocking the token. Fixes: #455 Signed-off-by: Simo Sorce --- src/session.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/session.c b/src/session.c index 42cbaab7..69c3a1f3 100644 --- a/src/session.c +++ b/src/session.c @@ -439,6 +439,35 @@ static int p11prov_session_prompt_for_pin(struct p11prov_slot *slot, return ret; } +static CK_RV check_pin_flags_ok(P11PROV_CTX *ctx, CK_SLOT_ID slotid) +{ + CK_TOKEN_INFO token; + CK_RV ret; + + ret = p11prov_GetTokenInfo(ctx, slotid, &token); + if (ret != CKR_OK) { + return ret; + } + + if (token.flags & CKF_USER_PIN_FINAL_TRY) { + ret = CKR_CANCEL; + P11PROV_raise(ctx, ret, + "Only one auth attempt left on token. " + "Canceling login attempt to avoid locking the token. " + "Manual user login required to reset counter."); + } else if (token.flags & CKF_USER_PIN_LOCKED) { + ret = CKR_PIN_LOCKED; + P11PROV_raise(ctx, ret, "PIN marked as locked, canceling login"); + } else if (token.flags & CKF_USER_PIN_TO_BE_CHANGED) { + ret = CKR_PIN_EXPIRED; + P11PROV_raise(ctx, ret, "PIN marked as expired, canceling login"); + } else { + ret = CKR_OK; + } + + return ret; +} + /* returns a locked login_session if _session is not NULL */ static CK_RV token_login(P11PROV_SESSION *session, P11PROV_URI *uri, OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg, @@ -522,6 +551,11 @@ static CK_RV token_login(P11PROV_SESSION *session, P11PROV_URI *uri, } } + ret = check_pin_flags_ok(session->provctx, session->slotid); + if (ret != CKR_OK) { + goto done; + } + P11PROV_debug("Attempt Login on session %lu", session->session); /* Supports only USER login sessions for now */ ret = p11prov_Login(session->provctx, session->session, user_type, pin,