Skip to content

Incorrect slot for new associated object #557

Open
@bukka

Description

@bukka

Describe the bug

First of all I'm not really sure if this is actually reproducible in the current master but there is a chance it might happen too. I'm adding this mainly to not forget that this issue is there as it should be resolved before default PIN selection in #536 is merged.

My client has been reporting issue with blocking PIN when they use multiple slots with tokens having different PINs. I should note that they run a version with few patches including the default PIN selection implemented in #536

After digging through the logs (extended with some extra custom info) and code I noticed following.

After the object (public key in this case) is imported, it is followed by MATCH which tries to find associated object which means calling find operation. The issue is in the session (specifically slot) selection before this operation is started. The problem is that when such object is imported, the slotid is set to CK_UNAVAILABLE_INFORMATION so when session is selected, it uses following logic:

/* caller is cycling through slots, find the next viable one */
for (slot = p11prov_fetch_slot(slots, &slot_idx); slot != NULL;
slot = p11prov_fetch_slot(slots, &slot_idx)) {
CK_SLOT_ID slot_id = p11prov_slot_get_slot_id(slot);
if (id != CK_UNAVAILABLE_INFORMATION && id != slot_id) {
/* seek to next slot to check */
continue;
} else {
/* Found "next" slot.
* Reset the id, so from now on we check every following slot
* and return the first one that successfully passes checks.
*/
id = CK_UNAVAILABLE_INFORMATION;
}
ret = check_slot(provctx, slot, uri, mechtype, rw);
if (ret != CKR_OK) {
/* keep going */
continue;
}
if (reqlogin && !check_skip_login(provctx, slot)) {
ret = slot_login(slot, uri, pw_cb, pw_cbarg, reqlogin, NULL);
if (ret != CKR_OK) {
/* keep going */
continue;
}
}
id = slot_id;
P11PROV_debug("Found a slot %lu", id);
break;
}

The slot selected here is then set to the object that is then added to the pool. The selected session in this flow does not require login so it doesn't fail here.

The actual PIN failure happens later when verify is used and the key is duplicated and subsequently token login is required. It will use the slot selected above but because there is not pin in object (no refresh URI), it will use the configured PIN for default slot. However if the default slot does not match the slot for the session (which can easily happen when the default slot is configured and maybe there is a chance it happens anyway), then it result in incorrect PIN failure.

Currently I came up with following change ( bukka@cf89911 ), which is not yet confirmed that it fixes the issue but the idea is to select the default slot before getting the session when looking for an associated object and use that slot for the object. But I'm wondering what's the actual point of the current session slot selection above. Why doesn't it just always use the default slot?

To Reproduce

This is not easy to reproduce as it requires some slot preconditions. So far I haven't managed to recreate but it might be possible to recreate it artificially which I will attempt to do later.

Expected behavior

New associated object should be assigned to the default slot

Operating environment (please complete the following information):

  • Linux otherwise does not matter

Token and application used (please complete the following information):

  • Device: SoftHSMv2 but any device supporting multiple slot can show this issue
  • Application: Nginx

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions