From d0830a4445115ef4cdbc8b524794f276f7954f7a Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Mon, 8 Oct 2018 12:47:25 +0200 Subject: [PATCH 44/47] p11_child: add PKCS#11 uri to restrict selection Related to https://pagure.io/SSSD/sssd/issue/3814 Reviewed-by: Jakub Hrozek (cherry picked from commit f7b2152a4c3c816a5bc4226a0e01791313accef3) --- src/p11_child/p11_child.h | 2 +- src/p11_child/p11_child_common.c | 9 +++-- src/p11_child/p11_child_nss.c | 2 +- src/p11_child/p11_child_openssl.c | 81 +++++++++++++++++++++++++++++++++++++-- 4 files changed, 86 insertions(+), 8 deletions(-) diff --git a/src/p11_child/p11_child.h b/src/p11_child/p11_child.h index dd8fdeafbf947aad930e61ae694bc99df6d8212a..92ecf74a891e46f93e8dee69391bec6325fe2249 100644 --- a/src/p11_child/p11_child.h +++ b/src/p11_child/p11_child.h @@ -54,5 +54,5 @@ bool do_verification_b64(struct p11_ctx *p11_ctx, const char *cert_b64); errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, enum op_mode mode, const char *pin, const char *module_name_in, const char *token_name_in, - const char *key_id_in, char **_multi); + const char *key_id_in, const char *uri, char **_multi); #endif /* __P11_CHILD_H__ */ diff --git a/src/p11_child/p11_child_common.c b/src/p11_child/p11_child_common.c index bc5f6b09b191f0ea853f45d8a78bc6e4a69c3da7..097e7fa07fb4d90e087250aec9f971b4a2afdb52 100644 --- a/src/p11_child/p11_child_common.c +++ b/src/p11_child/p11_child_common.c @@ -60,7 +60,7 @@ static int do_work(TALLOC_CTX *mem_ctx, enum op_mode mode, const char *ca_db, bool wait_for_card, const char *cert_b64, const char *pin, const char *module_name, const char *token_name, - const char *key_id, char **multi) + const char *key_id, const char *uri, char **multi) { int ret; struct p11_ctx *p11_ctx; @@ -90,7 +90,7 @@ static int do_work(TALLOC_CTX *mem_ctx, enum op_mode mode, const char *ca_db, } } else { ret = do_card(mem_ctx, p11_ctx, mode, pin, - module_name, token_name, key_id, multi); + module_name, token_name, key_id, uri, multi); } done: @@ -159,6 +159,7 @@ int main(int argc, const char *argv[]) char *key_id = NULL; char *cert_b64 = NULL; bool wait_for_card = false; + char *uri = NULL; struct poptOption long_options[] = { POPT_AUTOHELP @@ -194,6 +195,8 @@ int main(int argc, const char *argv[]) _("Key ID for authentication"), NULL}, {"certificate", 0, POPT_ARG_STRING, &cert_b64, 0, _("certificate to verify, base64 encoded"), NULL}, + {"uri", 0, POPT_ARG_STRING, &uri, 0, + _("PKCS#11 URI to restrict selection"), NULL}, POPT_TABLEEND }; @@ -367,7 +370,7 @@ int main(int argc, const char *argv[]) } ret = do_work(main_ctx, mode, nss_db, cert_verify_opts, wait_for_card, - cert_b64, pin, module_name, token_name, key_id, &multi); + cert_b64, pin, module_name, token_name, key_id, uri, &multi); if (ret != 0) { DEBUG(SSSDBG_OP_FAILURE, "do_work failed.\n"); goto fail; diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c index fff1f2525878b596e518b717476e892d1cf2ddae..f9cbf3f37a26c7fefe2106aa9db4b006faaf4e1a 100644 --- a/src/p11_child/p11_child_nss.c +++ b/src/p11_child/p11_child_nss.c @@ -480,7 +480,7 @@ bool do_verification_b64(struct p11_ctx *p11_ctx, const char *cert_b64) errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, enum op_mode mode, const char *pin, const char *module_name_in, const char *token_name_in, - const char *key_id_in, char **_multi) + const char *key_id_in, const char *uri, char **_multi) { int ret; SECStatus rv; diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c index 09edeefbdf95e151af97cd4b4e5811569386caec..000e1c94f11edc32abceafb39e98b16ca0664c50 100644 --- a/src/p11_child/p11_child_openssl.c +++ b/src/p11_child/p11_child_openssl.c @@ -85,7 +85,7 @@ static char *get_pkcs11_uri(TALLOC_CTX *mem_ctx, CK_INFO *module_info, memcpy(p11_kit_uri_get_token_info(uri), token_info, sizeof(CK_TOKEN_INFO)); memcpy(p11_kit_uri_get_slot_info(uri), slot_info, sizeof(CK_SLOT_INFO)); - ret = p11_kit_uri_set_slot_id(uri, slot_id); + p11_kit_uri_set_slot_id(uri, slot_id); memcpy(p11_kit_uri_get_module_info(uri), module_info, sizeof(CK_INFO)); @@ -662,7 +662,7 @@ static errno_t wait_for_card(CK_FUNCTION_LIST *module, CK_SLOT_ID *slot_id) errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, enum op_mode mode, const char *pin, const char *module_name_in, const char *token_name_in, - const char *key_id_in, char **_multi) + const char *key_id_in, const char *uri_str, char **_multi) { int ret; size_t c; @@ -674,6 +674,7 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, CK_ULONG num_slots; CK_SLOT_ID slots[MAX_SLOTS]; CK_SLOT_ID slot_id; + CK_SLOT_ID uri_slot_id; CK_SLOT_INFO info; CK_TOKEN_INFO token_info; CK_INFO module_info; @@ -690,6 +691,19 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, char *multi = NULL; bool pkcs11_session = false; bool pkcs11_login = false; + P11KitUri *uri = NULL; + + if (uri_str != NULL) { + uri = p11_kit_uri_new(); + ret = p11_kit_uri_parse(uri_str, P11_KIT_URI_FOR_ANY, uri); + if (ret != P11_KIT_URI_OK) { + DEBUG(SSSDBG_OP_FAILURE, "p11_kit_uri_parse failed [%d][%s].\n", + ret, p11_kit_uri_message(ret)); + ret = EINVAL; + goto done; + } + } + /* Maybe use P11_KIT_MODULE_TRUSTED ? */ modules = p11_kit_modules_load_and_initialize(0); @@ -709,6 +723,23 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, free(mod_name); free(mod_file_name); + if (uri != NULL) { + memset(&module_info, 0, sizeof(CK_INFO)); + rv = modules[c]->C_GetInfo(&module_info); + if (rv != CKR_OK) { + DEBUG(SSSDBG_OP_FAILURE, "C_GetInfo failed.\n"); + ret = EIO; + goto done; + } + + /* Skip modules which do not match the PKCS#11 URI */ + if (p11_kit_uri_match_module_info(uri, &module_info) != 1) { + DEBUG(SSSDBG_TRACE_ALL, + "Not matching URI [%s], skipping.\n", uri_str); + continue; + } + } + num_slots = MAX_SLOTS; rv = modules[c]->C_GetSlotList(CK_FALSE, slots, &num_slots); if (rv != CKR_OK) { @@ -730,6 +761,37 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, info.slotDescription, info.manufacturerID, info.flags, (info.flags & CKF_REMOVABLE_DEVICE) ? "true": "false", (info.flags & CKF_TOKEN_PRESENT) ? "true": "false"); + + /* Skip slots which do not match the PKCS#11 URI */ + if (uri != NULL) { + uri_slot_id = p11_kit_uri_get_slot_id(uri); + if ((uri_slot_id != (CK_SLOT_ID)-1 + && uri_slot_id != slots[s]) + || p11_kit_uri_match_slot_info(uri, &info) != 1) { + DEBUG(SSSDBG_TRACE_ALL, + "Not matching URI [%s], skipping.\n", uri_str); + continue; + } + } + + if ((info.flags & CKF_TOKEN_PRESENT) && uri != NULL) { + rv = modules[c]->C_GetTokenInfo(slots[s], &token_info); + if (rv != CKR_OK) { + DEBUG(SSSDBG_OP_FAILURE, "C_GetTokenInfo failed.\n"); + ret = EIO; + goto done; + } + DEBUG(SSSDBG_TRACE_ALL, "Token label [%s].\n", + token_info.label); + + if (p11_kit_uri_match_token_info(uri, &token_info) != 1) { + DEBUG(SSSDBG_CONF_SETTINGS, + "No matching uri [%s], skipping.\n", uri_str); + continue; + } + + } + if ((info.flags & CKF_REMOVABLE_DEVICE)) { break; } @@ -788,6 +850,13 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, goto done; } + if (uri != NULL && p11_kit_uri_match_token_info(uri, &token_info) != 1) { + DEBUG(SSSDBG_CONF_SETTINGS, "No token matching uri [%s] found.", + uri_str); + ret = ENOENT; + goto done; + } + module_id = c; slot_name = p11_kit_space_strdup(info.slotDescription, sizeof(info.slotDescription)); @@ -891,7 +960,12 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx, } memset(&module_info, 0, sizeof(CK_INFO)); - module->C_GetInfo(&module_info); + rv = module->C_GetInfo(&module_info); + if (rv != CKR_OK) { + DEBUG(SSSDBG_OP_FAILURE, "C_GetInfo failed.\n"); + ret = EIO; + goto done; + } DLIST_FOR_EACH(item, cert_list) { item->uri = get_pkcs11_uri(mem_ctx, &module_info, &info, slot_id, @@ -970,6 +1044,7 @@ done: free(token_name); free(module_file_name); p11_kit_modules_finalize_and_release(modules); + p11_kit_uri_free(uri); return ret; } -- 2.14.4