Skip to content

Commit

Permalink
session: Implement interactive fallback PIN prompt when none provided
Browse files Browse the repository at this point in the history
Fixes: latchset#295

Signed-off-by: Jakub Jelen <[email protected]>
  • Loading branch information
Jakuje committed Nov 20, 2023
1 parent 7bb3016 commit 24b3e1c
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <openssl/proverr.h>
#include <openssl/core_names.h>
#include <openssl/provider.h>
#include <openssl/ui.h>

#define UNUSED __attribute__((unused))
#define RET_OSSL_OK 1
Expand Down
69 changes: 62 additions & 7 deletions src/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,45 @@ CK_SLOT_ID p11prov_session_slotid(P11PROV_SESSION *session)
return session->slotid;
}

static int p11prov_session_get_pin(struct p11prov_slot *slot, char *cb_pin,
size_t *cb_pin_len)
{
char *prompt = NULL;
UI *ui = UI_new_method(NULL);
const char *login_info = p11prov_slot_get_login_info(slot);
int ret;

P11PROV_debug("Starting internal PIN prompt slot=%p", slot);

if (ui == NULL) {
ret = RET_OSSL_ERR;
goto err;
}
prompt = UI_construct_prompt(ui, "PIN", login_info);
if (!prompt) {
ret = RET_OSSL_ERR;
goto err;
}
ret = UI_dup_input_string(ui, prompt, UI_INPUT_FLAG_DEFAULT_PWD, cb_pin, 4,
MAX_PIN_LENGTH);
if (ret <= 0) {
ret = RET_OSSL_ERR;
goto err;
}

if (UI_process(ui)) {
ret = RET_OSSL_ERR;
goto err;
}

*cb_pin_len = strlen(cb_pin);

err:
OPENSSL_free(prompt);
UI_free(ui);
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,
Expand All @@ -400,6 +439,9 @@ static CK_RV token_login(P11PROV_SESSION *session, P11PROV_URI *uri,
bool cache = false;
CK_RV ret;

P11PROV_debug("Log into the token session=%p uri=%p slot=%p type=%d",
session, uri, slot, user_type);

token = p11prov_slot_get_token(slot);
if (!(token->flags & CKF_PROTECTED_AUTHENTICATION_PATH)) {
const char *cached_pin = p11prov_slot_get_cached_pin(slot);
Expand Down Expand Up @@ -431,8 +473,15 @@ static CK_RV token_login(P11PROV_SESSION *session, P11PROV_URI *uri,
};
ret = pw_cb(cb_pin, sizeof(cb_pin), &cb_pin_len, params, pw_cbarg);
if (ret != RET_OSSL_OK) {
ret = CKR_GENERAL_ERROR;
goto done;
/* this error can mean anything from the user canceling the prompt to no UI method provided
* Fall back to our prompt here */
ret =
p11prov_session_get_pin(slot, (char *)cb_pin, &cb_pin_len);
if (ret != RET_OSSL_OK) {
/* give up */
ret = CKR_GENERAL_ERROR;
goto done;
}
}
if (cb_pin_len == 0) {
ret = CKR_CANCEL;
Expand All @@ -441,13 +490,19 @@ static CK_RV token_login(P11PROV_SESSION *session, P11PROV_URI *uri,

pin = (CK_UTF8CHAR_PTR)cb_pin;
pinlen = cb_pin_len;

cache = p11prov_ctx_cache_pins(session->provctx);

} else {
ret = CKR_CANCEL;
goto done;
/* We are asking the user off-band for the user consent -- from store
* we will always receive non-null (but unusable) callback */
ret = p11prov_session_get_pin(slot, (char *)cb_pin, &cb_pin_len);
if (ret != RET_OSSL_OK) {
ret = CKR_GENERAL_ERROR;
goto done;
}

pin = (CK_UTF8CHAR_PTR)cb_pin;
pinlen = strlen(cb_pin);
}
cache = p11prov_ctx_cache_pins(session->provctx);
}

P11PROV_debug("Attempt Login on session %lu", session->session);
Expand Down

0 comments on commit 24b3e1c

Please sign in to comment.