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: #295

Signed-off-by: Jakub Jelen <[email protected]>
  • Loading branch information
Jakuje committed Nov 16, 2023
1 parent 5af4e1b commit ba7db56
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 5 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
66 changes: 61 additions & 5 deletions src/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,44 @@ 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 +438,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 +472,14 @@ 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 @@ -443,10 +490,19 @@ static CK_RV token_login(P11PROV_SESSION *session, P11PROV_URI *uri,
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);
}
}

Expand Down

0 comments on commit ba7db56

Please sign in to comment.