Blame SOURCES/0060-Ticket-47596-attrcrypt-fails-to-find-unlocked-key.patch

cc3dff
From 7b257e2f72ac674025f894ec5fdcc2eaca34b0a2 Mon Sep 17 00:00:00 2001
cc3dff
From: Rich Megginson <rmeggins@redhat.com>
cc3dff
Date: Fri, 15 Nov 2013 10:24:26 -0700
cc3dff
Subject: [PATCH 60/65] Ticket #47596 attrcrypt fails to find unlocked key
cc3dff
cc3dff
https://fedorahosted.org/389/ticket/47596
cc3dff
Reviewed by: nkinder (Thanks!)
cc3dff
Branch: 389-ds-base-1.3.1
cc3dff
Fix Description: There should always be a pre-authenticated slot/token that
cc3dff
has the servers cert and key.  Just loop through all of the slots that the
cc3dff
server's cert is found on, and use the first one that is authenticated.
cc3dff
Platforms tested: RHEL6 x86_64
cc3dff
Flag Day: no
cc3dff
Doc impact: no
cc3dff
(cherry picked from commit b1fad4e35c0f963bf4678a2ed9a068dbe4fb159c)
cc3dff
(cherry picked from commit cf091de4ae70ad8d683ff33c57e75e58ff900502)
cc3dff
(cherry picked from commit 92b46296c0b4ab9aa436ae09bca95832e2276c6e)
cc3dff
---
cc3dff
 ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c |  2 +-
cc3dff
 ldap/servers/slapd/proto-slap.h               |  1 +
cc3dff
 ldap/servers/slapd/ssl.c                      | 58 +++++++++++++++++++++++++++
cc3dff
 3 files changed, 60 insertions(+), 1 deletion(-)
cc3dff
cc3dff
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
cc3dff
index 09cce9b..f4a5d1a 100644
cc3dff
--- a/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
cc3dff
+++ b/ldap/servers/slapd/back-ldbm/ldbm_attrcrypt.c
cc3dff
@@ -425,7 +425,7 @@ attrcrypt_fetch_private_key(SECKEYPrivateKey **private_key)
cc3dff
         LDAPDebug(LDAP_DEBUG_ANY,"Can't find certificate %s in attrcrypt_fetch_private_key: %d - %s\n", cert_name, errorCode, slapd_pr_strerror(errorCode));
cc3dff
 	}
cc3dff
 	if( cert != NULL ) {
cc3dff
-		key = slapd_pk11_findKeyByAnyCert(cert, NULL);
cc3dff
+		key = slapd_get_unlocked_key_for_cert(cert, NULL);
cc3dff
 	}
cc3dff
 	if (key == NULL) {
cc3dff
                 errorCode = PR_GetError();
cc3dff
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
cc3dff
index 4c1dab9..39c1f54 100644
cc3dff
--- a/ldap/servers/slapd/proto-slap.h
cc3dff
+++ b/ldap/servers/slapd/proto-slap.h
cc3dff
@@ -1012,6 +1012,7 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS);
cc3dff
 int slapd_security_library_is_initialized();
cc3dff
 int slapd_ssl_listener_is_initialized();
cc3dff
 int slapd_SSL_client_auth (LDAP* ld);
cc3dff
+SECKEYPrivateKey *slapd_get_unlocked_key_for_cert(CERTCertificate *cert, void *pin_arg);
cc3dff
 
