dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone
Blob Blame History Raw
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