Blame SOURCES/openldap-nss-certs-from-certdb-fallback-pem.patch

767ab2
MozNSS: load certificates from certdb, fallback to PEM
767ab2
767ab2
If TLS_CACERT pointed to a PEM file and TLS_CACERTDIR was set to NSS
767ab2
certificate database, the backend assumed that the certificate is always
767ab2
located in the certificate database. This assumption might be wrong.
767ab2
767ab2
This patch makes the library to try to load the certificate from NSS
767ab2
database and fallback to PEM file if unsuccessfull.
767ab2
767ab2
Author: Jan Vcelak <jvcelak@redhat.com>
767ab2
Upstream ITS: #7389
767ab2
Resolves: #857455
767ab2
767ab2
diff --git a/libraries/libldap/tls_m.c b/libraries/libldap/tls_m.c
767ab2
index 6847bea..8339391 100644
767ab2
--- a/libraries/libldap/tls_m.c
767ab2
+++ b/libraries/libldap/tls_m.c
767ab2
@@ -1412,7 +1412,7 @@ tlsm_ctx_load_private_key( tlsm_ctx *ctx )
767ab2
 	/* prefer unlocked key, then key from opened certdb, then any other */
767ab2
 	if ( unlocked_key )
767ab2
 		ctx->tc_private_key = unlocked_key;
767ab2
-	else if ( ctx->tc_certdb_slot )
767ab2
+	else if ( ctx->tc_certdb_slot && !ctx->tc_using_pem )
767ab2
 		ctx->tc_private_key = PK11_FindKeyByDERCert( ctx->tc_certdb_slot, ctx->tc_certificate, pin_arg );
767ab2
 	else
767ab2
 		ctx->tc_private_key = PK11_FindKeyByAnyCert( ctx->tc_certificate, pin_arg );
767ab2
@@ -1909,8 +1909,6 @@ tlsm_deferred_init( void *arg )
767ab2
 				}
767ab2
 				return -1;
767ab2
 			}
767ab2
-
767ab2
-			ctx->tc_using_pem = PR_TRUE;
767ab2
 		}
767ab2
 
767ab2
 		NSS_SetDomesticPolicy();
767ab2
@@ -2363,15 +2361,9 @@ tlsm_deferred_ctx_init( void *arg )
767ab2
 
767ab2
 	/* set up our cert and key, if any */
767ab2
 	if ( lt->lt_certfile ) {
767ab2
-		/* if using the PEM module, load the PEM file specified by lt_certfile */
767ab2
-		/* otherwise, assume this is the name of a cert already in the db */
767ab2
-		if ( ctx->tc_using_pem ) {
767ab2
-			/* this sets ctx->tc_certificate to the correct value */
767ab2
-			int rc = tlsm_add_cert_from_file( ctx, lt->lt_certfile, PR_FALSE );
767ab2
-			if ( rc ) {
767ab2
-				return rc;
767ab2
-			}
767ab2
-		} else {
767ab2
+
767ab2
+		/* first search in certdb (lt_certfile is nickname) */
767ab2
+		if ( ctx->tc_certdb ) {
767ab2
 			char *tmp_certname;
767ab2
 
767ab2
 			if ( tlsm_is_tokenname_certnick( lt->lt_certfile )) {
767ab2
@@ -2391,8 +2383,31 @@ tlsm_deferred_ctx_init( void *arg )
767ab2
 				Debug( LDAP_DEBUG_ANY,
767ab2
 					   "TLS: error: the certificate '%s' could not be found in the database - error %d:%s.\n",
767ab2
 					   lt->lt_certfile, errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
767ab2
+			}
767ab2
+		}
767ab2
+
767ab2
+		/* fallback to PEM module (lt_certfile is filename) */
767ab2
+		if ( !ctx->tc_certificate ) {
767ab2
+			if ( !pem_module && tlsm_init_pem_module() ) {
767ab2
+				int pem_errcode = PORT_GetError();
767ab2
+				Debug( LDAP_DEBUG_ANY,
767ab2
+					   "TLS: fallback to PEM impossible, module cannot be loaded - error %d:%s.\n",
767ab2
+					   pem_errcode, PR_ErrorToString( pem_errcode, PR_LANGUAGE_I_DEFAULT ), 0 );
767ab2
 				return -1;
767ab2
 			}
767ab2
+
767ab2
+			/* this sets ctx->tc_certificate to the correct value */
767ab2
+			if ( !tlsm_add_cert_from_file( ctx, lt->lt_certfile, PR_FALSE ) ) {
767ab2
+				ctx->tc_using_pem = PR_TRUE;
767ab2
+			}
767ab2
+		}
767ab2
+
767ab2
+		if ( ctx->tc_certificate ) {
767ab2
+			Debug( LDAP_DEBUG_ANY,
767ab2
+				   "TLS: certificate '%s' successfully loaded from %s.\n", lt->lt_certfile,
767ab2
+				   ctx->tc_using_pem ? "PEM file" : "moznss database", 0);
767ab2
+		} else {
767ab2
+			return -1;
767ab2
 		}
767ab2
 	}
767ab2