From 3323f9d0a79b8cf8729862f374c60af173b6cefa Mon Sep 17 00:00:00 2001
From: Quanah Gibson-Mount <quanah@openldap.org>
Date: Sun, 12 Dec 2010 01:39:32 +0000
Subject: [PATCH] ITS#6589 allow self-signed server certs

---
 libraries/libldap/tls_m.c | 35 +++++++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/libraries/libldap/tls_m.c b/libraries/libldap/tls_m.c
index 281a244fd3..a0a1233252 100644
--- a/libraries/libldap/tls_m.c
+++ b/libraries/libldap/tls_m.c
@@ -1491,11 +1491,38 @@ tlsm_find_and_verify_cert_key(tlsm_ctx *ctx, PRFileDesc *fd, const char *certnam
 		status = CERT_VerifyCertificateNow( ctx->tc_certdb, cert,
 											checkSig, certUsage,
 											pin_arg, NULL );
-		if (status != SECSuccess) {
+		if ( status != SECSuccess ) {
+			/* NSS doesn't like self-signed CA certs that are also used for 
+			   TLS/SSL server certs (such as generated by openssl req -x509)
+			   CERT_VerifyCertificateNow returns SEC_ERROR_UNTRUSTED_ISSUER in that case
+			   so, see if the cert and issuer are the same cert
+			*/
 			PRErrorCode errcode = PR_GetError();
-			Debug( LDAP_DEBUG_ANY,
-				   "TLS: error: the certificate %s is not valid - error %d:%s\n",
-				   certname, errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
+
+			if ( errcode == SEC_ERROR_UNTRUSTED_ISSUER ) {
+				CERTCertificate *issuer = CERT_FindCertIssuer( cert, PR_Now(), certUsageSSLServer );
+				if ( NULL == issuer ) {
+					/* no issuer - fail */
+					Debug( LDAP_DEBUG_ANY,
+						   "TLS: error: the server certificate %s has no issuer - "
+						   "please check this certificate for validity\n",
+						   certname, 0, 0 );
+				} else if ( CERT_CompareCerts( cert, issuer ) ) {
+					/* self signed - warn and allow */
+					status = SECSuccess;
+					rc = 0;
+					Debug( LDAP_DEBUG_ANY,
+						   "TLS: warning: using self-signed server certificate %s\n",
+						   certname, 0, 0 );
+				}
+				CERT_DestroyCertificate( issuer );
+			}
+
+			if ( status != SECSuccess ) {
+				Debug( LDAP_DEBUG_ANY,
+					   "TLS: error: the certificate %s is not valid - error %d:%s\n",
+					   certname, errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) );
+			}
 		} else {
 			rc = 0; /* success */
 		}
-- 
GitLab