/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