Blame SOURCES/0043-p11_child-show-PKCS-11-URI-in-debug-output.patch

71e593
From d931db919e85fda2bfc195403c81b873ca94c4d4 Mon Sep 17 00:00:00 2001
71e593
From: Sumit Bose <sbose@redhat.com>
71e593
Date: Mon, 8 Oct 2018 10:45:28 +0200
71e593
Subject: [PATCH 43/47] p11_child: show PKCS#11 URI in debug output
71e593
71e593
Related to https://pagure.io/SSSD/sssd/issue/3814
71e593
71e593
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
71e593
(cherry picked from commit 46fd681a73ffef062cd027e7018e1a02d7a0a9df)
71e593
---
71e593
 src/p11_child/p11_child_nss.c     | 240 ++++++++++++++++++++++++++++++++++++++
71e593
 src/p11_child/p11_child_openssl.c |  80 +++++++++++++
71e593
 2 files changed, 320 insertions(+)
71e593
71e593
diff --git a/src/p11_child/p11_child_nss.c b/src/p11_child/p11_child_nss.c
71e593
index b2777d1d245d4942263ebf0610eef5cf6a528bd1..fff1f2525878b596e518b717476e892d1cf2ddae 100644
71e593
--- a/src/p11_child/p11_child_nss.c
71e593
+++ b/src/p11_child/p11_child_nss.c
71e593
@@ -39,6 +39,7 @@
71e593
 #include <pk11pub.h>
71e593
 #include <prerror.h>
71e593
 #include <ocsp.h>
71e593
+#include <pkcs11uri.h>
71e593
 
71e593
 #include "util/child_common.h"
71e593
 #include "providers/backend.h"
71e593
@@ -63,6 +64,239 @@ struct p11_ctx {
71e593
                     | certificateUsageStatusResponder \
71e593
                     | certificateUsageSSLCA )
71e593
 