cc3dff
 /*
cc3dff
  * security_wrappers.c
cc3dff
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
cc3dff
index f515b8e..8b80acb 100644
cc3dff
--- a/ldap/servers/slapd/ssl.c
cc3dff
+++ b/ldap/servers/slapd/ssl.c
cc3dff
@@ -1577,3 +1577,61 @@ char* slapd_get_tmp_dir()
cc3dff
 #endif
cc3dff
 	return ( tmpdir );
cc3dff
 }
cc3dff
+
cc3dff
+SECKEYPrivateKey *
cc3dff
+slapd_get_unlocked_key_for_cert(CERTCertificate *cert, void *pin_arg)
cc3dff
+{
cc3dff
+	SECKEYPrivateKey *key = NULL;
cc3dff
+	PK11SlotListElement *sle;
cc3dff
+	PK11SlotList *slotlist = PK11_GetAllSlotsForCert(cert, NULL);
cc3dff
+	const char *certsubject = cert->subjectName ? cert->subjectName : "unknown cert";
cc3dff
+
cc3dff
+	if (!slotlist) {
cc3dff
+		PRErrorCode errcode = PR_GetError();
cc3dff
+		slapi_log_error(SLAPI_LOG_FATAL, "slapd_get_unlocked_key_for_cert",
cc3dff
+				"Error: cannot get slot list for certificate [%s] (%d: %s)\n",
cc3dff
+				certsubject, errcode, slapd_pr_strerror(errcode));
cc3dff
+		return key;
cc3dff
+	}
cc3dff
+
cc3dff
+	for (sle = slotlist->head; sle; sle = sle->next) {
cc3dff
+		PK11SlotInfo *slot = sle->slot;
cc3dff
+		const char *slotname = (slot && PK11_GetSlotName(slot)) ? PK11_GetSlotName(slot) : "unknown slot";
cc3dff
+		const char *tokenname = (slot && PK11_GetTokenName(slot)) ? PK11_GetTokenName(slot) : "unknown token";
cc3dff
+		if (!slot) {
cc3dff
+			slapi_log_error(SLAPI_LOG_TRACE, "slapd_get_unlocked_key_for_cert",
cc3dff
+					"Missing slot for slot list element for certificate [%s]\n",
cc3dff
+					certsubject);
cc3dff
+		} else if (PK11_IsLoggedIn(slot, pin_arg)) {
cc3dff
+			key = PK11_FindKeyByDERCert(slot, cert, pin_arg);
cc3dff
+			slapi_log_error(SLAPI_LOG_TRACE, "slapd_get_unlocked_key_for_cert",
cc3dff
+					"Found unlocked slot [%s] token [%s] for certificate [%s]\n",
cc3dff
+					slotname, tokenname, certsubject);
cc3dff
+			break;
cc3dff
+		} else {
cc3dff
+			slapi_log_error(SLAPI_LOG_TRACE, "slapd_get_unlocked_key_for_cert",
cc3dff
+					"Skipping locked slot [%s] token [%s] for certificate [%s]\n",
cc3dff
+					slotname, tokenname, certsubject);
cc3dff
+		}
cc3dff
+	}
cc3dff
+
cc3dff
+	if (!key) {
cc3dff
+		slapi_log_error(SLAPI_LOG_FATAL, "slapd_get_unlocked_key_for_cert",
cc3dff
+				"Error: could not find any unlocked slots for certificate [%s].  "
cc3dff
+		                "Please review your TLS/SSL configuration.  The following slots were found:\n",
cc3dff
+		                certsubject);
cc3dff
+		for (sle = slotlist->head; sle; sle = sle->next) {
cc3dff
+			PK11SlotInfo *slot = sle->slot;
cc3dff
+			const char *slotname = (slot && PK11_GetSlotName(slot)) ? PK11_GetSlotName(slot) : "unknown slot";
cc3dff
+			const char *tokenname = (slot && PK11_GetTokenName(slot)) ? PK11_GetTokenName(slot) : "unknown token";
cc3dff
+			slapi_log_error(SLAPI_LOG_FATAL, "slapd_get_unlocked_key_for_cert",
cc3dff
+					"Slot [%s] token [%s] was locked.\n",
cc3dff
+					slotname, tokenname);
cc3dff
+		}
cc3dff
+
cc3dff
+	}
cc3dff
+
cc3dff
+	PK11_FreeSlotList(slotlist);
cc3dff
+	return key;
cc3dff
+}
cc3dff
+
cc3dff
-- 
cc3dff
1.8.1.4
cc3dff