/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);