Skip to content

Commit

Permalink
Add support for key generation callbacks
Browse files Browse the repository at this point in the history
OpenSSL provides callbacks to be called to display key generation progress.
PKCS11 support passing callbacks into the token.

There is no guarantee the token will call the callbacks, but it might.

Signed-off-by: Simo Sorce <simo@redhat.com>
  • Loading branch information
simo5 committed Jan 12, 2023
1 parent a6e8323 commit 9ea7c27
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 6 deletions.
40 changes: 36 additions & 4 deletions src/keymgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ struct key_generator {
CK_ULONG ec_params_size;
} ec;
} data;

OSSL_CALLBACK *cb_fn;
void *cb_arg;
};

static void *p11prov_common_gen_init(void *provctx, int selection,
Expand Down Expand Up @@ -280,10 +283,33 @@ static int p11prov_common_gen_set_params(void *genctx,
return RET_OSSL_OK;
}

static CK_RV common_gen_callback(void *cbarg)
{
struct key_generator *ctx = (struct key_generator *)cbarg;
OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END, OSSL_PARAM_END };
int data = 0;
int ret;

if (!ctx->cb_fn) {
return CKR_OK;
}

params[0] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_POTENTIAL, &data);
params[1] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_ITERATION, &data);

ret = ctx->cb_fn(params, ctx->cb_arg);
if (ret != RET_OSSL_OK) {
return CKR_CANCEL;
}

return CKR_OK;
}

static void *p11prov_common_gen(struct key_generator *ctx,
CK_ATTRIBUTE *pubkey_template,
CK_ATTRIBUTE *privkey_template, int pubtsize,
int privtsize)
int privtsize, OSSL_CALLBACK *cb_fn,
void *cb_arg)
{
CK_SLOT_ID slotid = CK_UNAVAILABLE_INFORMATION;
CK_BYTE id[16];
Expand All @@ -304,6 +330,12 @@ static void *p11prov_common_gen(struct key_generator *ctx,
return NULL;
}

if (cb_fn) {
ctx->cb_fn = cb_fn;
ctx->cb_arg = cb_arg;
p11prov_session_set_callback(session, common_gen_callback, ctx);
}

sh = p11prov_session_handle(session);

if (ctx->id_len != 0) {
Expand Down Expand Up @@ -361,7 +393,7 @@ static void p11prov_common_gen_cleanup(void *genctx)
{
struct key_generator *ctx = (struct key_generator *)genctx;

P11PROV_debug("rsa gen_cleanup %p", genctx);
P11PROV_debug("common gen_cleanup %p", genctx);

if (ctx->label) {
OPENSSL_free(ctx->label);
Expand Down Expand Up @@ -424,7 +456,7 @@ static void *p11prov_rsa_gen(void *genctx, OSSL_CALLBACK *cb_fn, void *cb_arg)
P11PROV_debug("rsa gen %p %p %p", genctx, cb_fn, cb_arg);

return p11prov_common_gen(ctx, pubkey_template, privkey_template, pubtsize,
privtsize);
privtsize, cb_fn, cb_arg);
}

static const OSSL_PARAM *p11prov_rsa_gen_settable_params(void *genctx,
Expand Down Expand Up @@ -872,7 +904,7 @@ static void *p11prov_ec_gen(void *genctx, OSSL_CALLBACK *cb_fn, void *cb_arg)
P11PROV_debug("ec gen %p %p %p", ctx, cb_fn, cb_arg);

return p11prov_common_gen(ctx, pubkey_template, privkey_template, pubtsize,
privtsize);
privtsize, cb_fn, cb_arg);
}

static const OSSL_PARAM *p11prov_ec_gen_settable_params(void *genctx,
Expand Down
35 changes: 33 additions & 2 deletions src/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,9 @@ struct p11prov_session {
CK_FLAGS flags;

pthread_mutex_t lock;

p11prov_session_callback_t cb;
void *cbarg;
};

struct p11prov_session_pool {
Expand All @@ -455,19 +458,37 @@ struct p11prov_session_pool {
pthread_mutex_t lock;
};

static CK_RV token_session_callback(CK_SESSION_HANDLE hSession,
CK_NOTIFICATION event,
CK_VOID_PTR pApplication)
{
P11PROV_SESSION *session = (P11PROV_SESSION *)pApplication;

if (session->session != hSession) {
/* something not right, let's ignore this callback */
return CKR_OK;
}

if (session->cb) {
return session->cb(session->cbarg);
}

return CKR_OK;
}

/* in nanoseconds, 1 seconds */
#define MAX_WAIT 1000000000
/* sleep interval, 50 microseconds (max 20 attempts) */
#define SLEEP 50000

static CK_RV token_session_open(P11PROV_SESSION *session, CK_FLAGS flags)
{
uint64_t startime = 0;
CK_RV ret;

do {
ret = p11prov_OpenSession(session->provctx, session->slotid, flags,
NULL, NULL, &session->session);
session, token_session_callback,
&session->session);
P11PROV_debug("C_OpenSession ret:%lu (session: %lu)", ret,
session->session);
if (ret != CKR_SESSION_COUNT) {
Expand Down Expand Up @@ -1201,6 +1222,9 @@ void p11prov_return_session(P11PROV_SESSION *session)
return;
}

/* remove any callback */
p11prov_session_set_callback(session, NULL, NULL);

pool = session->pool;

if (pool) {
Expand Down Expand Up @@ -1230,3 +1254,10 @@ void p11prov_return_session(P11PROV_SESSION *session)
session_free(session);
}
}

void p11prov_session_set_callback(P11PROV_SESSION *session,
p11prov_session_callback_t cb, void *cbarg)
{
session->cb = cb;
session->cbarg = cbarg;
}
4 changes: 4 additions & 0 deletions src/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,8 @@ CK_RV p11prov_take_login_session(P11PROV_CTX *provctx, CK_SLOT_ID slotid,
P11PROV_SESSION **_session);
void p11prov_return_session(P11PROV_SESSION *session);

typedef CK_RV (*p11prov_session_callback_t)(void *cbarg);
void p11prov_session_set_callback(P11PROV_SESSION *session,
p11prov_session_callback_t cb, void *cbarg);

#endif /* _SESSION_H */

0 comments on commit 9ea7c27

Please sign in to comment.