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

Daniel Atallah <[email protected]>
Newsgroups gmane.comp.gnome.gaim.cvs
Message-ID <[email protected]>
Changeset: befb6523dc5cc01bed160bf6c8ea71afcc5e3b5c
Author:	 Daniel Atallah <[email protected]>
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);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.