From d0830a4445115ef4cdbc8b524794f276f7954f7a Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
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 <jhrozek@redhat.com>
(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