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

Mark Doliner <[email protected]>
Newsgroups gmane.comp.gnome.gaim.cvs
Message-ID <[email protected]>
Changeset: 4721e2194afad6bbbcd27782fff923264916565b
Author:	 Mark Doliner <[email protected]>
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/[email protected]                          |    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/[email protected]                       |    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/[email protected]                          |   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);
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.