andykimpe / rpms / 389-ds-base

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