/pidgin/main: 4721e2194afa: Merge changes from the release-2.x.y...

Mark Doliner mark at kingant.net
Fri Oct 24 02:28:16 EDT 2014


Changeset: 4721e2194afad6bbbcd27782fff923264916565b
Author:	 Mark Doliner <mark at kingant.net>
Date:	 2014-10-23 22:57 -0700
Branch:	 default
URL: https://hg.pidgin.im/pidgin/main/rev/4721e2194afa

Description:

Merge changes from the release-2.x.y branch into master.

Merging the certificate and ssl changes was difficult. Lots of conflicts.

diffstat:

 .hgtags                                 |      1 +
 COPYRIGHT                               |      1 +
 ChangeLog                               |     27 +-
 ChangeLog.API                           |      3 +
 libpurple/certificate.c                 |     34 +-
 libpurple/certificate.h                 |     62 +
 libpurple/plugins/ssl/ssl-gnutls.c      |     37 +-
 libpurple/plugins/ssl/ssl-nss.c         |    116 +-
 libpurple/protocols/gg/lib/protobuf-c.c |      4 +
 libpurple/protocols/jabber/jutil.c      |      6 +-
 po/af.po                                |   2718 +-----
 po/am.po                                |   6984 +++++-----------
 po/ar.po                                |   4571 ++--------
 po/as.po                                |   5472 +-----------
 po/ast.po                               |    374 +-
 po/az.po                                |   6500 ++++----------
 po/be at latin.po                          |    404 +-
 po/bg.po                                |   8072 +++++-------------
 po/bn.po                                |   3200 +------
 po/bn_IN.po                             |   2313 +----
 po/brx.po                               |   6865 +--------------
 po/bs.po                                |  10070 ++++++-----------------
 po/ca.po                                |   4156 +---------
 po/ca at valencia.po                       |    875 +-
 po/cs.po                                |   3108 +------
 po/dz.po                                |   8567 ++++---------------
 po/el.po                                |    375 +-
 po/en_AU.po                             |  12632 +++++++++--------------------
 po/en_CA.po                             |    397 +-
 po/en_GB.po                             |    369 +-
 po/eo.po                                |   2605 +----
 po/es.po                                |   2365 +-----
 po/es_AR.po                             |  10161 +++++------------------
 po/et.po                                |    380 +-
 po/eu.po                                |   4222 +--------
 po/fa.po                                |     87 +-
 po/fi.po                                |   5249 +-----------
 po/fr.po                                |   1459 +--
 po/ga.po                                |    390 +-
 po/gl.po                                |   3070 +-----
 po/gu.po                                |   1759 +---
 po/he.po                                |    370 +-
 po/hi.po                                |   2296 +----
 po/hr.po                                |    444 +-
 po/hu.po                                |    778 +-
 po/id.po                                |   6202 +++-----------
 po/it.po                                |   1386 +--
 po/ja.po                                |   4386 ++--------
 po/ka.po                                |   5987 ++++---------
 po/kk.po                                |   8025 ++----------------
 po/km.po                                |    359 +-
 po/kn.po                                |   2857 +-----
 po/ko.po                                |   6556 +++-----------
 po/ks.po                                |   6865 +--------------
 po/ku.po                                |   8191 ++++--------------
 po/lt.po                                |    426 +-
 po/lv.po                                |   8553 +++----------------
 po/mhr.po                               |    399 +-
 po/mk.po                                |   5150 ++---------
 po/ml.po                                |   2306 +----
 po/mn.po                                |   3570 ++------
 po/mr.po                                |   1855 +---
 po/my_MM.po                             |    374 +-
 po/nb.po                                |   4065 ++-------
 po/ne.po                                |   9975 ++++++-----------------
 po/nl.po                                |    394 +-
 po/nn.po                                |    401 +-
 po/oc.po                                |    706 +-
 po/or.po                                |   1859 +---
 po/pa.po                                |    370 +-
 po/ps.po                                |   4024 ++------
 po/pt.po                                |    381 +-
 po/pt_BR.po                             |   2618 +-----
 po/ro.po                                |    600 +-
 po/ru.po                                |   2336 +----
 po/sd.po                                |   6865 +--------------
 po/si.po                                |   2122 +---
 po/sk.po                                |   2875 +------
 po/sl.po                                |    417 +-
 po/sq.po                                |   1474 +-
 po/sr.po                                |   4809 ++--------
 po/sr at latin.po                          |   4807 ++--------
 po/sv.po                                |   2863 +-----
 po/sw.po                                |   4092 +++------
 po/ta.po                                |   3450 +-------
 po/te.po                                |   1763 +---
 po/th.po                                |   5268 +++--------
 po/tr.po                                |   5363 +++---------
 po/tt.po                                |   7007 +--------------
 po/uk.po                                |    607 +-
 po/ur.po                                |   6274 +++-----------
 po/uz.po                                |   8383 +++----------------
 po/vi.po                                |   1613 +---
 po/xh.po                                |  10387 ++++++------------------
 po/zh_CN.po                             |   2585 +-----
 po/zh_HK.po                             |   2422 +-----
 po/zh_TW.po                             |   2420 +-----
 97 files changed, 70213 insertions(+), 242777 deletions(-)