71e593
+
71e593
+static char *get_pkcs11_string(TALLOC_CTX *mem_ctx, const char *in, size_t len)
71e593
+{
71e593
+    size_t c = len;
71e593
+
71e593
+    if (in == NULL || len == 0) {
71e593
+        return NULL;
71e593
+    }
71e593
+
71e593
+    while(c > 0 && in[c - 1] == ' ') {
71e593
+        c--;
71e593
+    }
71e593
+
71e593
+    return talloc_strndup(mem_ctx, in, c);
71e593
+}
71e593
+
71e593
+static char *pct_encode(TALLOC_CTX *mem_ctx, SECItem *data)
71e593
+{
71e593
+    char *pct;
71e593
+    size_t c;
71e593
+    int ret;
71e593
+
71e593
+    pct = talloc_zero_size(mem_ctx, sizeof(char) * (3*data->len + 1));
71e593
+    if (pct == NULL) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_size failed.\n");
71e593
+        return NULL;
71e593
+    }
71e593
+
71e593
+    for (c = 0; c < data->len; c++) {
71e593
+        ret = snprintf(pct + 3*c, 4, "%%%02X", data->data[c]);
71e593
+        if (ret != 3) {
71e593
+            DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n");
71e593
+            talloc_free(pct);
71e593
+            return NULL;
71e593
+        }
71e593
+    }
71e593
+
71e593
+    return pct;
71e593
+}
71e593
+
71e593
+static char *get_key_id_pct(TALLOC_CTX *mem_ctx, PK11SlotInfo *slot,
71e593
+                            CERTCertificate *cert)
71e593
+{
71e593
+    SECItem *key_id = NULL;
71e593
+    char *key_id_str = NULL;
71e593
+
71e593
+    key_id = PK11_GetLowLevelKeyIDForCert(slot, cert, NULL);
71e593
+    if (key_id == NULL) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE,
71e593
+              "PK11_GetLowLevelKeyIDForCert failed [%d][%s].\n",
71e593
+              PR_GetError(), PORT_ErrorToString(PR_GetError()));
71e593
+        return NULL;
71e593
+    }
71e593
+
71e593
+    key_id_str = pct_encode(mem_ctx, key_id);
71e593
+    SECITEM_FreeItem(key_id, PR_TRUE);
71e593
+    if (key_id_str == NULL) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "pct_encode failed.\n");
71e593
+        return NULL;
71e593
+    }
71e593
+
71e593
+    return key_id_str;
71e593
+}
71e593
+
71e593
+static char *get_pkcs11_uri(TALLOC_CTX *mem_ctx, SECMODModule *mod,
71e593
+                            PK11SlotInfo *slot,
71e593
+                            const char *label, CERTCertificate *cert)
71e593
+{
71e593
+    CK_INFO module_info;
71e593
+    CK_SLOT_INFO slot_info;
71e593
+    CK_TOKEN_INFO token_info;
71e593
+    char *values[13];
71e593
+    PK11URIAttribute attrs[13];
71e593
+    size_t nattrs = 0;
71e593
+    SECStatus rv;
71e593
+    char *tmp_str;
71e593
+    char *uri_str;
71e593
+    PK11URI *uri;
71e593
+    CK_SLOT_ID slot_id;
71e593
+    char *id_pct;
71e593
+
71e593
+    rv = PK11_GetModInfo(mod, &module_info);
71e593
+    if (rv != SECSuccess) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "PK11_GetModInfo failed.\n");
71e593
+        return NULL;
71e593
+    }
71e593
+
71e593
+    rv = PK11_GetSlotInfo(slot, &slot_info);
71e593
+    if (rv != SECSuccess) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "PK11_GetSlotInfo failed.\n");
71e593
+        return NULL;
71e593
+    }
71e593
+
71e593
+    rv = PK11_GetTokenInfo(slot, &token_info);
71e593
+    if (rv != SECSuccess) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "PK11_GetTokenInfo failed.\n");
71e593
+        return NULL;
71e593
+    }
71e593
+    values[nattrs] = get_pkcs11_string(mem_ctx,
71e593
+                                       (char *)module_info.libraryDescription,
71e593
+                                       sizeof(module_info.libraryDescription));
71e593
+    if (values[nattrs] != NULL && *values[nattrs] != '\0') {
71e593
+        attrs[nattrs].name = PK11URI_PATTR_LIBRARY_DESCRIPTION;
71e593
+        attrs[nattrs].value = values[nattrs];
71e593
+        nattrs++;
71e593
+    }
71e593
+
71e593
+    values[nattrs] = get_pkcs11_string(mem_ctx,
71e593
+                                       (char *)module_info.manufacturerID,
71e593
+                                       sizeof(module_info.manufacturerID));
71e593
+    if (values[nattrs] != NULL && *values[nattrs] != '\0') {
71e593
+        attrs[nattrs].name = PK11URI_PATTR_LIBRARY_MANUFACTURER;
71e593
+        attrs[nattrs].value = values[nattrs];
71e593
+        nattrs++;
71e593
+    }
71e593
+
71e593
+    values[nattrs] = talloc_asprintf(mem_ctx, "%d.%d",
71e593
+                                     module_info.libraryVersion.major,
71e593
+                                     module_info.libraryVersion.minor);
71e593
+    if (values[nattrs] != NULL && *values[nattrs] != '\0') {
71e593
+        attrs[nattrs].name = PK11URI_PATTR_LIBRARY_VERSION;
71e593
+        attrs[nattrs].value = values[nattrs];
71e593
+        nattrs++;
71e593
+    }
71e593
+
71e593
+    values[nattrs] = get_pkcs11_string(mem_ctx,
71e593
+                                       (char *)slot_info.slotDescription,
71e593
+                                       sizeof(slot_info.slotDescription));
71e593
+    if (values[nattrs] != NULL && *values[nattrs] != '\0') {
71e593
+        attrs[nattrs].name = PK11URI_PATTR_SLOT_DESCRIPTION;
71e593
+        attrs[nattrs].value = values[nattrs];
71e593
+        nattrs++;
71e593
+    }
71e593
+
71e593
+    values[nattrs] = get_pkcs11_string(mem_ctx,
71e593
+                                       (char *)slot_info.manufacturerID,
71e593
+                                       sizeof(slot_info.manufacturerID));
71e593
+    if (values[nattrs] != NULL && *values[nattrs] != '\0') {
71e593
+        attrs[nattrs].name = PK11URI_PATTR_SLOT_MANUFACTURER;
71e593
+        attrs[nattrs].value = values[nattrs];
71e593
+        nattrs++;
71e593
+    }
71e593
+
71e593
+    slot_id = PK11_GetSlotID(slot);
71e593
+    values[nattrs] = talloc_asprintf(mem_ctx, "%d", (int) slot_id);
71e593
+    if (values[nattrs] != NULL && *values[nattrs] != '\0') {
71e593
+        attrs[nattrs].name = PK11URI_PATTR_SLOT_ID;
71e593
+        attrs[nattrs].value = values[nattrs];
71e593
+        nattrs++;
71e593
+    }
71e593
+
71e593
+    values[nattrs] = get_pkcs11_string(mem_ctx, (char *)token_info.model,
71e593
+                                       sizeof(token_info.model));
71e593
+    if (values[nattrs] != NULL && *values[nattrs] != '\0') {
71e593
+        attrs[nattrs].name = PK11URI_PATTR_MODEL;
71e593
+        attrs[nattrs].value = values[nattrs];
71e593
+        nattrs++;
71e593
+    }
71e593
+
71e593
+    values[nattrs] = get_pkcs11_string(mem_ctx,
71e593
+                                       (char *)token_info.manufacturerID,
71e593
+                                       sizeof(token_info.manufacturerID));
71e593
+    if (values[nattrs] != NULL && *values[nattrs] != '\0') {
71e593
+        attrs[nattrs].name = PK11URI_PATTR_MANUFACTURER;
71e593
+        attrs[nattrs].value = values[nattrs];
71e593
+        nattrs++;
71e593
+    }
71e593
+
71e593
+    values[nattrs] = get_pkcs11_string(mem_ctx,
71e593
+                                       (char *)token_info.serialNumber,
71e593
+                                       sizeof(token_info.serialNumber));
71e593
+    if (values[nattrs] != NULL && *values[nattrs] != '\0') {
71e593
+        attrs[nattrs].name = PK11URI_PATTR_SERIAL;
71e593
+        attrs[nattrs].value = values[nattrs];
71e593
+        nattrs++;
71e593
+    }
71e593
+
71e593
+    values[nattrs] = get_pkcs11_string(mem_ctx, (char *)token_info.label,
71e593
+                                       sizeof(token_info.label));
71e593
+    if (values[nattrs] != NULL && *values[nattrs] != '\0') {
71e593
+        attrs[nattrs].name = PK11URI_PATTR_TOKEN;
71e593
+        attrs[nattrs].value = values[nattrs];
71e593
+        nattrs++;
71e593
+    }
71e593
+
71e593
+    if (label != NULL && *label != '\0') {
71e593
+        attrs[nattrs].name = PK11URI_PATTR_OBJECT;
71e593
+        attrs[nattrs].value = label;
71e593
+        nattrs++;
71e593
+    }
71e593
+
71e593
+    attrs[nattrs].name = PK11URI_PATTR_TYPE;
71e593
+    attrs[nattrs].value = "cert";
71e593
+    nattrs++;
71e593
+
71e593
+    uri = PK11URI_CreateURI(attrs, nattrs, NULL, 0);
71e593
+    if (uri == NULL) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "PK11URI_CreateURI failed.\n");
71e593
+        return NULL;
71e593
+    }
71e593
+
71e593
+    tmp_str = PK11URI_FormatURI(NULL, uri);
71e593
+    PK11URI_DestroyURI(uri);
71e593
+    if (tmp_str == NULL) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "PK11URI_FormatURI failed.\n");
71e593
+        return NULL;
71e593
+    }
71e593
+
71e593
+    /* Currently I have no idea how to get the ID properly formatted with the
71e593
+     * NSS  PK11 calls. Since all attribute values are treated as strings zeros
71e593
+     * in the IDs cannot be handled. And the IDs cannot be set percent-encoded
71e593
+     * since all attribute values will be escaped which means the '%' sign
71e593
+     * will be escaped to '%25'. Hence for the time being the ID is added
71e593
+     * manually to the end of the URI. */
71e593
+    id_pct = get_key_id_pct(mem_ctx, slot, cert);
71e593
+    if (id_pct == NULL || *id_pct == '\0') {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "get_key_id_pct failed.\n");
71e593
+        PORT_Free(tmp_str);
71e593
+        return NULL;
71e593
+    }
71e593
+
71e593
+    uri_str = talloc_asprintf(mem_ctx, "%s;%s=%s", tmp_str,
71e593
+                                                   PK11URI_PATTR_ID, id_pct);
71e593
+    talloc_free(id_pct);
71e593
+    if (uri_str == NULL) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
71e593
+        return NULL;
71e593
+    }
71e593
+
71e593
+    return uri_str;
71e593
+
71e593
+}
71e593
+
71e593
 static char *password_passthrough(PK11SlotInfo *slot, PRBool retry, void *arg)
