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