Skip to content

Commit 73f544e

Browse files
committed
Allow objects on uninitialized tokens
1 parent a1edcd0 commit 73f544e

File tree

2 files changed

+134
-47
lines changed

2 files changed

+134
-47
lines changed

src/eng_back.c

Lines changed: 130 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ static void *ctx_try_load_object(ENGINE_CTX *ctx,
391391
{
392392
PKCS11_SLOT *slot;
393393
PKCS11_SLOT *found_slot = NULL, **matched_slots = NULL;
394-
PKCS11_TOKEN *tok, *match_tok = NULL;
394+
PKCS11_TOKEN *match_tok = NULL;
395395
unsigned int n, m;
396396
char *obj_id = NULL;
397397
size_t obj_id_len = 0;
@@ -406,6 +406,10 @@ static void *ctx_try_load_object(ENGINE_CTX *ctx,
406406
if (object_uri && *object_uri) {
407407
obj_id_len = strlen(object_uri) + 1;
408408
obj_id = OPENSSL_malloc(obj_id_len);
409+
if (!obj_id) {
410+
ctx_log(ctx, 0, "Could not allocate memory for ID\n");
411+
goto cleanup;
412+
}
409413
if (!strncasecmp(object_uri, "pkcs11:", 7)) {
410414
n = parse_pkcs11_uri(ctx, object_uri, &match_tok,
411415
obj_id, &obj_id_len, tmp_pin, &tmp_pin_len, &obj_label);
@@ -415,12 +419,12 @@ static void *ctx_try_load_object(ENGINE_CTX *ctx,
415419
"The PKCS#11 URI format is defined by RFC7512\n",
416420
object_typestr);
417421
ENGerr(ENG_F_CTX_LOAD_OBJECT, ENG_R_INVALID_ID);
418-
goto error;
422+
goto cleanup;
419423
}
420424
if (tmp_pin_len > 0 && tmp_pin[0] != 0) {
421425
tmp_pin[tmp_pin_len] = 0;
422426
if (!ctx_ctrl_set_pin(ctx, tmp_pin)) {
423-
goto error;
427+
goto cleanup;
424428
}
425429
}
426430
ctx_log(ctx, 1, "Looking in slots for %s %s login: ",
@@ -436,7 +440,7 @@ static void *ctx_try_load_object(ENGINE_CTX *ctx,
436440
"still accepted for now\n",
437441
object_typestr);
438442
ENGerr(ENG_F_CTX_LOAD_OBJECT, ENG_R_INVALID_ID);
439-
goto error;
443+
goto cleanup;
440444
}
441445
ctx_log(ctx, 1, "Looking in slot %d for %s %s login: ",
442446
slot_nr, object_typestr, login ? "with" : "without");
@@ -455,8 +459,8 @@ static void *ctx_try_load_object(ENGINE_CTX *ctx,
455459
matched_slots = (PKCS11_SLOT **)calloc(ctx->slot_count,
456460
sizeof(PKCS11_SLOT *));
457461
if (!matched_slots) {
458-
ctx_log(ctx, 0, "Could not allocate memory for matched slots\n");
459-
goto error;
462+
ctx_log(ctx, 0, "Could not allocate memory for slots\n");
463+
goto cleanup;
460464
}
461465

462466
for (n = 0; n < ctx->slot_count; n++) {
@@ -504,8 +508,9 @@ static void *ctx_try_load_object(ENGINE_CTX *ctx,
504508
}
505509
ctx_log(ctx, 1, "\n");
506510

507-
/* Ignore slots without tokens or with uninitialized token */
508-
if (found_slot && found_slot->token && found_slot->token->initialized) {
511+
/* Ignore slots without tokens. Thales HSM (and potentially
512+
* other modules) allow objects on uninitialized tokens. */
513+
if (found_slot && found_slot->token) {
509514
matched_slots[matched_count] = found_slot;
510515
matched_count++;
511516
}
@@ -516,73 +521,151 @@ static void *ctx_try_load_object(ENGINE_CTX *ctx,
516521
if (match_tok) {
517522
ctx_log(ctx, 0, "No matching initialized token was found for %s\n",
518523
object_typestr);
519-
goto error;
524+
goto cleanup;
520525
}
521526

522527
/* If the legacy slot ID format was used */
523528
if (slot_nr != -1) {
524529
ctx_log(ctx, 0, "The %s was not found on slot %d\n", object_typestr, slot_nr);
525-
goto error;
530+
goto cleanup;
526531
} else {
527532
found_slot = PKCS11_find_token(ctx->pkcs11_ctx,
528533
ctx->slot_list, ctx->slot_count);
529-
/* Ignore if the the token is not initialized */
530-
if (found_slot && found_slot->token &&
531-
found_slot->token->initialized) {
534+
/* Ignore slots without tokens. Thales HSM (and potentially
535+
* other modules) allow objects on uninitialized tokens. */
536+
if (found_slot && found_slot->token) {
532537
matched_slots[matched_count] = found_slot;
533538
matched_count++;
534539
} else {
535540
ctx_log(ctx, 0, "No tokens found\n");
536-
goto error;
541+
goto cleanup;
537542
}
538543
}
539544
}
540545

541-
for (n = 0; n < matched_count; n++) {
542-
slot = matched_slots[n];
543-
tok = slot->token;
544-
if (!tok) {
545-
ctx_log(ctx, 0, "Empty slot found\n");
546-
break;
547-
}
546+
/* In several tokens certificates are marked as private */
547+
if (login) {
548+
/* Only try to login if a single slot matched to avoiding trying
549+
* the PIN against all matching slots */
548550

549-
ctx_log(ctx, 1, "Found slot: %s\n", slot->description);
550-
ctx_log(ctx, 1, "Found token: %s\n", slot->token->label);
551+
if (matched_count == 1) {
552+
slot = matched_slots[0];
553+
if (!slot->token) {
554+
ctx_log(ctx, 0, "Empty slot found: %s\n", slot->description);
555+
goto cleanup; /* failed */
556+
}
557+
ctx_log(ctx, 1, "Found slot: %s\n", slot->description);
558+
ctx_log(ctx, 1, "Found token: %s\n", slot->token->label[0]?
559+
slot->token->label : "no label");
551560

552-
/* In several tokens certificates are marked as private */
553-
if (login) {
554561
/* Only try to login if login is required */
555-
if (tok->loginRequired || ctx->force_login) {
556-
/* Only try to login if a single slot matched to avoiding trying
557-
* the PIN against all matching slots */
558-
if (matched_count == 1) {
559-
if (!ctx_login(ctx, slot, tok,
560-
ui_method, callback_data)) {
562+
if (slot->token->loginRequired || ctx->force_login) {
563+
if (!ctx_login(ctx, slot, slot->token, ui_method, callback_data)) {
564+
ctx_log(ctx, 0, "Login to token failed, returning NULL...\n");
565+
goto cleanup; /* failed */
566+
}
567+
}
568+
} else {
569+
/* Multiple matching slots */
570+
size_t init_count = 0;
571+
size_t uninit_count = 0;
572+
PKCS11_SLOT **init_slots = NULL, **uninit_slots = NULL;
573+
574+
init_slots = (PKCS11_SLOT **)calloc(ctx->slot_count, sizeof(PKCS11_SLOT *));
575+
if (!init_slots) {
576+
ctx_log(ctx, 0, "Could not allocate memory for slots\n");
577+
goto cleanup; /* failed */
578+
}
579+
uninit_slots = (PKCS11_SLOT **)calloc(ctx->slot_count, sizeof(PKCS11_SLOT *));
580+
if (!uninit_slots) {
581+
ctx_log(ctx, 0, "Could not allocate memory for slots\n");
582+
free(init_slots);
583+
goto cleanup; /* failed */
584+
}
585+
586+
for (m = 0; m < matched_count; m++) {
587+
slot = matched_slots[m];
588+
if (!slot->token) {
589+
ctx_log(ctx, 0, "Empty slot found: %s\n", slot->description);
590+
continue; /* skipped */
591+
}
592+
if (slot->token->initialized) {
593+
init_slots[init_count] = slot;
594+
init_count++;
595+
} else {
596+
uninit_slots[uninit_count] = slot;
597+
uninit_count++;
598+
}
599+
}
600+
601+
/* Initialized tokens */
602+
if (init_count == 1) {
603+
slot = init_slots[0];
604+
ctx_log(ctx, 1, "Found slot: %s\n", slot->description);
605+
ctx_log(ctx, 1, "Found token: %s\n", slot->token->label[0]?
606+
slot->token->label : "no label");
607+
608+
/* Only try to login if login is required */
609+
if (slot->token->loginRequired || ctx->force_login) {
610+
if (!ctx_login(ctx, slot, slot->token, ui_method, callback_data)) {
561611
ctx_log(ctx, 0, "Login to token failed, returning NULL...\n");
562-
goto error;
612+
free(init_slots);
613+
free(uninit_slots);
614+
goto cleanup; /* failed */
563615
}
564-
} else {
565-
ctx_log(ctx, 0, "Multiple matching slots (%zu); will not try to"
566-
" login\n", matched_count);
567-
for (m = 0; m < matched_count; m++){
568-
slot = matched_slots[m];
569-
ctx_log(ctx, 0, "- [%u] %s: %s\n", m + 1,
570-
slot->description? slot->description:
571-
"(no description)",
572-
(slot->token && slot->token->label)?
573-
slot->token->label: "no label");
616+
}
617+
} else {
618+
/* Multiple slots with initialized token */
619+
if (init_count > 1) {
620+
ctx_log(ctx, 0, "Multiple matching slots (%zu);"
621+
" will not try to login\n", init_count);
622+
}
623+
for (m = 0; m < init_count; m++) {
624+
slot = init_slots[m];
625+
ctx_log(ctx, 0, "- [%u] %s: %s\n", m + 1,
626+
slot->description? slot->description:
627+
"(no description)",
628+
(slot->token && slot->token->label)?
629+
slot->token->label: "no label");
630+
}
631+
free(init_slots);
632+
633+
/* Uninitialized tokens, user PIN is unset */
634+
for (m = 0; m < uninit_count; m++) {
635+
slot = uninit_slots[m];
636+
ctx_log(ctx, 1, "Found slot: %s\n", slot->description);
637+
ctx_log(ctx, 1, "Found token: %s\n", slot->token->label[0]?
638+
slot->token->label : "no label");
639+
object = match_func(ctx, slot->token, obj_id, obj_id_len, obj_label);
640+
if (object) {
641+
free(uninit_slots);
642+
goto cleanup; /* success */
574643
}
575-
goto error;
576644
}
645+
free(uninit_slots);
646+
goto cleanup; /* failed */
577647
}
578648
}
649+
object = match_func(ctx, slot->token, obj_id, obj_id_len, obj_label);
579650

580-
object = match_func(ctx, tok, obj_id, obj_id_len, obj_label);
581-
if (object)
582-
break;
651+
} else {
652+
/* Find public object */
653+
for (n = 0; n < matched_count; n++) {
654+
slot = matched_slots[n];
655+
if (!slot->token) {
656+
ctx_log(ctx, 0, "Empty slot found: %s\n", slot->description);
657+
break;
658+
}
659+
ctx_log(ctx, 1, "Found slot: %s\n", slot->description);
660+
ctx_log(ctx, 1, "Found token: %s\n", slot->token->label[0]?
661+
slot->token->label : "no label");
662+
object = match_func(ctx, slot->token, obj_id, obj_id_len, obj_label);
663+
if (object)
664+
break; /* success */
665+
}
583666
}
584667

585-
error:
668+
cleanup:
586669
/* Free the searched token data */
587670
if (match_tok) {
588671
OPENSSL_free(match_tok->model);

src/p11_slot.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,10 @@ int pkcs11_get_session(PKCS11_SLOT_private *slot, int rw, CK_SESSION_HANDLE *ses
180180
slot->num_sessions++;
181181
break;
182182
}
183+
if (rv == CKR_TOKEN_NOT_RECOGNIZED) {
184+
pthread_mutex_unlock(&slot->lock);
185+
return -1;
186+
}
183187

184188
/* Remember the maximum session count */
185189
if (rv == CKR_SESSION_COUNT)

0 commit comments

Comments
 (0)