71e593
 {
71e593
   /* give up if 1) no password was supplied, or 2) the password has already
71e593
@@ -465,6 +699,9 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx,
71e593
               cert_list_node->cert->nickname,
71e593
               cert_list_node->cert->subjectName);
71e593
 
71e593
+        DEBUG(SSSDBG_TRACE_ALL, "module uri: %s.\n", PK11_GetModuleURI(module));
71e593
+        DEBUG(SSSDBG_TRACE_ALL, "token uri: %s.\n", PK11_GetTokenURI(slot));
71e593
+
71e593
         if (p11_ctx->handle != NULL) {
71e593
             if (!do_verification(p11_ctx, cert_list_node->cert)) {
71e593
                 DEBUG(SSSDBG_OP_FAILURE,
71e593
@@ -651,6 +888,9 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx,
71e593
 
71e593
         DEBUG(SSSDBG_TRACE_ALL, "Found certificate has key id [%s].\n",
71e593
               key_id_str);
71e593
+        DEBUG(SSSDBG_TRACE_ALL, "uri: %s.\n", get_pkcs11_uri(mem_ctx, module,
71e593
+                                                             slot, label,
71e593
+                                                             found_cert));
71e593
 
71e593
         multi = talloc_asprintf_append(multi, "%s\n%s\n%s\n%s\n%s\n",
71e593
                                        token_name, module_name, key_id_str,
71e593
diff --git a/src/p11_child/p11_child_openssl.c b/src/p11_child/p11_child_openssl.c
71e593
index d4572d99cd3a3186128b46cc4a9453d716bd7979..09edeefbdf95e151af97cd4b4e5811569386caec 100644
71e593
--- a/src/p11_child/p11_child_openssl.c
71e593
+++ b/src/p11_child/p11_child_openssl.c
71e593
@@ -29,6 +29,7 @@
71e593
 #include <openssl/err.h>
71e593
 #include <openssl/rand.h>
71e593
 #include <p11-kit/p11-kit.h>
71e593
+#include <p11-kit/uri.h>
71e593
 
71e593
 #include <popt.h>
71e593
 
71e593
@@ -43,6 +44,72 @@ struct p11_ctx {
71e593
     bool wait_for_card;
71e593
 };
71e593
 
71e593
+
71e593
+static char *get_pkcs11_uri(TALLOC_CTX *mem_ctx, CK_INFO *module_info,
71e593
+                            CK_SLOT_INFO *slot_info, CK_SLOT_ID slot_id,
71e593
+                            CK_TOKEN_INFO *token_info, CK_ATTRIBUTE *label,
71e593
+                            CK_ATTRIBUTE *id)
71e593
+{
71e593
+    P11KitUri *uri;
71e593
+    char *uri_str = NULL;
71e593
+    char *tmp_str = NULL;
71e593
+    int ret;
71e593
+    CK_OBJECT_CLASS cert_class = CKO_CERTIFICATE;
71e593
+    CK_ATTRIBUTE class_attr = {CKA_CLASS, &cert_class, sizeof(CK_OBJECT_CLASS)};
71e593
+
71e593
+    uri = p11_kit_uri_new();
71e593
+    if (uri == NULL) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "p11_kit_uri_new failed.\n");
71e593
+        return NULL;
71e593
+    }
71e593
+
71e593
+    ret = p11_kit_uri_set_attribute(uri, label);
71e593
+    if (ret != P11_KIT_URI_OK) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "p11_kit_uri_set_attribute failed.\n");
71e593
+        goto done;
71e593
+    }
71e593
+
71e593
+    ret = p11_kit_uri_set_attribute(uri, id);
71e593
+    if (ret != P11_KIT_URI_OK) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "p11_kit_uri_set_attribute failed.\n");
71e593
+        goto done;
71e593
+    }
71e593
+
71e593
+    ret = p11_kit_uri_set_attribute(uri, &class_attr);
71e593
+    if (ret != P11_KIT_URI_OK) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "p11_kit_uri_set_attribute failed.\n");
71e593
+        goto done;
71e593
+    }
71e593
+
71e593
+
71e593
+    memcpy(p11_kit_uri_get_token_info(uri), token_info, sizeof(CK_TOKEN_INFO));
71e593
+
71e593
+    memcpy(p11_kit_uri_get_slot_info(uri), slot_info, sizeof(CK_SLOT_INFO));
71e593
+    ret = p11_kit_uri_set_slot_id(uri, slot_id);
71e593
+
71e593
+    memcpy(p11_kit_uri_get_module_info(uri), module_info, sizeof(CK_INFO));
71e593
+
71e593
+    ret = p11_kit_uri_format(uri, P11_KIT_URI_FOR_ANY, &tmp_str);
71e593
+    if (ret != P11_KIT_URI_OK) {
71e593
+        DEBUG(SSSDBG_OP_FAILURE, "p11_kit_uri_format failed [%s].\n",
71e593
+                                 p11_kit_uri_message(ret));
71e593
+        goto done;
71e593
+    }
71e593
+
71e593
+    if (tmp_str != NULL) {
71e593
+        uri_str = talloc_strdup(mem_ctx, tmp_str);
71e593
+        free(tmp_str);
71e593
+        if (uri_str == NULL) {
71e593
+            DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
71e593
+        }
71e593
+    }
71e593
+
71e593
+done:
71e593
+    p11_kit_uri_free(uri);
71e593
+
71e593
+    return uri_str;
71e593
+}
71e593
+
71e593
 static int talloc_cleanup_openssl(struct p11_ctx *p11_ctx)
71e593
 {
71e593
     CRYPTO_cleanup_all_ex_data();
71e593
@@ -234,6 +301,7 @@ struct cert_list {
71e593
     X509 *cert;
71e593
     char *subject_dn;
71e593
     char *cert_b64;
71e593
+    char *uri;
71e593
     CK_KEY_TYPE key_type;
71e593
     CK_OBJECT_HANDLE private_key;
71e593
 };
71e593
@@ -608,6 +676,7 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx,
71e593
     CK_SLOT_ID slot_id;
71e593
     CK_SLOT_INFO info;
71e593
     CK_TOKEN_INFO token_info;
71e593
+    CK_INFO module_info;
71e593
     CK_RV rv;
71e593
     size_t module_id;
71e593
     char *module_file_name = NULL;
71e593
@@ -821,6 +890,17 @@ errno_t do_card(TALLOC_CTX *mem_ctx, struct p11_ctx *p11_ctx,
71e593
         }
71e593
     }
71e593
 
71e593
+    memset(&module_info, 0, sizeof(CK_INFO));
71e593
+    module->C_GetInfo(&module_info);
71e593
+
71e593
+    DLIST_FOR_EACH(item, cert_list) {
71e593
+        item->uri = get_pkcs11_uri(mem_ctx, &module_info, &info, slot_id,
71e593
+                                   &token_info,
71e593
+                                   &item->attributes[1] /* label */,
71e593
+                                   &item->attributes[0] /* id */);
71e593
+        DEBUG(SSSDBG_TRACE_ALL, "uri: %s.\n", item->uri);
71e593
+    }
71e593
+
71e593
     /* TODO: check module_name_in, token_name_in, key_id_in */
71e593
 
71e593
     if (cert_list == NULL) {
71e593
-- 
71e593
2.14.4
71e593