Blob Blame Raw
From 34c120f0259750ff2228def2955de9ad985340e6 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Mon, 26 Aug 2019 22:01:35 +0000
Subject: [PATCH] Remove NOMODDB flag flag from context init, look for full
 tokens

The NSS databases were almost universally initialized with the
NOMODDB flag. I'm not sure if something changed in NSS but the
PKCS#11 modules were not being initialized. Adding this back after
permission checks are done results in tokens working again.

When looking for certs and keys try the full token:nickname string
as well as just nickname when comparing values.

https://pagure.io/certmonger/issue/125
---
 src/casave.c     |  3 +--
 src/certread-n.c | 33 ++++++++++++++++-----------------
 src/certsave-n.c |  5 +++++
 src/dogtag.c     |  3 +--
 src/keygen-n.c   |  5 +++++
 src/keyiread-n.c | 11 ++++++++++-
 src/scepgen-n.c  |  5 +++++
 src/submit-n.c   |  5 +++++
 src/toklist.c    |  2 +-
 9 files changed, 49 insertions(+), 23 deletions(-)

diff --git a/src/casave.c b/src/casave.c
index bde63f99..1cf5a406 100644
--- a/src/casave.c
+++ b/src/casave.c
@@ -111,8 +111,7 @@ cm_casave_main_n(int fd, struct cm_store_ca *ca, struct cm_store_entry *e,
 					break;
 				default:
 					flags = NSS_INIT_READONLY |
-						NSS_INIT_NOROOTINIT |
-						NSS_INIT_NOMODDB;
+						NSS_INIT_NOROOTINIT;
 					/* Sigh.  Not a lot of detail.  Check
 					 * if we succeed in read-only mode,
 					 * which we'll interpret as lack of
diff --git a/src/certread-n.c b/src/certread-n.c
index d535030b..bb61b61b 100644
--- a/src/certread-n.c
+++ b/src/certread-n.c
@@ -157,27 +157,22 @@ cm_certread_n_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry,
 		cm_log(1, "Unable to open NSS database.\n");
 		_exit(status);
 	}
+    /* Re-open the database with modules enabled */
+	NSS_ShutdownContext(ctx);
+	ctx = NSS_InitContext(entry->cm_cert_storage_location,
+			      NULL, NULL, NULL, NULL,
+			      (readwrite ? 0 : NSS_INIT_READONLY) |
+			      NSS_INIT_NOROOTINIT);
 	es = util_n_fips_hook();
 	if (es != NULL) {
 		cm_log(1, "Error putting NSS into FIPS mode: %s\n", es);
 		_exit(CM_SUB_STATUS_ERROR_INITIALIZING);
 	}
-	/* Allocate a memory pool. */
-	arena = PORT_NewArena(sizeof(double));
-	if (arena == NULL) {
-		cm_log(1, "Error opening database '%s'.\n",
-		       entry->cm_cert_storage_location);
-		if (NSS_ShutdownContext(ctx) != SECSuccess) {
-			cm_log(1, "Error shutting down NSS.\n");
-		}
-		_exit(ENOMEM);
-	}
 	/* Find the tokens that we might use for cert storage. */
 	mech = CKM_RSA_X_509;
 	slotlist = PK11_GetAllTokens(mech, PR_FALSE, PR_FALSE, NULL);
 	if (slotlist == NULL) {
 		cm_log(1, "Error getting list of tokens.\n");
-		PORT_FreeArena(arena, PR_TRUE);
 		if (NSS_ShutdownContext(ctx) != SECSuccess) {
 			cm_log(1, "Error shutting down NSS.\n");
 		}
@@ -249,6 +244,7 @@ cm_certread_n_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry,
 		}
 		/* If we need to log in in order to read certificates, do so. */
 		if (PK11_NeedLogin(sle->slot)) {
+			cm_log(3, "Need login to token %s\n", PK11_GetTokenName(sle->slot));
 			if (cm_pin_read_for_cert(entry, &pin) != 0) {
 				cm_log(1, "Error reading PIN for cert db, "
 				       "skipping.\n");
@@ -272,13 +268,19 @@ cm_certread_n_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry,
 		/* Walk the list of certificates in the slot, looking for one
 		 * which matches the specified nickname. */
 		certs = PK11_ListCertsInSlot(sle->slot);
+		cm_log(3, "Looking for %s\n", entry->cm_cert_nickname);
 		if (certs != NULL) {
 			for (node = CERT_LIST_HEAD(certs);
 			     !CERT_LIST_EMPTY(certs) &&
 			     !CERT_LIST_END(node, certs);
 			     node = CERT_LIST_NEXT(node)) {
-				if (strcmp(node->cert->nickname,
-					   entry->cm_cert_nickname) == 0) {
+				cm_log(3, "certread-n: Slot nickname %s\n",
+							node->cert->nickname);
+		        es = talloc_asprintf(entry, "%s:%s",
+					   entry->cm_cert_token, entry->cm_cert_nickname);
+				if ((strcmp(node->cert->nickname,
+					   entry->cm_cert_nickname) == 0) ||
+                    (strcmp(node->cert->nickname, es) == 0)) {
 					cm_log(3, "Located the certificate "
 					       "\"%s\".\n",
 					       entry->cm_cert_nickname);
@@ -321,7 +323,6 @@ next_slot:
 	if (cert == NULL) {
 		cm_log(1, "Error locating certificate.\n");
 		PK11_FreeSlotList(slotlist);
-		PORT_FreeArena(arena, PR_TRUE);
 		if (NSS_ShutdownContext(ctx) != SECSuccess) {
 			cm_log(1, "Error shutting down NSS.\n");
 		}
@@ -332,7 +333,6 @@ next_slot:
 	fclose(fp);
 	CERT_DestroyCertificate(cert);
 	PK11_FreeSlotList(slotlist);
-	PORT_FreeArena(arena, PR_TRUE);
 	if (NSS_ShutdownContext(ctx) != SECSuccess) {
 		cm_log(1, "Error shutting down NSS.\n");
 	}
@@ -358,8 +358,7 @@ cm_certread_n_parse(struct cm_store_entry *entry,
 			      NULL, NULL, NULL, NULL,
 			      NSS_INIT_NOCERTDB |
 			      NSS_INIT_READONLY |
-			      NSS_INIT_NOROOTINIT |
-			      NSS_INIT_NOMODDB);
+			      NSS_INIT_NOROOTINIT);
 	if (ctx == NULL) {
 		cm_log(1, "Unable to initialize NSS.\n");
 		_exit(1);
diff --git a/src/certsave-n.c b/src/certsave-n.c
index 972a1dfa..eda03b34 100644
--- a/src/certsave-n.c
+++ b/src/certsave-n.c
@@ -186,6 +186,11 @@ cm_certsave_n_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry,
 	} else {
 		/* We don't try to force FIPS mode here, as it seems to get in
 		 * the way of saving the certificate. */
+		NSS_ShutdownContext(ctx);
+		ctx = NSS_InitContext(entry->cm_cert_storage_location,
+				      NULL, NULL, NULL, NULL,
+				      (readwrite ? 0 : NSS_INIT_READONLY) |
+				      NSS_INIT_NOROOTINIT);
 
 		/* Allocate a memory pool. */
 		arena = PORT_NewArena(sizeof(double));
diff --git a/src/dogtag.c b/src/dogtag.c
index 55607f3d..c43664ef 100644
--- a/src/dogtag.c
+++ b/src/dogtag.c
@@ -306,8 +306,7 @@ main(int argc, const char **argv)
 			       NULL, NULL, NULL, NULL,
 			       NSS_INIT_NOCERTDB |
 			       NSS_INIT_READONLY |
-			       NSS_INIT_NOROOTINIT |
-			       NSS_INIT_NOMODDB);
+			       NSS_INIT_NOROOTINIT);
 	if (nctx == NULL) {
 		cm_log(1, "Unable to initialize NSS.\n");
 		_exit(1);
diff --git a/src/keygen-n.c b/src/keygen-n.c
index 061bd2af..e921d7ec 100644
--- a/src/keygen-n.c
+++ b/src/keygen-n.c
@@ -226,6 +226,11 @@ cm_keygen_n_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry,
 			break;
 		}
 	}
+	NSS_ShutdownContext(ctx);
+	ctx = NSS_InitContext(entry->cm_key_storage_location,
+			      NULL, NULL, NULL, NULL,
+			      (readwrite ? 0 : NSS_INIT_READONLY) |
+			      NSS_INIT_NOROOTINIT);
 	reason = util_n_fips_hook();
 	if (reason != NULL) {
 		cm_log(1, "Error putting NSS into FIPS mode: %s\n", reason);
diff --git a/src/keyiread-n.c b/src/keyiread-n.c
index 91b1be41..dc1c6092 100644
--- a/src/keyiread-n.c
+++ b/src/keyiread-n.c
@@ -115,6 +115,11 @@ cm_keyiread_n_get_keys(struct cm_store_entry *entry, int readwrite)
 			break;
 		}
 	}
+	NSS_ShutdownContext(ctx);
+	ctx = NSS_InitContext(entry->cm_key_storage_location,
+			      NULL, NULL, NULL, NULL,
+			      (readwrite ? 0 : NSS_INIT_READONLY) |
+			      NSS_INIT_NOROOTINIT);
 	reason = util_n_fips_hook();
 	if (reason != NULL) {
 		cm_log(1, "Error putting NSS into FIPS mode: %s\n", reason);
@@ -340,8 +345,12 @@ cm_keyiread_n_get_keys(struct cm_store_entry *entry, int readwrite)
 			     cnode = CERT_LIST_NEXT(cnode)) {
 				nickname = entry->cm_key_nickname;
 				cert = cnode->cert;
+				es = talloc_asprintf(entry, "%s:%s",
+									         entry->cm_cert_token,
+											 entry->cm_cert_nickname);
 				if ((nickname != NULL) &&
-				    (strcmp(cert->nickname, nickname) == 0)) {
+				    ((strcmp(cert->nickname, nickname) == 0) ||
+					(strcmp(cert->nickname, es) == 0))) {
 					cm_log(3, "Located a certificate with "
 					       "the key's nickname (\"%s\").\n",
 					       nickname);
diff --git a/src/scepgen-n.c b/src/scepgen-n.c
index d6735aa7..8c67b122 100644
--- a/src/scepgen-n.c
+++ b/src/scepgen-n.c
@@ -183,6 +183,11 @@ cm_scepgen_n_main(int fd, struct cm_store_ca *ca, struct cm_store_entry *entry,
 			break;
 		}
 	}
+	NSS_ShutdownContext(ctx);
+	ctx = NSS_InitContext(entry->cm_key_storage_location,
+			      NULL, NULL, NULL, NULL,
+			      NSS_INIT_READONLY |
+			      NSS_INIT_NOROOTINIT);
 	reason = util_n_fips_hook();
 	if (reason != NULL) {
 		cm_log(1, "Error putting NSS into FIPS mode: %s\n", reason);
diff --git a/src/submit-n.c b/src/submit-n.c
index b07ea23a..f27b9c7f 100644
--- a/src/submit-n.c
+++ b/src/submit-n.c
@@ -317,6 +317,11 @@ cm_submit_n_decrypt_envelope(const unsigned char *envelope,
 		}
 		goto done;
 	}
+	NSS_ShutdownContext(ctx);
+	ctx = NSS_InitContext(args->entry->cm_key_storage_location,
+			      NULL, NULL, NULL, NULL,
+			      NSS_INIT_READONLY |
+			      NSS_INIT_NOROOTINIT);
 	reason = util_n_fips_hook();
 	if (reason != NULL) {
 		cm_log(1, "Error putting NSS into FIPS mode: %s\n", reason);
diff --git a/src/toklist.c b/src/toklist.c
index a4328218..ac166722 100644
--- a/src/toklist.c
+++ b/src/toklist.c
@@ -79,7 +79,7 @@ main(int argc, const char **argv)
 
 	/* Open the database. */
 	ctx = NSS_InitContext(dbdir, NULL, NULL, NULL, NULL,
-			      NSS_INIT_NOROOTINIT | NSS_INIT_NOMODDB);
+			      NSS_INIT_NOROOTINIT);
 	if (ctx == NULL) {
 		printf("Unable to open NSS database '%s'.\n", dbdir);
 		_exit(CM_SUB_STATUS_ERROR_INITIALIZING);
-- 
2.21.0