[openldap] prefer key from authenticated slot, allow certificate name with token

jvcelak jvcelak at fedoraproject.org
Mon Aug 20 18:35:54 UTC 2012


commit ad070fca8d1aac32226d38fe84612e14bc8ecc2e
Author: Jan Vcelak <jvcelak at redhat.com>
Date:   Mon Aug 13 15:33:35 2012 +0200

    prefer key from authenticated slot, allow certificate name with token
    
    Resolves TLS failures in replication in 389 Directory Server introduced
    by recent Mozilla NSS backend fixes.

 openldap-nss-allow-certname-with-token-name.patch |   47 ++++++++++++
 openldap-nss-prefer-unlocked-key.patch            |   81 +++++++++++++++++++++
 openldap.spec                                     |   11 +++-
 3 files changed, 138 insertions(+), 1 deletions(-)
---
diff --git a/openldap-nss-allow-certname-with-token-name.patch b/openldap-nss-allow-certname-with-token-name.patch
new file mode 100644
index 0000000..a75e84f
--- /dev/null
+++ b/openldap-nss-allow-certname-with-token-name.patch
@@ -0,0 +1,47 @@
+Accept nss certificate name in the form of tokenname:certnickname
+
+Author: Rich Megginson <rmeggins at redhat.com>
+Upstream ITS: #7360
+
+diff --git a/libraries/libldap/tls_m.c b/libraries/libldap/tls_m.c
+index 5022efb..7377bb1 100644
+--- a/libraries/libldap/tls_m.c
++++ b/libraries/libldap/tls_m.c
+@@ -2102,6 +2102,22 @@ tlsm_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
+ 	return 0;
+ }
+ 
++/* returns true if the given string looks like 
++   "tokenname" ":" "certnickname"
++   This is true if there is a ':' colon character
++   in the string and the colon is not the first
++   or the last character in the string
++*/
++static int
++tlsm_is_tokenname_certnick( const char *certfile )
++{
++	if ( certfile ) {
++		const char *ptr = PL_strchr( certfile, ':' );
++		return ptr && (ptr != certfile) && (*(ptr+1));
++	}
++	return 0;
++}
++
+ static int
+ tlsm_deferred_ctx_init( void *arg )
+ {
+@@ -2268,7 +2284,10 @@ tlsm_deferred_ctx_init( void *arg )
+ 		} else {
+ 			char *tmp_certname;
+ 
+-			if (ctx->tc_certdb_slot) {
++			if (tlsm_is_tokenname_certnick(lt->lt_certfile)) {
++				/* assume already in form tokenname:certnickname */
++				tmp_certname = PL_strdup(lt->lt_certfile);
++			} else if (ctx->tc_certdb_slot) {
+ 				tmp_certname = PR_smprintf(TLSM_CERTDB_DESC_FMT ":%s", ctx->tc_unique, lt->lt_certfile);
+ 			} else {
+ 				tmp_certname = PR_smprintf("%s", lt->lt_certfile);
+-- 
+1.7.11.4
+
diff --git a/openldap-nss-prefer-unlocked-key.patch b/openldap-nss-prefer-unlocked-key.patch
new file mode 100644
index 0000000..89f0701
--- /dev/null
+++ b/openldap-nss-prefer-unlocked-key.patch
@@ -0,0 +1,81 @@
+MozNSS: prefer authenticated slot when getting private key
+
+Author: Jan Vcelak <jvcelak at redhat.com>
+Upstream ITS: #7359
+
+diff --git a/libraries/libldap/tls_m.c b/libraries/libldap/tls_m.c
+index f37da06..5022efb 100644
+--- a/libraries/libldap/tls_m.c
++++ b/libraries/libldap/tls_m.c
+@@ -901,7 +901,7 @@ tlsm_get_pin(PK11SlotInfo *slot, PRBool retry, tlsm_ctx *ctx)
+ 	 * capability the server would have to be started in foreground mode
+ 	 * if using an encrypted key.
+ 	 */
+-	if ( ctx->tc_pin_file ) {
++	if ( ctx && ctx->tc_pin_file ) {
+ 		pwdstr = tlsm_get_pin_from_file( token_name, ctx );
+ 		if (retry && pwdstr != NULL)
+ 			return NULL;
+@@ -990,6 +990,38 @@ tlsm_cert_is_self_issued( CERTCertificate *cert )
+ 	return is_self_issued;
+ }
+ 
++/*
++ * The private key for used certificate can be already unlocked by other
++ * thread or library. Find the unlocked key if possible.
++ */
++static SECKEYPrivateKey *
++tlsm_find_unlocked_key(tlsm_ctx *ctx, void *pin_arg)
++{
++	SECKEYPrivateKey *result = NULL;
++
++	PK11SlotList *slots = PK11_GetAllSlotsForCert(ctx->tc_certificate, NULL);
++	if (!slots) {
++		PRErrorCode errcode = PR_GetError();
++		Debug(LDAP_DEBUG_ANY,
++				"TLS: cannot get all slots for certificate '%s' (error %d: %s)",
++				tlsm_ctx_subject_name(ctx), errcode,
++				PR_ErrorToString(errcode, PR_LANGUAGE_I_DEFAULT));
++		return result;
++	}
++
++	PK11SlotListElement *le;
++	for (le = slots->head; le && !result; le = le->next) {
++		PK11SlotInfo *slot = le->slot;
++		if (!PK11_IsLoggedIn(slot, NULL))
++			continue;
++
++		result = PK11_FindKeyByDERCert(slot, ctx->tc_certificate, pin_arg);
++	}
++
++	PK11_FreeSlotList(slots);
++	return result;
++}
++
+ static SECStatus
+ tlsm_verify_cert(CERTCertDBHandle *handle, CERTCertificate *cert, void *pinarg,
+ 				 PRBool checksig, SECCertificateUsage certUsage, PRBool warn_only,
+@@ -1303,7 +1335,19 @@ tlsm_ctx_load_private_key(tlsm_ctx *ctx)
+ 
+ 	void *pin_arg = SSL_RevealPinArg(ctx->tc_model);
+ 
+-	ctx->tc_private_key = PK11_FindKeyByAnyCert(ctx->tc_certificate, pin_arg);
++	SECKEYPrivateKey *unlocked_key = tlsm_find_unlocked_key(ctx, pin_arg);
++	Debug(LDAP_DEBUG_ANY,
++			"TLS: %s unlocked certificate for certificate '%s'.\n",
++			unlocked_key ? "found" : "no", tlsm_ctx_subject_name(ctx), 0);
++
++	/* prefer unlocked key, then key from opened certdb, then any other */
++	if (unlocked_key)
++		ctx->tc_private_key = unlocked_key;
++	else if (ctx->tc_certdb_slot)
++		ctx->tc_private_key = PK11_FindKeyByDERCert(ctx->tc_certdb_slot, ctx->tc_certificate, pin_arg);
++	else
++		ctx->tc_private_key = PK11_FindKeyByAnyCert(ctx->tc_certificate, pin_arg);
++
+ 	if (!ctx->tc_private_key) {
+ 		PRErrorCode errcode = PR_GetError();
+ 		Debug(LDAP_DEBUG_ANY,
+-- 
+1.7.11.4
+
diff --git a/openldap.spec b/openldap.spec
index 2c329cf..dc80c00 100644
--- a/openldap.spec
+++ b/openldap.spec
@@ -8,7 +8,7 @@
 
 Name: openldap
 Version: 2.4.32
-Release: 1%{?dist}
+Release: 2%{?dist}
 Summary: LDAP support libraries
 Group: System Environment/Daemons
 License: OpenLDAP
@@ -40,6 +40,8 @@ Patch8: openldap-syncrepl-unset-tls-options.patch
 Patch9: openldap-constraint-count.patch
 Patch10: openldap-man-sasl-nocanon.patch
 Patch11: openldap-ai-addrconfig.patch
+Patch12: openldap-nss-prefer-unlocked-key.patch
+Patch13: openldap-nss-allow-certname-with-token-name.patch
 
 # Fedora specific patches
 Patch100: openldap-autoconf-pkgconfig-nss.patch
@@ -153,6 +155,8 @@ ln -s %{_includedir}/nspr4 include/nspr
 %patch9 -p1
 %patch10 -p1
 %patch11 -p1
+%patch12 -p1
+%patch13 -p1
 
 %patch101 -p1
 
@@ -610,6 +614,11 @@ exit 0
 %{evolution_connector_prefix}/
 
 %changelog
+* Mon Aug 20 2012 Jan Vcelak <jvcelak at redhat.com> 2.4.32-2
+- enhancement: TLS, prefer private keys from authenticated slots
+- enhancement: TLS, allow certificate specification including token name
+- resolve TLS failures in replication in 389 Directory Server
+
 * Wed Aug 01 2012 Jan Vcelak <jvcelak at redhat.com> 2.4.32-1
 - new upstream release
   + library: double free, SASL handling


More information about the scm-commits mailing list