diffs (truncated from 579983 to 300 lines):

diff --git a/.hgtags b/.hgtags
--- a/.hgtags
+++ b/.hgtags
@@ -89,3 +89,4 @@ 4992bd90d8ad78ebdd324dd90d3e9d443f7dd002
 ad7e7fb98db3bbd7bf9ab49072fd34cd4fa25dd9 v2.10.7
 5010e6877abce3bfc2a4912e6b38fed7d6d3df19 v2.10.8
 9438f4b2904d9574b9e6ffba463d354b3661139f v2.10.9
+b7fedd2a570b760f252cf8a65a584137ab0af2cb v2.10.10
diff --git a/COPYRIGHT b/COPYRIGHT
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -164,6 +164,7 @@ William Ehlhardt
 Markus Elfring
 Nelson Elhage
 Ignacio J. Elia
+Kai Engert
 Brian Enigma
 Mattias Eriksson
 Pat Erley
diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -75,10 +75,18 @@ version 3.0.0 (??/??/????):
 	* The Offline Message Emulation plugin now adds a note that the message
 	  was an offline message. (Flavius Anton) (#2497)
 
-version 2.10.10 (?/?/?):
+version 2.10.10 (10/22/14):
 	General:
-	* Allow and prefer TLS 1.2 and 1.1 when using libnss. (Elrond and
-	  Ashish Gupta) (#15909)
+	* Check the basic constraints extension when validating SSL/TLS
+	  certificates. This fixes a security hole that allowed a malicious
+	  man-in-the-middle to impersonate an IM server or any other https
+	  endpoint. This affected both the NSS and GnuTLS plugins. (Discovered
+	  by an anonymous person and Jacob Appelbaum of the Tor Project, with
+	  thanks to Moxie Marlinspike for first publishing about this type of
+	  vulnerability. Thanks to Kai Engert for guidance and for some of the
+	  NSS changes) (CVE-2014-3694)
+	* Allow and prefer TLS 1.2 and 1.1 when using the NSS plugin for SSL.
+	  (Elrond and Ashish Gupta) (#15909)
 
 	libpurple3 compatibility:
 	* Encrypted account passwords are preserved until the new one is set.
@@ -87,7 +95,7 @@ version 2.10.10 (?/?/?):
 	Windows-Specific Changes:
 	* Don't allow overwriting arbitrary files on the file system when the
 	  user installs a smiley theme via drag-and-drop. (Discovered by Yves
-	  Younan of Sourcefire VRT)
+	  Younan of Cisco Talos) (CVE-2014-3697)
 	* Updates to dependencies:
 		* NSS 3.17.1 and NSPR 4.10.7
 
@@ -100,7 +108,7 @@ version 2.10.10 (?/?/?):
 	Groupwise:
 	* Fix potential remote crash parsing server message that indicates that
 	  a large amount of memory should be allocated. (Discovered by Yves Younan
-	  and Richard Johnson of Sourcefire VRT) (CVE-2014-NNNN)
+	  and Richard Johnson of Cisco Talos) (CVE-2014-3696)
 
 	IRC:
 	* Fix a possible leak of unencrypted data when using /me command
@@ -108,10 +116,15 @@ version 2.10.10 (?/?/?):
 
 	MXit:
 	* Fix potential remote crash parsing a malformed emoticon response.
-	  (Discovered by Yves Younan and Richard Johnson of Sourcefire VRT)
-	  (CVE-2014-NNNN)
+	  (Discovered by Yves Younan and Richard Johnson of Cisco Talos)
+	  (CVE-2014-3695)
 
 	XMPP:
+	* Fix potential information leak where a malicious XMPP server and
+	  possibly even a malicious remote user could create a carefully crafted
+	  XMPP message that causes libpurple to send an XMPP message containing
+	  arbitrary memory. (Discovered and fixed by Thijs Alkemade and Paul
+	  Aurich) (CVE-2014-3698)
 	* Fix Facebook XMPP roster quirks. (#15041, #15957)
 
 	Yahoo:
diff --git a/ChangeLog.API b/ChangeLog.API
--- a/ChangeLog.API
+++ b/ChangeLog.API
@@ -509,6 +509,9 @@ version 3.0.0 (??/??/????):
 		* _GntTreeColumnFlag
 		* _GntWidgetFlags
 
+version 2.10.10:
+	* No changes
+
 version 2.10.9:
 	* No changes
 
diff --git a/libpurple/certificate.c b/libpurple/certificate.c
--- a/libpurple/certificate.c
+++ b/libpurple/certificate.c
@@ -861,10 +861,11 @@ static GList *x509_ca_certs = NULL;
 /* Used for lazy initialization purposes. */
 static gboolean x509_ca_initialized = FALSE;
 
-/* Adds a certificate to the in-memory cache, doing nothing else */
+/* Adds a certificate to the in-memory cache, and mark it as trusted */
 static gboolean
 x509_ca_quiet_put_cert(PurpleCertificate *crt)
 {
+	gboolean ret;
 	x509_ca_element *el;
 
 	/* lazy_init calls this function, so calling lazy_init here is a
@@ -876,12 +877,20 @@ x509_ca_quiet_put_cert(PurpleCertificate
 	/* TODO: Perhaps just check crt->scheme->name instead? */
 	g_return_val_if_fail(crt->scheme == purple_certificate_find_scheme(x509_ca.scheme_name), FALSE);
 
-	el = g_new0(x509_ca_element, 1);
-	el->dn = purple_certificate_get_unique_id(crt);
-	el->crt = purple_certificate_copy(crt);
-	x509_ca_certs = g_list_prepend(x509_ca_certs, el);
+	ret = TRUE;
 
-	return TRUE;
+	if (crt->scheme->register_trusted_tls_cert) {
+		ret = (crt->scheme->register_trusted_tls_cert)(crt, TRUE);
+	}
+
+	if (ret) {
+		el = g_new0(x509_ca_element, 1);
+		el->dn = purple_certificate_get_unique_id(crt);
+		el->crt = purple_certificate_copy(crt);
+		x509_ca_certs = g_list_prepend(x509_ca_certs, el);
+	}
+
+	return ret;
 }
 
 /* Since the libpurple CertificatePools get registered before plugins are
@@ -1018,6 +1027,7 @@ x509_ca_uninit(void)
 	g_list_free(x509_ca_certs);
 	x509_ca_certs = NULL;
 	x509_ca_initialized = FALSE;
+	/** TODO: the cert store in the SSL implementation wouldn't be cleared by this */
 	g_list_foreach(x509_ca_paths, (GFunc)g_free, NULL);
 	g_list_free(x509_ca_paths);
 	x509_ca_paths = NULL;
@@ -1276,6 +1286,10 @@ x509_tls_peers_put_cert(const gchar *id,
 	keypath = purple_certificate_pool_mkpath(&x509_tls_peers, id);
 	ret = purple_certificate_export(keypath, crt);
 
+	if (crt->scheme->register_trusted_tls_cert) {
+		ret = (crt->scheme->register_trusted_tls_cert)(crt, FALSE);
+	}
+
 	g_free(keypath);
 	return ret;
 }
@@ -1628,6 +1642,14 @@ x509_tls_cached_unknown_peer(PurpleCerti
 
 	peer_crt = (PurpleCertificate *) chain->data;
 
+	if (peer_crt->scheme->verify_cert) {
+		/** Make sure we've loaded the CA certs (which causes NSS to trust them) */
+		g_return_if_fail(x509_ca_lazy_init());
+		peer_crt->scheme->verify_cert(vrq, &flags);
+		x509_tls_cached_complete(vrq, flags);
+		return;
+	}
+
 	/* TODO: Figure out a way to check for a bad signature, as opposed to
 	   "not self-signed" */
 	if ( purple_certificate_signed_by(peer_crt, peer_crt) ) {
diff --git a/libpurple/certificate.h b/libpurple/certificate.h
--- a/libpurple/certificate.h
+++ b/libpurple/certificate.h
@@ -79,6 +79,52 @@ typedef enum
 	PURPLE_CERTIFICATE_LAST = 0x80000,
 } PurpleCertificateVerificationStatus;
 
+/*
+ * TODO: Merge this with PurpleCertificateVerificationStatus for 3.0.0
+ */
+typedef enum {
+	PURPLE_CERTIFICATE_UNKNOWN_ERROR = -1,
+
+	/* Not an error */
+	PURPLE_CERTIFICATE_NO_PROBLEMS = 0,
+
+	/* Non-fatal */
+	PURPLE_CERTIFICATE_NON_FATALS_MASK = 0x0000FFFF,
+
+	/* The certificate is self-signed. */
+	PURPLE_CERTIFICATE_SELF_SIGNED = 0x01,
+
+	/* The CA is not in libpurple's pool of certificates. */
+	PURPLE_CERTIFICATE_CA_UNKNOWN = 0x02,
+
+	/* The current time is before the certificate's specified
+	 * activation time.
+	 */
+	PURPLE_CERTIFICATE_NOT_ACTIVATED = 0x04,
+
+	/* The current time is after the certificate's specified expiration time */
+	PURPLE_CERTIFICATE_EXPIRED = 0x08,
+
+	/* The certificate's subject name doesn't match the expected */
+	PURPLE_CERTIFICATE_NAME_MISMATCH = 0x10,
+
+	/* No CA pool was found. This shouldn't happen... */
+	PURPLE_CERTIFICATE_NO_CA_POOL = 0x20,
+
+	/* Fatal */
+	PURPLE_CERTIFICATE_FATALS_MASK = 0xFFFF0000,
+
+	/* The signature chain could not be validated. Due to limitations in the
+	 * the current API, this also indicates one of the CA certificates in the
+	 * chain is expired (or not yet activated). FIXME 3.0.0 */
+	PURPLE_CERTIFICATE_INVALID_CHAIN = 0x10000,
+
+	/* The signature has been revoked. */
+	PURPLE_CERTIFICATE_REVOKED = 0x20000,
+
+	PURPLE_CERTIFICATE_LAST = 0x40000,
+} PurpleCertificateInvalidityFlags;
+
 #define PURPLE_TYPE_CERTIFICATE   (purple_certificate_get_type())
 typedef struct _PurpleCertificate PurpleCertificate;
 
@@ -256,6 +302,9 @@ struct _PurpleCertificateScheme
 	PurpleCertificate * (* copy_certificate)(PurpleCertificate *crt);
 	void (* destroy_certificate)(PurpleCertificate * crt);
 
+	/** Find whether "crt" has a valid signature from "issuer," including
+	 * appropriate values for the CA flag in the basic constraints extension.
+	 *  @see purple_certificate_signed_by() */
 	gboolean (*signed_by)(PurpleCertificate *crt, PurpleCertificate *issuer);
 	GByteArray * (* get_fingerprint_sha1)(PurpleCertificate *crt);
 	gchar * (* get_unique_id)(PurpleCertificate *crt);
@@ -269,8 +318,21 @@ struct _PurpleCertificateScheme
 	GSList * (* import_certificates)(const gchar * filename);
 	GByteArray * (* get_der_data)(PurpleCertificate *crt);
 
+	/**
+	 * Register a certificate as "trusted."
+	 */
+	gboolean (* register_trusted_tls_cert)(PurpleCertificate *crt, gboolean ca);
+
+	/**
+	 * Verify that a certificate is valid, performing all necessary checks
+	 * including date range, valid cert chain, recognized and valid CAs, etc.
+	 */
+	void (* verify_cert)(PurpleCertificateVerificationRequest *vrq, PurpleCertificateInvalidityFlags *flags);
+
 	/*< private >*/
 	void (*_purple_reserved1)(void);
+	void (*_purple_reserved2)(void);
+	void (*_purple_reserved3)(void);
 };
 
 /**
diff --git a/libpurple/plugins/ssl/ssl-gnutls.c b/libpurple/plugins/ssl/ssl-gnutls.c
--- a/libpurple/plugins/ssl/ssl-gnutls.c
+++ b/libpurple/plugins/ssl/ssl-gnutls.c
@@ -1024,7 +1024,7 @@ x509_certificate_signed_by(PurpleCertifi
 	crt_dat = X509_GET_GNUTLS_DATA(crt);
 	issuer_dat = X509_GET_GNUTLS_DATA(issuer);
 
-	/* First, let's check that crt.issuer is actually issuer */
+	/* Ensure crt issuer matches the name on the issuer cert. */
 	ret = gnutls_x509_crt_check_issuer(crt_dat, issuer_dat);
 	if (ret <= 0) {
 
@@ -1053,6 +1053,41 @@ x509_certificate_signed_by(PurpleCertifi
 		return FALSE;
 	}
 
+	/* Check basic constraints extension (if it exists then the CA flag must
+	   be set to true, and it must exist for certs with version 3 or higher. */
+	ret = gnutls_x509_crt_get_basic_constraints(issuer_dat, NULL, NULL, NULL);
+	if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) {
+		if (gnutls_x509_crt_get_version(issuer_dat) >= 3) {
+			/* Reject cert (no basic constraints and cert version is >= 3). */
+			gchar *issuer_id = purple_certificate_get_unique_id(issuer);
+			purple_debug_info("gnutls/x509", "Rejecting cert because the "
+					"basic constraints extension is missing from issuer cert "
+					"for %s. The basic constraints extension is required on "
+					"all version 3 or higher certs (this cert is version %d).",
+					issuer_id ? issuer_id : "(null)",
+					gnutls_x509_crt_get_version(issuer_dat));
+			g_free(issuer_id);
+			return FALSE;
+		} else {
+			/* Allow cert (no basic constraints and cert version is < 3). */
+			purple_debug_info("gnutls/x509", "Basic constraint extension is "
+					"missing from issuer cert for %s. Allowing this because "
+					"the cert is version %d and the basic constraints "
+					"extension is only required for version 3 or higher "
+					"certs.", issuer_id ? issuer_id : "(null)",
+					gnutls_x509_crt_get_version(issuer_dat));
+		}
+	} else if (ret <= 0) {
+		/* Reject cert (CA flag is false in basic constraints). */
+		gchar *issuer_id = purple_certificate_get_unique_id(issuer);



More information about the Commits mailing list