Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use a cached version of the URI to refresh objects
Browse files Browse the repository at this point in the history
This allows us to retain better information about the object
and critically things like a PIN passed in the URI to be able
to login to the token after a fork when the PIN is not specified in the
token configuration.

Signed-off-by: Simo Sorce <[email protected]>
simo5 committed Nov 30, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent b4728fa commit 758ca61
Showing 3 changed files with 165 additions and 3 deletions.
87 changes: 84 additions & 3 deletions src/objects.c
Original file line number Diff line number Diff line change
@@ -40,6 +40,8 @@ struct p11prov_obj {
CK_BBOOL cka_copyable;
CK_BBOOL cka_token;

P11PROV_URI *refresh_uri;

union {
struct p11prov_key key;
struct p11prov_crt crt;
@@ -999,6 +1001,9 @@ CK_RV p11prov_obj_find(P11PROV_CTX *provctx, P11PROV_SESSION *session,
/* unknown object or other recoverable error to ignore */
continue;
} else if (ret == CKR_OK) {
/* keep a copy of the URI for refreshes as it may contain
* things like a PIN necessary to log in */
obj->refresh_uri = p11prov_copy_uri(uri);
ret = cb(cb_ctx, obj);
}
if (ret != CKR_OK) {
@@ -1084,13 +1089,86 @@ static P11PROV_OBJ *find_associated_obj(P11PROV_CTX *provctx, P11PROV_OBJ *obj,

static void p11prov_obj_refresh(P11PROV_OBJ *obj)
{
int login_behavior;
bool login = false;
CK_SLOT_ID slotid = CK_UNAVAILABLE_INFORMATION;
P11PROV_SESSION *session = NULL;
CK_SESSION_HANDLE sess = CK_INVALID_HANDLE;
CK_ATTRIBUTE template[3] = { 0 };
CK_ATTRIBUTE *attr;
int anum;
CK_OBJECT_HANDLE handle;
CK_ULONG objcount = 0;
P11PROV_OBJ *tmp = NULL;
tmp = find_associated_obj(obj->ctx, obj, obj->class);
if (!tmp) {
/* nothing we can do, invalid handle it is */
CK_RV ret;

P11PROV_debug("Refresh object %p", obj);

if (obj->class == CKO_PRIVATE_KEY) {
login = true;
}
login_behavior = p11prov_ctx_login_behavior(obj->ctx);
if (login_behavior == PUBKEY_LOGIN_ALWAYS) {
login = true;
}

slotid = p11prov_obj_get_slotid(obj);

ret = p11prov_get_session(obj->ctx, &slotid, NULL, obj->refresh_uri,
CK_UNAVAILABLE_INFORMATION, NULL, NULL, login,
false, &session);

if (ret != CKR_OK) {
P11PROV_debug("Failed to get session to refresh object %p", obj);
return;
}

sess = p11prov_session_handle(session);

anum = 0;
CKATTR_ASSIGN(template[anum], CKA_CLASS, &obj -> class, sizeof(obj->class));
anum++;
/* use CKA_ID if available */
attr = p11prov_obj_get_attr(obj, CKA_ID);
if (attr) {
template[anum] = *attr;
anum++;
}
/* use Label if available */
attr = p11prov_obj_get_attr(obj, CKA_LABEL);
if (attr) {
template[anum] = *attr;
anum++;
}

ret = p11prov_FindObjectsInit(obj->ctx, sess, template, anum);
if (ret != CKR_OK) {
goto done;
}

/* we expect a single entry */
ret = p11prov_FindObjects(obj->ctx, sess, &handle, 1, &objcount);

/* Finalizing is not fatal so ignore result */
p11prov_FindObjectsFinal(obj->ctx, sess);

if (ret != CKR_OK) {
P11PROV_debug("Failed to find refresh object %p", obj);
goto done;
}
if (objcount != 1) {
P11PROV_raise(obj->ctx, ret,
"Too many objects found on refresh (count=%ld)",
objcount);
goto done;
}

ret = p11prov_obj_from_handle(obj->ctx, session, handle, &tmp);
if (ret != CKR_OK) {
P11PROV_raise(obj->ctx, ret, "Failed to get object from handle");
goto done;
}

/* move over all the object data, then free the tmp */
obj->handle = tmp->handle;
obj->cached = tmp->cached;
@@ -1112,6 +1190,9 @@ static void p11prov_obj_refresh(P11PROV_OBJ *obj)
* cause use-after-free issues */
p11prov_obj_free(tmp);
obj->raf = false;

done:
p11prov_return_session(session);
}

#define SECRET_KEY_ATTRS 2
75 changes: 75 additions & 0 deletions src/util.c
Original file line number Diff line number Diff line change
@@ -320,6 +320,15 @@ static int get_pin_file(P11PROV_CTX *ctx, const char *str, size_t len,
return ret;
}

#define COPY_STRUCT_MEMBER(dst, src, _name) \
if ((src)->_name) { \
(dst)->_name = strdup((src)->_name); \
if (!(dst)->_name) { \
p11prov_uri_free((dst)); \
return NULL; \
} \
}

static void p11prov_uri_free_int(P11PROV_URI *uri)
{
OPENSSL_free(uri->library_manufacturer);
@@ -795,16 +804,33 @@ CK_OBJECT_CLASS p11prov_uri_get_class(P11PROV_URI *uri)
return uri->type;
}

void p11prov_uri_set_class(P11PROV_URI *uri, CK_OBJECT_CLASS class)
{
uri->type = class;
}

CK_ATTRIBUTE p11prov_uri_get_id(P11PROV_URI *uri)
{
return uri->id;
}

void p11prov_uri_set_id(P11PROV_URI *uri, CK_ATTRIBUTE *id)
{
OPENSSL_free(uri->id.pValue);
p11prov_copy_attr(&uri->id, id);
}

CK_ATTRIBUTE p11prov_uri_get_label(P11PROV_URI *uri)
{
return uri->object;
}

void p11prov_uri_set_label(P11PROV_URI *uri, CK_ATTRIBUTE *label)
{
OPENSSL_free(uri->object.pValue);
p11prov_copy_attr(&uri->object, label);
}

char *p11prov_uri_get_serial(P11PROV_URI *uri)
{
return uri->serial;
@@ -815,6 +841,55 @@ char *p11prov_uri_get_pin(P11PROV_URI *uri)
return uri->pin;
}

CK_SLOT_ID p11prov_uri_get_slot_id(P11PROV_URI *uri)
{
return uri->slot_id;
}

void p11prov_uri_set_slot_id(P11PROV_URI *uri, CK_SLOT_ID slot_id)
{
uri->slot_id = slot_id;
}

P11PROV_URI *p11prov_copy_uri(P11PROV_URI *uri)
{
P11PROV_URI *cu;
CK_RV rv;

cu = OPENSSL_zalloc(sizeof(P11PROV_URI));
if (!cu) {
return NULL;
}

COPY_STRUCT_MEMBER(cu, uri, library_manufacturer)
COPY_STRUCT_MEMBER(cu, uri, library_description)
COPY_STRUCT_MEMBER(cu, uri, token)
COPY_STRUCT_MEMBER(cu, uri, manufacturer)
COPY_STRUCT_MEMBER(cu, uri, model)
COPY_STRUCT_MEMBER(cu, uri, serial)
COPY_STRUCT_MEMBER(cu, uri, slot_description)
COPY_STRUCT_MEMBER(cu, uri, slot_manufacturer)
COPY_STRUCT_MEMBER(cu, uri, pin)

rv = p11prov_copy_attr(&cu->id, &uri->id);
if (rv != CKR_OK) {
p11prov_uri_free(cu);
return NULL;
}

rv = p11prov_copy_attr(&cu->object, &uri->object);
if (rv != CKR_OK) {
p11prov_uri_free(cu);
return NULL;
}

cu->library_version = uri->library_version;
cu->slot_id = uri->slot_id;
cu->type = uri->type;

return cu;
}

CK_RV p11prov_uri_match_token(P11PROV_URI *uri, CK_SLOT_ID slot_id,
CK_SLOT_INFO *slot, CK_TOKEN_INFO *token)
{
6 changes: 6 additions & 0 deletions src/util.h
Original file line number Diff line number Diff line change
@@ -57,10 +57,16 @@ P11PROV_URI *p11prov_parse_uri(P11PROV_CTX *ctx, const char *uri);
char *p11prov_key_to_uri(P11PROV_CTX *ctx, P11PROV_OBJ *key);
void p11prov_uri_free(P11PROV_URI *parsed_uri);
CK_OBJECT_CLASS p11prov_uri_get_class(P11PROV_URI *uri);
void p11prov_uri_set_class(P11PROV_URI *uri, CK_OBJECT_CLASS class);
CK_ATTRIBUTE p11prov_uri_get_id(P11PROV_URI *uri);
void p11prov_uri_set_id(P11PROV_URI *uri, CK_ATTRIBUTE *id);
CK_ATTRIBUTE p11prov_uri_get_label(P11PROV_URI *uri);
void p11prov_uri_set_label(P11PROV_URI *uri, CK_ATTRIBUTE *label);
char *p11prov_uri_get_serial(P11PROV_URI *uri);
char *p11prov_uri_get_pin(P11PROV_URI *uri);
CK_SLOT_ID p11prov_uri_get_slot_id(P11PROV_URI *uri);
void p11prov_uri_set_slot_id(P11PROV_URI *uri, CK_SLOT_ID slot_id);
P11PROV_URI *p11prov_copy_uri(P11PROV_URI *uri);
CK_RV p11prov_uri_match_token(P11PROV_URI *uri, CK_SLOT_ID slot_id,
CK_SLOT_INFO *slot, CK_TOKEN_INFO *token);
int p11prov_get_pin(P11PROV_CTX *ctx, const char *in, char **out);

0 comments on commit 758ca61

Please sign in to comment.