Mercurial > pidgin
changeset 31172:e89df17f5ae7
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.
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Sun, 30 Jan 2011 17:51:02 +0000 |
parents | 78e68751cc40 |
children | 24d62d6f72cc |
files | ChangeLog libpurple/certificate.c |
diffstat | 2 files changed, 19 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/ChangeLog Wed Jan 26 02:58:37 2011 +0000 +++ b/ChangeLog Sun Jan 30 17:51:02 2011 +0000 @@ -10,6 +10,8 @@ * 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;
--- a/libpurple/certificate.c Wed Jan 26 02:58:37 2011 +0000 +++ b/libpurple/certificate.c Sun Jan 30 17:51:02 2011 +0000 @@ -1602,7 +1602,7 @@ 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 @@ 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 @@ 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 @@ * * 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) {