Skip to content

Commit

Permalink
Implement support for CKA_ALWAYS_AUTHENTICATE
Browse files Browse the repository at this point in the history
Fixes latchset#42

Signed-off-by: Simo Sorce <simo@redhat.com>
  • Loading branch information
simo5 committed Oct 23, 2023
1 parent f9b04f9 commit 92e2fd0
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 4 deletions.
10 changes: 10 additions & 0 deletions src/asymmetric_cipher.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ static int p11prov_rsaenc_decrypt(void *ctx, unsigned char *out, size_t *outlen,
CK_OBJECT_HANDLE handle;
CK_ULONG out_size = *outlen;
int result = RET_OSSL_ERR;
bool always_auth = false;
CK_RV ret;

P11PROV_debug("decrypt (ctx=%p)", ctx);
Expand Down Expand Up @@ -296,6 +297,15 @@ static int p11prov_rsaenc_decrypt(void *ctx, unsigned char *out, size_t *outlen,
goto endsess;
}

always_auth =
p11prov_obj_get_bool(encctx->key, CKA_ALWAYS_AUTHENTICATE, false);
if (always_auth) {
ret = p11prov_context_specific_login(session, NULL, NULL, NULL);
if (ret != CKR_OK) {
goto endsess;
}
}

ret = p11prov_Decrypt(encctx->provctx, sess, (void *)in, inlen, out,
&out_size);
if (ret != CKR_OK) {
Expand Down
34 changes: 33 additions & 1 deletion src/objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,35 @@ CK_ATTRIBUTE *p11prov_obj_get_attr(P11PROV_OBJ *obj, CK_ATTRIBUTE_TYPE type)
return NULL;
}

bool p11prov_obj_get_bool(P11PROV_OBJ *obj, CK_ATTRIBUTE_TYPE type, bool def)
{
CK_ATTRIBUTE *attr = NULL;

if (!obj) {
return def;
}

for (int i = 0; i < obj->numattrs; i++) {
if (obj->attrs[i].type == type) {
attr = &obj->attrs[i];
}
}

if (!attr || !attr->pValue) {
return def;
}

if (attr->ulValueLen == sizeof(CK_BBOOL)) {
if (*((CK_BBOOL *)attr->pValue) == CK_FALSE) {
return false;
} else {
return true;
}
}

return def;
}

CK_KEY_TYPE p11prov_obj_get_key_type(P11PROV_OBJ *obj)
{
if (obj) {
Expand Down Expand Up @@ -566,8 +595,9 @@ P11PROV_CTX *p11prov_obj_get_prov_ctx(P11PROV_OBJ *obj)

/* CKA_ID
* CKA_LABEL
* CKA_ALWAYS_AUTHENTICATE
* CKA_ALLOWED_MECHANISMS see p11prov_obj_from_handle() */
#define BASE_KEY_ATTRS_NUM 3
#define BASE_KEY_ATTRS_NUM 4

#define RSA_ATTRS_NUM (BASE_KEY_ATTRS_NUM + 2)
static int fetch_rsa_key(P11PROV_CTX *ctx, P11PROV_SESSION *session,
Expand All @@ -588,6 +618,7 @@ static int fetch_rsa_key(P11PROV_CTX *ctx, P11PROV_SESSION *session,
FA_SET_BUF_ALLOC(attrs, num, CKA_PUBLIC_EXPONENT, true);
FA_SET_BUF_ALLOC(attrs, num, CKA_ID, false);
FA_SET_BUF_ALLOC(attrs, num, CKA_LABEL, false);
FA_SET_BUF_ALLOC(attrs, num, CKA_ALWAYS_AUTHENTICATE, false);
ret = p11prov_fetch_attributes(ctx, session, object, attrs, num);
if (ret != CKR_OK) {
/* free any allocated memory */
Expand Down Expand Up @@ -745,6 +776,7 @@ static CK_RV fetch_ec_key(P11PROV_CTX *ctx, P11PROV_SESSION *session,
}
FA_SET_BUF_ALLOC(attrs, num, CKA_ID, false);
FA_SET_BUF_ALLOC(attrs, num, CKA_LABEL, false);
FA_SET_BUF_ALLOC(attrs, num, CKA_ALWAYS_AUTHENTICATE, false);
ret = p11prov_fetch_attributes(ctx, session, object, attrs, num);
if (ret != CKR_OK) {
/* free any allocated memory */
Expand Down
1 change: 1 addition & 0 deletions src/objects.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ CK_SLOT_ID p11prov_obj_get_slotid(P11PROV_OBJ *obj);
CK_OBJECT_HANDLE p11prov_obj_get_handle(P11PROV_OBJ *obj);
CK_OBJECT_CLASS p11prov_obj_get_class(P11PROV_OBJ *obj);
CK_ATTRIBUTE *p11prov_obj_get_attr(P11PROV_OBJ *obj, CK_ATTRIBUTE_TYPE type);
bool p11prov_obj_get_bool(P11PROV_OBJ *obj, CK_ATTRIBUTE_TYPE type, bool def);
CK_KEY_TYPE p11prov_obj_get_key_type(P11PROV_OBJ *obj);
CK_ULONG p11prov_obj_get_key_bit_size(P11PROV_OBJ *obj);
CK_ULONG p11prov_obj_get_key_size(P11PROV_OBJ *obj);
Expand Down
31 changes: 28 additions & 3 deletions src/session.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ CK_SLOT_ID p11prov_session_slotid(P11PROV_SESSION *session)
/* 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,
struct p11prov_slot *slot)
struct p11prov_slot *slot, CK_USER_TYPE user_type)
{
char cb_pin[MAX_PIN_LENGTH + 1] = { 0 };
size_t cb_pin_len = 0;
Expand Down Expand Up @@ -452,7 +452,7 @@ static CK_RV token_login(P11PROV_SESSION *session, P11PROV_URI *uri,

P11PROV_debug("Attempt Login on session %lu", session->session);
/* Supports only USER login sessions for now */
ret = p11prov_Login(session->provctx, session->session, CKU_USER, pin,
ret = p11prov_Login(session->provctx, session->session, user_type, pin,
pinlen);
if (ret == CKR_USER_ALREADY_LOGGED_IN) {
ret = CKR_OK;
Expand Down Expand Up @@ -481,6 +481,31 @@ static CK_RV token_login(P11PROV_SESSION *session, P11PROV_URI *uri,
return ret;
}

CK_RV p11prov_context_specific_login(P11PROV_SESSION *session, P11PROV_URI *uri,
OSSL_PASSPHRASE_CALLBACK *pw_cb,
void *pw_cbarg)
{
P11PROV_SLOTS_CTX *sctx = NULL;
P11PROV_SLOT *slot = NULL;
CK_RV ret;

ret = p11prov_take_slots(session->provctx, &sctx);
if (ret != CKR_OK) {
return CKR_GENERAL_ERROR;
}

slot = p11prov_get_slot_by_id(sctx, p11prov_session_slotid(session));
if (!slot) {
ret = CKR_GENERAL_ERROR;
}

ret =
token_login(session, uri, pw_cb, pw_cbarg, slot, CKU_CONTEXT_SPECIFIC);

p11prov_return_slots(sctx);
return ret;
}

static CK_RV check_slot(P11PROV_CTX *ctx, P11PROV_SLOT *slot, P11PROV_URI *uri,
CK_MECHANISM_TYPE mechtype, bool rw)
{
Expand Down Expand Up @@ -689,7 +714,7 @@ static CK_RV slot_login(P11PROV_SLOT *slot, P11PROV_URI *uri,
/* we seem to already have a valid logged in session */
ret = CKR_OK;
} else {
ret = token_login(session, uri, pw_cb, pw_cbarg, slot);
ret = token_login(session, uri, pw_cb, pw_cbarg, slot, CKU_USER);
}

done:
Expand Down
4 changes: 4 additions & 0 deletions src/session.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ CK_RV p11prov_take_login_session(P11PROV_CTX *provctx, CK_SLOT_ID slotid,
P11PROV_SESSION **_session);
void p11prov_return_session(P11PROV_SESSION *session);

CK_RV p11prov_context_specific_login(P11PROV_SESSION *session, P11PROV_URI *uri,
OSSL_PASSPHRASE_CALLBACK *pw_cb,
void *pw_cbarg);

typedef CK_RV (*p11prov_session_callback_t)(void *cbarg);
void p11prov_session_set_callback(P11PROV_SESSION *session,
p11prov_session_callback_t cb, void *cbarg);
Expand Down
8 changes: 8 additions & 0 deletions src/signature.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,7 @@ static CK_RV p11prov_sig_operate_init(P11PROV_SIG_CTX *sigctx, bool digest_op,
CK_SESSION_HANDLE sess;
CK_SLOT_ID slotid;
bool reqlogin = false;
bool always_auth = false;
CK_RV ret;

P11PROV_debug("called (sigctx=%p, digest_op=%s)", sigctx,
Expand Down Expand Up @@ -838,6 +839,13 @@ static CK_RV p11prov_sig_operate_init(P11PROV_SIG_CTX *sigctx, bool digest_op,
"Failed to open session on slot %lu", slotid);
}

if (reqlogin)
always_auth =
p11prov_obj_get_bool(sigctx->key, CKA_ALWAYS_AUTHENTICATE, false);
if (always_auth) {
ret = p11prov_context_specific_login(session, NULL, NULL, NULL);
}

done:
if (ret != CKR_OK) {
p11prov_return_session(session);
Expand Down

0 comments on commit 92e2fd0

Please sign in to comment.