/pidgin/main: befb6523dc5c: Fix NSS handling of self-signed cert...

Daniel Atallah datallah at pidgin.im
Fri Oct 31 18:16:58 EDT 2014


Changeset: befb6523dc5cc01bed160bf6c8ea71afcc5e3b5c
Author:	 Daniel Atallah <datallah at pidgin.im>
Date:	 2014-10-31 18:01 -0400
Branch:	 release-2.x.y
URL: https://hg.pidgin.im/pidgin/main/rev/befb6523dc5c

Description:

Fix NSS handling of self-signed certificates. Fixes #16412.

diffstat:

 ChangeLog                       |   5 +++--
 libpurple/plugins/ssl/ssl-nss.c |  34 ++++++++++++++++++++++++----------
 2 files changed, 27 insertions(+), 12 deletions(-)

diffs (86 lines):

diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,8 +1,9 @@
 Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul
 
 version 2.10.11 (?/?/?):
-	Stuff:
-	* Things.
+	General:
+	* Fix handling of Self-Signed SSL/TLS Certificates when using the NSS
+          plugin (#16412)
 
 version 2.10.10 (10/22/14):
 	General:
diff --git a/libpurple/plugins/ssl/ssl-nss.c b/libpurple/plugins/ssl/ssl-nss.c
--- a/libpurple/plugins/ssl/ssl-nss.c
+++ b/libpurple/plugins/ssl/ssl-nss.c
@@ -1044,9 +1044,10 @@ static void x509_verify_cert(PurpleCerti
 	CERTCertDBHandle *certdb = CERT_GetDefaultCertDB();
 	CERTCertificate *crt_dat;
 	PRTime now = PR_Now();
-	SECStatus          rv;
+	SECStatus rv;
 	PurpleCertificate *first_cert = vrq->cert_chain->data;
 	CERTVerifyLog log;
+	gboolean self_signed = FALSE;
 
 	crt_dat = X509_NSS_DATA(first_cert);
 
@@ -1059,6 +1060,14 @@ static void x509_verify_cert(PurpleCerti
 		CERTVerifyLogNode *node   = NULL;
 		unsigned int depth = (unsigned int)-1;
 
+		if (crt_dat->isRoot) {
+			self_signed = TRUE;
+			*flags |= PURPLE_CERTIFICATE_SELF_SIGNED;
+		}
+
+		/* Handling of untrusted, etc. modeled after
+		 * source/security/manager/ssl/src/TransportSecurityInfo.cpp in Firefox
+		 */
 		for (node = log.head; node; node = node->next) {
 			if (depth != node->depth) {
 				depth = node->depth;
@@ -1077,13 +1086,18 @@ static void x509_verify_cert(PurpleCerti
 					break;
 				case SEC_ERROR_UNKNOWN_ISSUER:
 				case SEC_ERROR_UNTRUSTED_ISSUER:
-					if (crt_dat->isRoot) {
-						*flags |= PURPLE_CERTIFICATE_SELF_SIGNED;
-					} else {
+					if (!self_signed) {
 						*flags |= PURPLE_CERTIFICATE_CA_UNKNOWN;
 					}
 					break;
+				case SEC_ERROR_CA_CERT_INVALID:
+				case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
+				case SEC_ERROR_UNTRUSTED_CERT:
 				case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
+					if (!self_signed) {
+						*flags |= PURPLE_CERTIFICATE_INVALID_CHAIN;
+					}
+					break;
 				case SEC_ERROR_BAD_SIGNATURE:
 				default:
 					*flags |= PURPLE_CERTIFICATE_INVALID_CHAIN;
@@ -1091,12 +1105,12 @@ static void x509_verify_cert(PurpleCerti
 			if (node->cert)
 				CERT_DestroyCertificate(node->cert);
 		}
-	} else {
-		rv = CERT_VerifyCertName(crt_dat, vrq->subject_name);
-		if (rv != SECSuccess) {
-			purple_debug_error("nss", "Cert chain valid, but name not verified\n");
-			*flags |= PURPLE_CERTIFICATE_NAME_MISMATCH;
-		}
+	}
+
+	rv = CERT_VerifyCertName(crt_dat, vrq->subject_name);
+	if (rv != SECSuccess) {
+		purple_debug_error("nss", "subject name not verified\n");
+		*flags |= PURPLE_CERTIFICATE_NAME_MISMATCH;
 	}
 
 	PORT_FreeArena(log.arena, PR_FALSE);



More information about the Commits mailing list