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 29, 2023
1 parent 52b7afb commit 594cf13
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 16 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
91 changes: 75 additions & 16 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_prompt_for_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 All @@ -421,18 +463,39 @@ static CK_RV token_login(P11PROV_SESSION *session, P11PROV_URI *uri,
}
if (pin) {
pinlen = strlen((const char *)pin);
} else if (pw_cb) {
const char *login_info = p11prov_slot_get_login_info(slot);
OSSL_PARAM params[2] = {
OSSL_PARAM_DEFN(OSSL_PASSPHRASE_PARAM_INFO,
OSSL_PARAM_UTF8_STRING, (void *)login_info,
strlen(login_info)),
OSSL_PARAM_END,
};
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;
} else {
if (pw_cb) {
const char *login_info = p11prov_slot_get_login_info(slot);
OSSL_PARAM params[2] = {
OSSL_PARAM_DEFN(OSSL_PASSPHRASE_PARAM_INFO,
OSSL_PARAM_UTF8_STRING, (void *)login_info,
strlen(login_info)),
OSSL_PARAM_END,
};
ret = pw_cb(cb_pin, sizeof(cb_pin), &cb_pin_len, params,
pw_cbarg);
if (ret != RET_OSSL_OK) {
/* 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_prompt_for_pin(slot, (char *)cb_pin,
&cb_pin_len);
if (ret != RET_OSSL_OK) {
/* give up */
ret = CKR_GENERAL_ERROR;
goto done;
}
}
} else {
/* 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_prompt_for_pin(slot, (char *)cb_pin,
&cb_pin_len);
if (ret != RET_OSSL_OK) {
ret = CKR_GENERAL_ERROR;
goto done;
}
}
if (cb_pin_len == 0) {
ret = CKR_CANCEL;
Expand All @@ -443,10 +506,6 @@ 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;
}
}

Expand Down

0 comments on commit 594cf13

Please sign in to comment.