pidgin: 4bfdb2f4: certificate: Better validation of chains...

darkrain42 at pidgin.im darkrain42 at pidgin.im
Sun Jan 30 12:55:49 EST 2011


----------------------------------------------------------------------
Revision: 4bfdb2f4a2c641b32d5e00e30482664d4ec477be
Parent:   3ac33e317365417aff2244c57b8deaaeef7af84a
Author:   darkrain42 at pidgin.im
Date:     01/30/11 12:51:02
Branch:   im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/4bfdb2f4a2c641b32d5e00e30482664d4ec477be

Changelog: 

certificate: Better validation of chains which have an intermediate signed w/ MD5.

We already distribute the CAcert class 3 root as a trusted root.  Newer versions
of GnuTLS (combined with the changes to deal with MSN's cert breakage) require
us to check if the last cert (not just its issuer) is in our trusted store.

Changes against parent 3ac33e317365417aff2244c57b8deaaeef7af84a

  patched  ChangeLog
  patched  libpurple/certificate.c

-------------- next part --------------
============================================================
--- ChangeLog	da4383633b03c5fba06db0b715dd282878f8b11a
+++ ChangeLog	3c92eb62b26929bfd0e16f079786e092f763f9cc
@@ -10,6 +10,8 @@ version 2.7.10 (??/??/????):
 	* Perl bindings now respect LDFLAGS. (Peter Volkov, Markos Chandras)
 	  (#12638)
 	* Added AddTrust External Root CA.  (#11554)
+	* Resolve some issues validating X.509 certificates signed off the CAcert
+	  Class 3 intermediate cert when using the GnuTLS SSL/TLS plugin.
 
 	Groupwise:
 	* Don't show two windows when using "Get Info" on a buddy. (Gabriel Burt;
============================================================
--- libpurple/certificate.c	cd16efb840d7939c18b71fb2f0cd535214d0ced6
+++ libpurple/certificate.c	2fc13f5153c7ac389fe4bf692763ec8bfc9727a7
@@ -1602,7 +1602,7 @@ x509_tls_cached_unknown_peer(PurpleCerti
 	GSList *ca_crts, *cur;
 	GByteArray *last_fpr, *ca_fpr;
 	gboolean valid = FALSE;
-	gchar *ca_id;
+	gchar *ca_id, *ca2_id;
 
 	peer_crt = (PurpleCertificate *) chain->data;
 
@@ -1668,7 +1668,9 @@ x509_tls_cached_unknown_peer(PurpleCerti
 		return;
 	} /* if (signature chain not good) */
 
-	/* Next, attempt to verify the last certificate against a CA */
+	/* Next, attempt to verify the last certificate is signed by a trusted
+	 * CA, or is a trusted CA (based on fingerprint).
+	 */
 	/* If, for whatever reason, there is no Certificate Authority pool
 	   loaded, we'll verify the subject name and then warn about thsi. */
 	if ( !ca ) {
@@ -1684,27 +1686,31 @@ x509_tls_cached_unknown_peer(PurpleCerti
 
 	end_crt = g_list_last(chain)->data;
 
-	/* Attempt to look up the last certificate's issuer */
-	ca_id = purple_certificate_get_issuer_unique_id(end_crt);
+	/* Attempt to look up the last certificate, and the last certificate's
+	 * issuer. 
+	 */
+	ca_id  = purple_certificate_get_issuer_unique_id(end_crt);
+	ca2_id = purple_certificate_get_unique_id(end_crt);
 	purple_debug_info("certificate/x509/tls_cached",
 			  "Checking for a CA with DN=%s\n",
 			  ca_id);
-	ca_crts = x509_ca_get_certs(ca_id);
+	purple_debug_info("certificate/x509/tls_cached",
+			  "Also checking for a CA with DN=%s\n",
+			  ca2_id);
+	ca_crts = g_slist_concat(x509_ca_get_certs(ca_id), x509_ca_get_certs(ca2_id));
+	g_free(ca_id);
+	g_free(ca2_id);
 	if ( NULL == ca_crts ) {
 		flags |= PURPLE_CERTIFICATE_CA_UNKNOWN;
 
 		purple_debug_warning("certificate/x509/tls_cached",
-				  "Certificate Authority with DN='%s' not "
-				  "found. I'll prompt the user, I guess.\n",
-				  ca_id);
-		g_free(ca_id);
+				  "No Certificate Authorities with either DN found "
+				  "found. I'll prompt the user, I guess.\n");
 
 		x509_tls_cached_check_subject_name(vrq, flags);
 		return;
 	}
 
-	g_free(ca_id);
-
 	/*
 	 * Check the fingerprints; if they match, then this certificate *is* one
 	 * of the designated "trusted roots", and we don't need to verify the
@@ -1714,10 +1720,6 @@ x509_tls_cached_unknown_peer(PurpleCerti
 	 *
 	 * If the fingerprints don't match, we'll fall back to checking the
 	 * signature.
-	 *
-	 * GnuTLS doesn't seem to include the final root in the verification
-	 * list, so this check will never succeed.  NSS *does* include it in
-	 * the list, so here we are.
 	 */
 	last_fpr = purple_certificate_get_fingerprint_sha1(end_crt);
 	for (cur = ca_crts; cur; cur = cur->next) {


More information about the Commits mailing list