From 2cf4bbb22209c1cddd8366fa6102e181fcdd29de Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Oct 30 2018 06:17:31 +0000 Subject: import empathy-3.12.13-1.el7 --- diff --git a/.empathy.metadata b/.empathy.metadata index c710cfc..f242029 100644 --- a/.empathy.metadata +++ b/.empathy.metadata @@ -1 +1 @@ -971aa8cce3f9aa3e0815a831d0e99c55ade1ce87 SOURCES/empathy-3.12.12.tar.xz +312f942c38ac8d3582b04e2a07641dfb9278259a SOURCES/empathy-3.12.13.tar.xz diff --git a/.gitignore b/.gitignore index 4217207..643e349 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/empathy-3.12.12.tar.xz +SOURCES/empathy-3.12.13.tar.xz diff --git a/SOURCES/empathy-fix-certificate-validation.patch b/SOURCES/empathy-fix-certificate-validation.patch new file mode 100644 index 0000000..2302d94 --- /dev/null +++ b/SOURCES/empathy-fix-certificate-validation.patch @@ -0,0 +1,1042 @@ +From 7712a50a4c3dfecda6b6401ba5a9dff52a583ecb Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Wed, 15 Mar 2017 20:23:43 +0100 +Subject: [PATCH 1/5] tls-verifier: Handle GNUTLS_CERT_REVOKED + +... by mapping it to TP_TLS_CERTIFICATE_REJECT_REASON_REVOKED. + +https://bugzilla.gnome.org/show_bug.cgi?id=780160 +--- + libempathy/empathy-tls-verifier.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/libempathy/empathy-tls-verifier.c b/libempathy/empathy-tls-verifier.c +index fcbc559b3f97..8f80b4372de1 100644 +--- a/libempathy/empathy-tls-verifier.c ++++ b/libempathy/empathy-tls-verifier.c +@@ -98,6 +98,8 @@ verification_output_to_reason (gint res, + *reason = TP_TLS_CERTIFICATE_REJECT_REASON_NOT_ACTIVATED; + else if (verify_output & GNUTLS_CERT_EXPIRED) + *reason = TP_TLS_CERTIFICATE_REJECT_REASON_EXPIRED; ++ else if (verify_output & GNUTLS_CERT_REVOKED) ++ *reason = TP_TLS_CERTIFICATE_REJECT_REASON_REVOKED; + else + *reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN; + +-- +2.14.4 + + +From 8c5dc77f406308b77b4a6c7274ff8096091267a6 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Mon, 20 Mar 2017 19:20:11 +0100 +Subject: [PATCH 2/5] tests: Fix comment + +The existing comment was mistakenly copied from +test_certificate_verify_success_with_full_chain. + +This test case is about a certificate that has been pinned against a +specific peer. The mock TLS connection doesn't have the full chain, +but just the leaf-level certificate that has been pinned. + +https://bugzilla.gnome.org/show_bug.cgi?id=780160 +--- + tests/empathy-tls-test.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/empathy-tls-test.c b/tests/empathy-tls-test.c +index 91b05761f9b9..0752e1b328c5 100644 +--- a/tests/empathy-tls-test.c ++++ b/tests/empathy-tls-test.c +@@ -654,8 +654,8 @@ test_certificate_verify_success_with_pinned (Test *test, + }; + + /* +- * In this test the mock TLS connection has a full certificate +- * chain. We look for an anchor certificate in the chain. ++ * In this test the mock TLS connection has a certificate that has ++ * been pinned for the test-server.empathy.gnome.org peer. + */ + + test->mock = mock_tls_certificate_new_and_register (test->dbus, +-- +2.14.4 + + +From 6fe06a78a7538cefa2333b180d58b330325796ab Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Mon, 20 Mar 2017 19:31:39 +0100 +Subject: [PATCH 3/5] tests: Actually test that hostnames of pinned + certificates are verified + +This test case is about ensuring that a pinned certificate won't be +validated if the wrong hostname is used. + +If we don't add the pinned certificate to our database, then checks for +pinning are going to fail regardless of the hostname being used. The +correct certificate-hostname pair needs to be in the database to ensure +that the hostnames are being matched as advertised. + +https://bugzilla.gnome.org/show_bug.cgi?id=780160 +--- + tests/empathy-tls-test.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/tests/empathy-tls-test.c b/tests/empathy-tls-test.c +index 0752e1b328c5..422909e7cc2a 100644 +--- a/tests/empathy-tls-test.c ++++ b/tests/empathy-tls-test.c +@@ -695,7 +695,8 @@ test_certificate_verify_pinned_wrong_host (Test *test, + test->mock = mock_tls_certificate_new_and_register (test->dbus, + "server-cert.cer", NULL); + +- /* Note that we're not adding any place to find root certs */ ++ /* We add the collabora directory with the collabora root */ ++ add_certificate_to_mock (test, "server-cert.cer", "test-server.empathy.gnome.org"); + + ensure_certificate_proxy (test); + +-- +2.14.4 + + +From f07492434449bcdd74a61aa74596884ef5700d88 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Wed, 15 Mar 2017 20:24:08 +0100 +Subject: [PATCH 4/5] tls-verifier: Use GIO to verify the chain of TLS + certificates + +Gcr has its own hand rolled code to complete the certificate chain and +validate it, which predates the equivalent functionality in GIO. These +days, GIO's GnuTLS backend is a better option because it defers to +GnuTLS to do the right thing. It benefits automatically from any +improvements made to GnuTLS itself. + +However, GIO doesn't support certificate pinning. Gcr continues to +provide that feature. + +Note: + +(a) We don't set "certificate-hostname" when we encounter +TP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH. The resulting loss +of verbosity in EmpathyTLSDialog is balanced by no longer relying on a +specific encryption library. + +(b) glib-networking doesn't differentiate between +GNUTLS_CERT_SIGNER_NOT_FOUND and GNUTLS_CERT_SIGNER_NOT_CA. Hence, we +club them together as TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED and we +no longer return TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED. + +(c) Unlike Gcr, GnuTLS doesn't seem to provide a way to load a PKCS#11 +module that's built into the code, as opposed to being a shared object. +This makes it hard for us to load our mock PKCS#11 module. Therefore, +we have disabled the test case that relies on using PKCS#11 storage to +complete the certificate chain. + +Bump required GLib version to 2.48. We really do need 2.48 because we +rely on the improvements to GIO's GnuTLS backend. + +https://bugzilla.gnome.org/show_bug.cgi?id=780160 +--- + configure.ac | 6 +- + libempathy/empathy-tls-verifier.c | 419 ++++++++++++++++++-------------------- + libempathy/empathy-tls-verifier.h | 3 + + tests/empathy-tls-test.c | 35 +++- + 4 files changed, 232 insertions(+), 231 deletions(-) + +diff --git a/configure.ac b/configure.ac +index a427eba3af56..cd6f371de799 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -37,9 +37,9 @@ AC_COPYRIGHT([ + FOLKS_REQUIRED=0.9.5 + GNUTLS_REQUIRED=2.8.5 + +-GLIB_REQUIRED=2.37.6 +-AC_DEFINE(GLIB_VERSION_MIN_REQUIRED, GLIB_VERSION_2_30, [Ignore post 2.30 deprecations]) +-AC_DEFINE(GLIB_VERSION_MAX_ALLOWED, GLIB_VERSION_2_38, [Prevent post 2.38 APIs]) ++GLIB_REQUIRED=2.48.0 ++AC_DEFINE(GLIB_VERSION_MIN_REQUIRED, GLIB_VERSION_2_48, [Ignore post 2.48 deprecations]) ++AC_DEFINE(GLIB_VERSION_MAX_ALLOWED, GLIB_VERSION_2_48, [Prevent post 2.48 APIs]) + + GTK_REQUIRED=3.9.4 + AC_DEFINE(GDK_VERSION_MIN_REQUIRED, GDK_VERSION_3_8, [Ignore post 3.8 deprecations]) +diff --git a/libempathy/empathy-tls-verifier.c b/libempathy/empathy-tls-verifier.c +index 8f80b4372de1..a8306bb569ea 100644 +--- a/libempathy/empathy-tls-verifier.c ++++ b/libempathy/empathy-tls-verifier.c +@@ -1,7 +1,9 @@ + /* + * empathy-tls-verifier.c - Source for EmpathyTLSVerifier + * Copyright (C) 2010 Collabora Ltd. ++ * Copyright (C) 2017 Red Hat, Inc. + * @author Cosimo Cecchi ++ * @author Debarshi Ray + * @author Stef Walter + * + * This library is free software; you can redistribute it and/or +@@ -43,6 +45,8 @@ enum { + }; + + typedef struct { ++ GTlsCertificate *g_certificate; ++ GTlsDatabase *database; + TpTLSCertificate *certificate; + gchar *hostname; + gchar **reference_identities; +@@ -53,135 +57,86 @@ typedef struct { + gboolean dispose_run; + } EmpathyTLSVerifierPriv; + +-static gboolean +-verification_output_to_reason (gint res, +- guint verify_output, +- TpTLSCertificateRejectReason *reason) ++static GTlsCertificate * ++tls_certificate_new_from_der (GPtrArray *data, GError **error) + { +- gboolean retval = TRUE; ++ GTlsBackend *tls_backend; ++ GTlsCertificate *cert = NULL; ++ GTlsCertificate *issuer = NULL; ++ GTlsCertificate *retval = NULL; ++ GType tls_certificate_type; ++ gint i; + +- g_assert (reason != NULL); ++ g_return_val_if_fail (error == NULL || *error == NULL, NULL); + +- if (res != GNUTLS_E_SUCCESS) +- { +- retval = FALSE; ++ tls_backend = g_tls_backend_get_default (); ++ tls_certificate_type = g_tls_backend_get_certificate_type (tls_backend); + +- /* the certificate is not structurally valid */ +- switch (res) +- { +- case GNUTLS_E_INSUFFICIENT_CREDENTIALS: +- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED; +- break; +- case GNUTLS_E_CONSTRAINT_ERROR: +- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_LIMIT_EXCEEDED; +- break; +- default: +- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN; +- break; +- } +- +- goto out; ++ for (i = (gint) data->len - 1; i >= 0; --i) ++ { ++ GArray *cert_data; ++ ++ cert_data = g_ptr_array_index (data, i); ++ cert = g_initable_new (tls_certificate_type, ++ NULL, ++ error, ++ "certificate", (GByteArray *) cert_data, ++ "issuer", issuer, ++ NULL); ++ ++ if (cert == NULL) ++ goto out; ++ ++ g_clear_object (&issuer); ++ issuer = g_object_ref (cert); ++ g_clear_object (&cert); + } + +- /* the certificate is structurally valid, check for other errors. */ +- if (verify_output & GNUTLS_CERT_INVALID) +- { +- retval = FALSE; +- +- if (verify_output & GNUTLS_CERT_SIGNER_NOT_FOUND) +- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED; +- else if (verify_output & GNUTLS_CERT_SIGNER_NOT_CA) +- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED; +- else if (verify_output & GNUTLS_CERT_INSECURE_ALGORITHM) +- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_INSECURE; +- else if (verify_output & GNUTLS_CERT_NOT_ACTIVATED) +- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_NOT_ACTIVATED; +- else if (verify_output & GNUTLS_CERT_EXPIRED) +- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_EXPIRED; +- else if (verify_output & GNUTLS_CERT_REVOKED) +- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_REVOKED; +- else +- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN; ++ g_assert_null (cert); ++ g_assert_true (G_IS_TLS_CERTIFICATE (issuer)); + +- goto out; +- } ++ retval = g_object_ref (issuer); + + out: ++ g_clear_object (&cert); ++ g_clear_object (&issuer); + return retval; + } + +-static void +-build_certificate_list_for_gnutls (GcrCertificateChain *chain, +- gnutls_x509_crt_t **list, +- guint *n_list, +- gnutls_x509_crt_t **anchors, +- guint *n_anchors) ++static TpTLSCertificateRejectReason ++verification_output_to_reason (GTlsCertificateFlags flags) + { +- GcrCertificate *cert; +- guint idx, length; +- gnutls_x509_crt_t *retval; +- gnutls_x509_crt_t gcert; +- gnutls_datum_t datum; +- gsize n_data; +- +- g_assert (list); +- g_assert (n_list); +- g_assert (anchors); +- g_assert (n_anchors); ++ TpTLSCertificateRejectReason retval; + +- *list = *anchors = NULL; +- *n_list = *n_anchors = 0; ++ g_assert (flags != 0); + +- length = gcr_certificate_chain_get_length (chain); +- retval = g_malloc0 (sizeof (gnutls_x509_crt_t) * length); +- +- /* Convert the main body of the chain to gnutls */ +- for (idx = 0; idx < length; ++idx) +- { +- cert = gcr_certificate_chain_get_certificate (chain, idx); +- datum.data = (gpointer)gcr_certificate_get_der_data (cert, &n_data); +- datum.size = n_data; +- +- gnutls_x509_crt_init (&gcert); +- if (gnutls_x509_crt_import (gcert, &datum, GNUTLS_X509_FMT_DER) < 0) +- g_return_if_reached (); +- +- retval[idx] = gcert; +- } +- +- *list = retval; +- *n_list = length; +- +- /* See if we have an anchor */ +- if (gcr_certificate_chain_get_status (chain) == +- GCR_CERTIFICATE_CHAIN_ANCHORED) ++ switch (flags) + { +- cert = gcr_certificate_chain_get_anchor (chain); +- g_return_if_fail (cert); +- +- datum.data = (gpointer)gcr_certificate_get_der_data (cert, &n_data); +- datum.size = n_data; +- +- gnutls_x509_crt_init (&gcert); +- if (gnutls_x509_crt_import (gcert, &datum, GNUTLS_X509_FMT_DER) < 0) +- g_return_if_reached (); +- +- retval = g_malloc0 (sizeof (gnutls_x509_crt_t) * 1); +- retval[0] = gcert; +- *anchors = retval; +- *n_anchors = 1; ++ case G_TLS_CERTIFICATE_UNKNOWN_CA: ++ retval = TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED; ++ break; ++ case G_TLS_CERTIFICATE_BAD_IDENTITY: ++ retval = TP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH; ++ break; ++ case G_TLS_CERTIFICATE_NOT_ACTIVATED: ++ retval = TP_TLS_CERTIFICATE_REJECT_REASON_NOT_ACTIVATED; ++ break; ++ case G_TLS_CERTIFICATE_EXPIRED: ++ retval = TP_TLS_CERTIFICATE_REJECT_REASON_EXPIRED; ++ break; ++ case G_TLS_CERTIFICATE_REVOKED: ++ retval = TP_TLS_CERTIFICATE_REJECT_REASON_REVOKED; ++ break; ++ case G_TLS_CERTIFICATE_INSECURE: ++ retval = TP_TLS_CERTIFICATE_REJECT_REASON_INSECURE; ++ break; ++ case G_TLS_CERTIFICATE_GENERIC_ERROR: ++ default: ++ retval = TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN; ++ break; + } +-} + +-static void +-free_certificate_list_for_gnutls (gnutls_x509_crt_t *list, +- guint n_list) +-{ +- guint idx; +- +- for (idx = 0; idx < n_list; idx++) +- gnutls_x509_crt_deinit (list[idx]); +- g_free (list); ++ return retval; + } + + static void +@@ -193,6 +148,7 @@ complete_verification (EmpathyTLSVerifier *self) + + g_simple_async_result_complete_in_idle (priv->verify_result); + ++ g_clear_object (&priv->g_certificate); + tp_clear_object (&priv->verify_result); + } + +@@ -209,6 +165,7 @@ abort_verification (EmpathyTLSVerifier *self, + reason); + g_simple_async_result_complete_in_idle (priv->verify_result); + ++ g_clear_object (&priv->g_certificate); + tp_clear_object (&priv->verify_result); + } + +@@ -221,142 +178,137 @@ debug_certificate (GcrCertificate *cert) + } + + static void +-debug_certificate_chain (GcrCertificateChain *chain) ++verify_chain_cb (GObject *object, ++ GAsyncResult *res, ++ gpointer user_data) + { +- GEnumClass *enum_class; +- GEnumValue *enum_value; +- gint idx, length; +- GcrCertificate *cert; +- +- enum_class = G_ENUM_CLASS +- (g_type_class_peek (GCR_TYPE_CERTIFICATE_CHAIN_STATUS)); +- enum_value = g_enum_get_value (enum_class, +- gcr_certificate_chain_get_status (chain)); +- length = gcr_certificate_chain_get_length (chain); +- DEBUG ("Certificate chain: length %u status %s", +- length, enum_value ? enum_value->value_nick : "XXX"); +- +- for (idx = 0; idx < length; ++idx) +- { +- cert = gcr_certificate_chain_get_certificate (chain, idx); +- debug_certificate (cert); +- } +-} ++ GError *error = NULL; + +-static void +-perform_verification (EmpathyTLSVerifier *self, +- GcrCertificateChain *chain) +-{ +- gboolean ret = FALSE; +- TpTLSCertificateRejectReason reason = +- TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN; +- gnutls_x509_crt_t *list, *anchors; +- guint n_list, n_anchors; +- guint verify_output; +- gint res; ++ GTlsCertificateFlags flags; ++ GTlsDatabase *tls_database = G_TLS_DATABASE (object); + gint i; +- gboolean matched = FALSE; ++ EmpathyTLSVerifier *self = EMPATHY_TLS_VERIFIER (user_data); + EmpathyTLSVerifierPriv *priv = GET_PRIV (self); + +- DEBUG ("Performing verification"); +- debug_certificate_chain (chain); +- +- list = anchors = NULL; +- n_list = n_anchors = 0; +- +- /* +- * If the first certificate is an pinned certificate then we completely +- * ignore the rest of the verification process. ++ /* FIXME: g_tls_database_verify_chain doesn't set the GError if the ++ * certificate chain couldn't be verified. See: ++ * https://bugzilla.gnome.org/show_bug.cgi?id=780310 + */ +- if (gcr_certificate_chain_get_status (chain) == GCR_CERTIFICATE_CHAIN_PINNED) ++ flags = g_tls_database_verify_chain_finish (tls_database, res, &error); ++ if (flags != 0) + { +- DEBUG ("Found pinned certificate for %s", priv->hostname); +- complete_verification (self); +- goto out; +- } +- +- build_certificate_list_for_gnutls (chain, &list, &n_list, +- &anchors, &n_anchors); +- if (list == NULL || n_list == 0) { +- g_warn_if_reached (); +- abort_verification (self, TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN); +- goto out; +- } ++ TpTLSCertificateRejectReason reason; + +- verify_output = 0; +- res = gnutls_x509_crt_list_verify (list, n_list, anchors, n_anchors, +- NULL, 0, 0, &verify_output); +- ret = verification_output_to_reason (res, verify_output, &reason); ++ /* We don't pass the identity to g_tls_database_verify. */ ++ g_assert_false (flags & G_TLS_CERTIFICATE_BAD_IDENTITY); + +- DEBUG ("Certificate verification gave result %d with reason %u", ret, ++ reason = verification_output_to_reason (flags); ++ DEBUG ("Certificate verification gave flags %d with reason %u", ++ (gint) flags, + reason); + +- if (!ret) { + abort_verification (self, reason); ++ g_clear_error (&error); + goto out; +- } ++ } + +- /* now check if the certificate matches one of the reference identities. */ +- if (priv->reference_identities != NULL) ++ for (i = 0; priv->reference_identities[i] != NULL; i++) + { +- for (i = 0, matched = FALSE; priv->reference_identities[i] != NULL; ++i) +- { +- if (gnutls_x509_crt_check_hostname (list[0], +- priv->reference_identities[i]) == 1) +- { +- matched = TRUE; +- break; +- } +- } ++ GSocketConnectable *identity = NULL; ++ ++ identity = g_network_address_new (priv->reference_identities[i], 0); ++ flags = g_tls_certificate_verify (priv->g_certificate, identity, NULL); ++ ++ g_object_unref (identity); ++ if (flags == 0) ++ break; + } + +- if (!matched) ++ if (flags != 0) + { +- gchar *certified_hostname; ++ TpTLSCertificateRejectReason reason; ++ ++ g_assert_cmpint (flags, ==, G_TLS_CERTIFICATE_BAD_IDENTITY); ++ ++ reason = verification_output_to_reason (flags); ++ DEBUG ("Certificate verification gave flags %d with reason %u", ++ (gint) flags, ++ reason); + +- certified_hostname = empathy_get_x509_certificate_hostname (list[0]); +- tp_asv_set_string (priv->details, +- "expected-hostname", priv->hostname); +- tp_asv_set_string (priv->details, +- "certificate-hostname", certified_hostname); ++ /* FIXME: We don't set "certificate-hostname" because ++ * GTlsCertificate doesn't expose the hostname used in the ++ * certificate. We will temporarily lose some verbosity in ++ * EmpathyTLSDialog, but that's balanced by no longer ++ * relying on a specific encryption library. ++ */ ++ tp_asv_set_string (priv->details, "expected-hostname", priv->hostname); + +- DEBUG ("Hostname mismatch: got %s but expected %s", +- certified_hostname, priv->hostname); ++ DEBUG ("Hostname mismatch: expected %s", priv->hostname); + +- g_free (certified_hostname); +- abort_verification (self, +- TP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH); ++ abort_verification (self, reason); + goto out; + } + +- DEBUG ("Hostname matched"); ++ DEBUG ("Verified certificate chain"); + complete_verification (self); + +- out: +- free_certificate_list_for_gnutls (list, n_list); +- free_certificate_list_for_gnutls (anchors, n_anchors); ++out: ++ /* Matches ref when starting verify chain */ ++ g_object_unref (self); + } + + static void +-perform_verification_cb (GObject *object, +- GAsyncResult *res, +- gpointer user_data) ++is_certificate_pinned_cb (GObject *object, ++ GAsyncResult *res, ++ gpointer user_data) + { + GError *error = NULL; +- +- GcrCertificateChain *chain = GCR_CERTIFICATE_CHAIN (object); ++ GPtrArray *cert_data; + EmpathyTLSVerifier *self = EMPATHY_TLS_VERIFIER (user_data); ++ EmpathyTLSVerifierPriv *priv = GET_PRIV (self); ++ ++ if (gcr_trust_is_certificate_pinned_finish (res, &error)) ++ { ++ DEBUG ("Found pinned certificate for %s", priv->hostname); ++ complete_verification (self); ++ goto out; ++ } ++ ++ /* error is set only when there is an actual failure. It won't be ++ * set, if it successfully determined that the ceritificate was not ++ * pinned. */ ++ if (error != NULL) ++ { ++ DEBUG ("Failed to determine if certificate is pinned: %s", ++ error->message); ++ g_clear_error (&error); ++ } + +- /* Even if building the chain fails, try verifying what we have */ +- if (!gcr_certificate_chain_build_finish (chain, res, &error)) ++ cert_data = tp_tls_certificate_get_cert_data (priv->certificate); ++ priv->g_certificate = tls_certificate_new_from_der (cert_data, &error); ++ if (error != NULL) + { +- DEBUG ("Building of certificate chain failed: %s", error->message); ++ DEBUG ("Verification of certificate chain failed: %s", error->message); ++ ++ abort_verification (self, TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN); + g_clear_error (&error); ++ goto out; + } + +- perform_verification (self, chain); ++ DEBUG ("Performing verification"); ++ ++ g_tls_database_verify_chain_async (priv->database, ++ priv->g_certificate, ++ G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER, ++ NULL, ++ NULL, ++ G_TLS_DATABASE_VERIFY_NONE, ++ NULL, ++ verify_chain_cb, ++ g_object_ref (self)); + +- /* Matches ref when staring chain build */ ++out: ++ /* Matches ref when starting is certificate pinned */ + g_object_unref (self); + } + +@@ -420,6 +372,8 @@ empathy_tls_verifier_dispose (GObject *object) + + priv->dispose_run = TRUE; + ++ g_clear_object (&priv->g_certificate); ++ g_clear_object (&priv->database); + tp_clear_object (&priv->certificate); + + G_OBJECT_CLASS (empathy_tls_verifier_parent_class)->dispose (object); +@@ -443,10 +397,14 @@ static void + empathy_tls_verifier_init (EmpathyTLSVerifier *self) + { + EmpathyTLSVerifierPriv *priv; ++ GTlsBackend *tls_backend; + + priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + EMPATHY_TYPE_TLS_VERIFIER, EmpathyTLSVerifierPriv); + priv->details = tp_asv_new (NULL, NULL); ++ ++ tls_backend = g_tls_backend_get_default (); ++ priv->database = g_tls_backend_get_default_database (tls_backend); + } + + static void +@@ -503,16 +461,15 @@ empathy_tls_verifier_verify_async (EmpathyTLSVerifier *self, + GAsyncReadyCallback callback, + gpointer user_data) + { +- GcrCertificateChain *chain; + GcrCertificate *cert; + GPtrArray *cert_data; + GArray *data; +- guint idx; + EmpathyTLSVerifierPriv *priv = GET_PRIV (self); + + DEBUG ("Starting verification"); + + g_return_if_fail (priv->verify_result == NULL); ++ g_return_if_fail (priv->g_certificate == NULL); + + cert_data = tp_tls_certificate_get_cert_data (priv->certificate); + g_return_if_fail (cert_data); +@@ -520,19 +477,22 @@ empathy_tls_verifier_verify_async (EmpathyTLSVerifier *self, + priv->verify_result = g_simple_async_result_new (G_OBJECT (self), + callback, user_data, NULL); + +- /* Create a certificate chain */ +- chain = gcr_certificate_chain_new (); +- for (idx = 0; idx < cert_data->len; ++idx) { +- data = g_ptr_array_index (cert_data, idx); +- cert = gcr_simple_certificate_new ((guchar *) data->data, data->len); +- gcr_certificate_chain_add (chain, cert); +- g_object_unref (cert); +- } ++ /* The first certificate in the chain is for the host */ ++ data = g_ptr_array_index (cert_data, 0); ++ cert = gcr_simple_certificate_new ((gpointer) data->data, ++ (gsize) data->len); ++ ++ DEBUG ("Checking if certificate is pinned:"); ++ debug_certificate (cert); + +- gcr_certificate_chain_build_async (chain, GCR_PURPOSE_SERVER_AUTH, priv->hostname, 0, +- NULL, perform_verification_cb, g_object_ref (self)); ++ gcr_trust_is_certificate_pinned_async (cert, ++ GCR_PURPOSE_SERVER_AUTH, ++ priv->hostname, ++ NULL, ++ is_certificate_pinned_cb, ++ g_object_ref (self)); + +- g_object_unref (chain); ++ g_object_unref (cert); + } + + gboolean +@@ -567,6 +527,21 @@ empathy_tls_verifier_verify_finish (EmpathyTLSVerifier *self, + return TRUE; + } + ++void empathy_tls_verifier_set_database (EmpathyTLSVerifier *self, ++ GTlsDatabase *database) ++{ ++ EmpathyTLSVerifierPriv *priv = GET_PRIV (self); ++ ++ g_return_if_fail (EMPATHY_IS_TLS_VERIFIER (self)); ++ g_return_if_fail (G_IS_TLS_DATABASE (database)); ++ ++ if (database == priv->database) ++ return; ++ ++ g_clear_object (&priv->database); ++ priv->database = g_object_ref (database); ++} ++ + void + empathy_tls_verifier_store_exception (EmpathyTLSVerifier *self) + { +diff --git a/libempathy/empathy-tls-verifier.h b/libempathy/empathy-tls-verifier.h +index c25d9756cb02..f9bf54a612f2 100644 +--- a/libempathy/empathy-tls-verifier.h ++++ b/libempathy/empathy-tls-verifier.h +@@ -72,6 +72,9 @@ gboolean empathy_tls_verifier_verify_finish (EmpathyTLSVerifier *self, + GHashTable **details, + GError **error); + ++void empathy_tls_verifier_set_database (EmpathyTLSVerifier *self, ++ GTlsDatabase *database); ++ + void empathy_tls_verifier_store_exception (EmpathyTLSVerifier *self); + + G_END_DECLS +diff --git a/tests/empathy-tls-test.c b/tests/empathy-tls-test.c +index 422909e7cc2a..b8f9ffcbb9af 100644 +--- a/tests/empathy-tls-test.c ++++ b/tests/empathy-tls-test.c +@@ -270,6 +270,7 @@ mock_tls_certificate_new_and_register (TpDBusDaemon *dbus, + + typedef struct { + GMainLoop *loop; ++ GTlsDatabase *database; + TpDBusDaemon *dbus; + const gchar *dbus_name; + MockTLSCertificate *mock; +@@ -283,9 +284,18 @@ setup (Test *test, gconstpointer data) + GError *error = NULL; + GckModule *module; + const gchar *trust_uris[2] = { MOCK_SLOT_ONE_URI, NULL }; ++ gchar *path = NULL; + + test->loop = g_main_loop_new (NULL, FALSE); + ++ path = g_build_filename (g_getenv ("EMPATHY_SRCDIR"), ++ "tests", ++ "certificates", ++ "certificate-authority.pem", ++ NULL); ++ test->database = g_tls_file_database_new (path, &error); ++ g_assert_no_error (error); ++ + test->dbus = tp_dbus_daemon_dup (&error); + g_assert_no_error (error); + +@@ -301,6 +311,8 @@ setup (Test *test, gconstpointer data) + gcr_pkcs11_set_modules (NULL); + gcr_pkcs11_add_module (module); + gcr_pkcs11_set_trust_lookup_uris (trust_uris); ++ ++ g_free (path); + } + + static void +@@ -325,6 +337,8 @@ teardown (Test *test, gconstpointer data) + g_object_unref (test->cert); + test->cert = NULL; + ++ g_clear_object (&test->database); ++ + g_main_loop_unref (test->loop); + test->loop = NULL; + +@@ -418,6 +432,8 @@ test_certificate_mock_basics (Test *test, + g_assert (test->mock->state == TP_TLS_CERTIFICATE_STATE_ACCEPTED); + } + ++#if 0 ++ + static void + test_certificate_verify_success_with_pkcs11_lookup (Test *test, + gconstpointer data G_GNUC_UNUSED) +@@ -459,6 +475,8 @@ test_certificate_verify_success_with_pkcs11_lookup (Test *test, + g_object_unref (verifier); + } + ++#endif ++ + static void + test_certificate_verify_success_with_full_chain (Test *test, + gconstpointer data G_GNUC_UNUSED) +@@ -486,6 +504,7 @@ test_certificate_verify_success_with_full_chain (Test *test, + + verifier = empathy_tls_verifier_new (test->cert, "test-server.empathy.gnome.org", + reference_identities); ++ empathy_tls_verifier_set_database (verifier, test->database); + empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test); + g_main_loop_run (test->loop); + empathy_tls_verifier_verify_finish (verifier, test->result, &reason, +@@ -525,9 +544,9 @@ test_certificate_verify_root_not_found (Test *test, + empathy_tls_verifier_verify_finish (verifier, test->result, &reason, + NULL, &error); + +- /* And it should say we're self-signed (oddly enough) */ ++ /* And it should say we're untrusted */ + g_assert_error (error, G_IO_ERROR, +- TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED); ++ TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED); + + g_clear_error (&error); + g_object_unref (verifier); +@@ -560,9 +579,9 @@ test_certificate_verify_root_not_anchored (Test *test, + empathy_tls_verifier_verify_finish (verifier, test->result, &reason, + NULL, &error); + +- /* And it should say we're self-signed (oddly enough) */ ++ /* And it should say we're untrusted */ + g_assert_error (error, G_IO_ERROR, +- TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED); ++ TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED); + + g_clear_error (&error); + g_object_unref (verifier); +@@ -590,6 +609,7 @@ test_certificate_verify_identities_invalid (Test *test, + + verifier = empathy_tls_verifier_new (test->cert, "invalid.host.name", + reference_identities); ++ empathy_tls_verifier_set_database (verifier, test->database); + empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test); + g_main_loop_run (test->loop); + +@@ -627,6 +647,7 @@ test_certificate_verify_uses_reference_identities (Test *test, + /* Should be using the reference_identities and not host name for checks */ + verifier = empathy_tls_verifier_new (test->cert, "test-server.empathy.gnome.org", + reference_identities); ++ empathy_tls_verifier_set_database (verifier, test->database); + empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test); + g_main_loop_run (test->loop); + +@@ -708,9 +729,9 @@ test_certificate_verify_pinned_wrong_host (Test *test, + empathy_tls_verifier_verify_finish (verifier, test->result, &reason, + NULL, &error); + +- /* And it should say we're self-signed */ ++ /* And it should say we're untrusted */ + g_assert_error (error, G_IO_ERROR, +- TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED); ++ TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED); + + g_clear_error (&error); + g_object_unref (verifier); +@@ -727,8 +748,10 @@ main (int argc, + + g_test_add ("/tls/certificate_basics", Test, NULL, + setup, test_certificate_mock_basics, teardown); ++#if 0 + g_test_add ("/tls/certificate_verify_success_with_pkcs11_lookup", Test, NULL, + setup, test_certificate_verify_success_with_pkcs11_lookup, teardown); ++#endif + g_test_add ("/tls/certificate_verify_success_with_full_chain", Test, NULL, + setup, test_certificate_verify_success_with_full_chain, teardown); + g_test_add ("/tls/certificate_verify_root_not_found", Test, NULL, +-- +2.14.4 + + +From a5ef984c6219070253f382d41101de9f904563c6 Mon Sep 17 00:00:00 2001 +From: Debarshi Ray +Date: Thu, 16 Mar 2017 19:50:40 +0100 +Subject: [PATCH 5/5] Remove the GnuTLS dependency + +GIO, backed by glib-networking, has everything that we need. + +https://bugzilla.gnome.org/show_bug.cgi?id=780160 +--- + configure.ac | 2 -- + libempathy/empathy-utils.c | 35 ----------------------------------- + libempathy/empathy-utils.h | 3 --- + src/empathy-auth-client.c | 2 -- + tests/empathy-tls-test.c | 2 -- + 5 files changed, 44 deletions(-) + +diff --git a/configure.ac b/configure.ac +index cd6f371de799..a1cd48687e27 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -35,7 +35,6 @@ AC_COPYRIGHT([ + + # Hardp deps + FOLKS_REQUIRED=0.9.5 +-GNUTLS_REQUIRED=2.8.5 + + GLIB_REQUIRED=2.48.0 + AC_DEFINE(GLIB_VERSION_MIN_REQUIRED, GLIB_VERSION_2_48, [Ignore post 2.48 deprecations]) +@@ -219,7 +218,6 @@ PKG_CHECK_MODULES(EMPATHY, + gio-2.0 >= $GLIB_REQUIRED + gio-unix-2.0 >= $GLIB_REQUIRED + libsecret-1 >= $LIBSECRET_REQUIRED +- gnutls >= $GNUTLS_REQUIRED + gmodule-export-2.0 + gobject-2.0 + gsettings-desktop-schemas +diff --git a/libempathy/empathy-utils.c b/libempathy/empathy-utils.c +index e8349373639f..88e28b8dd92b 100644 +--- a/libempathy/empathy-utils.c ++++ b/libempathy/empathy-utils.c +@@ -20,10 +20,6 @@ + * Authors: Richard Hult + * Martyn Russell + * Xavier Claessens +- * +- * Some snippets are taken from GnuTLS 2.8.6, which is distributed under the +- * same GNU Lesser General Public License 2.1 (or later) version. See +- * empathy_get_x509_certified_hostname (). + */ + + #include "config.h" +@@ -648,37 +644,6 @@ empathy_folks_persona_is_interesting (FolksPersona *persona) + return TRUE; + } + +-gchar * +-empathy_get_x509_certificate_hostname (gnutls_x509_crt_t cert) +-{ +- gchar dns_name[256]; +- gsize dns_name_size; +- gint idx; +- gint res = 0; +- +- /* this snippet is taken from GnuTLS. +- * see gnutls/lib/x509/rfc2818_hostname.c +- */ +- for (idx = 0; res >= 0; idx++) +- { +- dns_name_size = sizeof (dns_name); +- res = gnutls_x509_crt_get_subject_alt_name (cert, idx, +- dns_name, &dns_name_size, NULL); +- +- if (res == GNUTLS_SAN_DNSNAME || res == GNUTLS_SAN_IPADDRESS) +- return g_strndup (dns_name, dns_name_size); +- } +- +- dns_name_size = sizeof (dns_name); +- res = gnutls_x509_crt_get_dn_by_oid (cert, GNUTLS_OID_X520_COMMON_NAME, +- 0, 0, dns_name, &dns_name_size); +- +- if (res >= 0) +- return g_strndup (dns_name, dns_name_size); +- +- return NULL; +-} +- + gchar * + empathy_format_currency (gint amount, + guint scale, +diff --git a/libempathy/empathy-utils.h b/libempathy/empathy-utils.h +index a9ff0d89060d..deb3ae87b7aa 100644 +--- a/libempathy/empathy-utils.h ++++ b/libempathy/empathy-utils.h +@@ -27,7 +27,6 @@ + + #include + #include +-#include + #include + #include + #include +@@ -85,8 +84,6 @@ gboolean empathy_connection_can_group_personas (TpConnection *connection, + FolksIndividual *individual); + gboolean empathy_folks_persona_is_interesting (FolksPersona *persona); + +-gchar * empathy_get_x509_certificate_hostname (gnutls_x509_crt_t cert); +- + gchar *empathy_format_currency (gint amount, + guint scale, + const gchar *currency); +diff --git a/src/empathy-auth-client.c b/src/empathy-auth-client.c +index 3ee478d3e29c..6b6482d4b23d 100644 +--- a/src/empathy-auth-client.c ++++ b/src/empathy-auth-client.c +@@ -22,7 +22,6 @@ + #include "config.h" + + #include +-#include + + #include "empathy-auth-factory.h" + #include "empathy-bad-password-dialog.h" +@@ -297,7 +296,6 @@ main (int argc, + g_option_context_free (context); + + empathy_gtk_init (); +- gnutls_global_init (); + g_set_application_name (_("Empathy authentication client")); + + /* Make empathy and empathy-auth-client appear as the same app in +diff --git a/tests/empathy-tls-test.c b/tests/empathy-tls-test.c +index b8f9ffcbb9af..9b62ae4e0ec7 100644 +--- a/tests/empathy-tls-test.c ++++ b/tests/empathy-tls-test.c +@@ -1,6 +1,5 @@ + #include "config.h" + +-#include + #include + #include + +@@ -744,7 +743,6 @@ main (int argc, + int result; + + test_init (argc, argv); +- gnutls_global_init (); + + g_test_add ("/tls/certificate_basics", Test, NULL, + setup, test_certificate_mock_basics, teardown); +-- +2.14.4 + diff --git a/SOURCES/fix-certificate-validation.patch b/SOURCES/fix-certificate-validation.patch deleted file mode 100644 index 8228ade..0000000 --- a/SOURCES/fix-certificate-validation.patch +++ /dev/null @@ -1,1042 +0,0 @@ -From 73c173dfc567dcdac9c37bdaeea8b1d5ba4ccd5e Mon Sep 17 00:00:00 2001 -From: Debarshi Ray -Date: Wed, 15 Mar 2017 20:23:43 +0100 -Subject: [PATCH 1/5] tls-verifier: Handle GNUTLS_CERT_REVOKED - -... by mapping it to TP_TLS_CERTIFICATE_REJECT_REASON_REVOKED. - -https://bugzilla.gnome.org/show_bug.cgi?id=780160 ---- - libempathy/empathy-tls-verifier.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/libempathy/empathy-tls-verifier.c b/libempathy/empathy-tls-verifier.c -index fcbc559b3f97..8f80b4372de1 100644 ---- a/libempathy/empathy-tls-verifier.c -+++ b/libempathy/empathy-tls-verifier.c -@@ -98,6 +98,8 @@ verification_output_to_reason (gint res, - *reason = TP_TLS_CERTIFICATE_REJECT_REASON_NOT_ACTIVATED; - else if (verify_output & GNUTLS_CERT_EXPIRED) - *reason = TP_TLS_CERTIFICATE_REJECT_REASON_EXPIRED; -+ else if (verify_output & GNUTLS_CERT_REVOKED) -+ *reason = TP_TLS_CERTIFICATE_REJECT_REASON_REVOKED; - else - *reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN; - --- -2.9.3 - - -From 54fb0e0550ba4664934e73e1de8793479b3370b8 Mon Sep 17 00:00:00 2001 -From: Debarshi Ray -Date: Mon, 20 Mar 2017 19:20:11 +0100 -Subject: [PATCH 2/5] tests: Fix comment - -The existing comment was mistakenly copied from -test_certificate_verify_success_with_full_chain. - -This test case is about a certificate that has been pinned against a -specific peer. The mock TLS connection doesn't have the full chain, -but just the leaf-level certificate that has been pinned. - -https://bugzilla.gnome.org/show_bug.cgi?id=780160 ---- - tests/empathy-tls-test.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/tests/empathy-tls-test.c b/tests/empathy-tls-test.c -index 91b05761f9b9..0752e1b328c5 100644 ---- a/tests/empathy-tls-test.c -+++ b/tests/empathy-tls-test.c -@@ -654,8 +654,8 @@ test_certificate_verify_success_with_pinned (Test *test, - }; - - /* -- * In this test the mock TLS connection has a full certificate -- * chain. We look for an anchor certificate in the chain. -+ * In this test the mock TLS connection has a certificate that has -+ * been pinned for the test-server.empathy.gnome.org peer. - */ - - test->mock = mock_tls_certificate_new_and_register (test->dbus, --- -2.9.3 - - -From 77be5d93d0c438acfa765f94f04fe9ee1f6eba6e Mon Sep 17 00:00:00 2001 -From: Debarshi Ray -Date: Mon, 20 Mar 2017 19:31:39 +0100 -Subject: [PATCH 3/5] tests: Actually test that hostnames of pinned - certificates are verified - -This test case is about ensuring that a pinned certificate won't be -validated if the wrong hostname is used. - -If we don't add the pinned certificate to our database, then checks for -pinning are going to fail regardless of the hostname being used. The -correct certificate-hostname pair needs to be in the database to ensure -that the hostnames are being matched as advertised. - -https://bugzilla.gnome.org/show_bug.cgi?id=780160 ---- - tests/empathy-tls-test.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/tests/empathy-tls-test.c b/tests/empathy-tls-test.c -index 0752e1b328c5..422909e7cc2a 100644 ---- a/tests/empathy-tls-test.c -+++ b/tests/empathy-tls-test.c -@@ -695,7 +695,8 @@ test_certificate_verify_pinned_wrong_host (Test *test, - test->mock = mock_tls_certificate_new_and_register (test->dbus, - "server-cert.cer", NULL); - -- /* Note that we're not adding any place to find root certs */ -+ /* We add the collabora directory with the collabora root */ -+ add_certificate_to_mock (test, "server-cert.cer", "test-server.empathy.gnome.org"); - - ensure_certificate_proxy (test); - --- -2.9.3 - - -From a9ce001092a2f2868c4926817b5946e1e93687d6 Mon Sep 17 00:00:00 2001 -From: Debarshi Ray -Date: Wed, 15 Mar 2017 20:24:08 +0100 -Subject: [PATCH 4/5] tls-verifier: Use GIO to verify the chain of TLS - certificates - -Gcr has its own hand rolled code to complete the certificate chain and -validate it, which predates the equivalent functionality in GIO. These -days, GIO's GnuTLS backend is a better option because it defers to -GnuTLS to do the right thing. It benefits automatically from any -improvements made to GnuTLS itself. - -However, GIO doesn't support certificate pinning. Gcr continues to -provide that feature. - -Note: - -(a) We don't set "certificate-hostname" when we encounter -TP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH. The resulting loss -of verbosity in EmpathyTLSDialog is balanced by no longer relying on a -specific encryption library. - -(b) glib-networking doesn't differentiate between -GNUTLS_CERT_SIGNER_NOT_FOUND and GNUTLS_CERT_SIGNER_NOT_CA. Hence, we -club them together as TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED and we -no longer return TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED. - -(c) Unlike Gcr, GnuTLS doesn't seem to provide a way to load a PKCS#11 -module that's built into the code, as opposed to being a shared object. -This makes it hard for us to load our mock PKCS#11 module. Therefore, -we have disabled the test case that relies on using PKCS#11 storage to -complete the certificate chain. - -Bump required GLib version to 2.48. We really do need 2.48 because we -rely on the improvements to GIO's GnuTLS backend. - -https://bugzilla.gnome.org/show_bug.cgi?id=780160 ---- - configure.ac | 6 +- - libempathy/empathy-tls-verifier.c | 419 ++++++++++++++++++-------------------- - libempathy/empathy-tls-verifier.h | 3 + - tests/empathy-tls-test.c | 35 +++- - 4 files changed, 232 insertions(+), 231 deletions(-) - -diff --git a/configure.ac b/configure.ac -index a427eba3af56..cd6f371de799 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -37,9 +37,9 @@ AC_COPYRIGHT([ - FOLKS_REQUIRED=0.9.5 - GNUTLS_REQUIRED=2.8.5 - --GLIB_REQUIRED=2.37.6 --AC_DEFINE(GLIB_VERSION_MIN_REQUIRED, GLIB_VERSION_2_30, [Ignore post 2.30 deprecations]) --AC_DEFINE(GLIB_VERSION_MAX_ALLOWED, GLIB_VERSION_2_38, [Prevent post 2.38 APIs]) -+GLIB_REQUIRED=2.48.0 -+AC_DEFINE(GLIB_VERSION_MIN_REQUIRED, GLIB_VERSION_2_48, [Ignore post 2.48 deprecations]) -+AC_DEFINE(GLIB_VERSION_MAX_ALLOWED, GLIB_VERSION_2_48, [Prevent post 2.48 APIs]) - - GTK_REQUIRED=3.9.4 - AC_DEFINE(GDK_VERSION_MIN_REQUIRED, GDK_VERSION_3_8, [Ignore post 3.8 deprecations]) -diff --git a/libempathy/empathy-tls-verifier.c b/libempathy/empathy-tls-verifier.c -index 8f80b4372de1..a8306bb569ea 100644 ---- a/libempathy/empathy-tls-verifier.c -+++ b/libempathy/empathy-tls-verifier.c -@@ -1,7 +1,9 @@ - /* - * empathy-tls-verifier.c - Source for EmpathyTLSVerifier - * Copyright (C) 2010 Collabora Ltd. -+ * Copyright (C) 2017 Red Hat, Inc. - * @author Cosimo Cecchi -+ * @author Debarshi Ray - * @author Stef Walter - * - * This library is free software; you can redistribute it and/or -@@ -43,6 +45,8 @@ enum { - }; - - typedef struct { -+ GTlsCertificate *g_certificate; -+ GTlsDatabase *database; - TpTLSCertificate *certificate; - gchar *hostname; - gchar **reference_identities; -@@ -53,135 +57,86 @@ typedef struct { - gboolean dispose_run; - } EmpathyTLSVerifierPriv; - --static gboolean --verification_output_to_reason (gint res, -- guint verify_output, -- TpTLSCertificateRejectReason *reason) -+static GTlsCertificate * -+tls_certificate_new_from_der (GPtrArray *data, GError **error) - { -- gboolean retval = TRUE; -+ GTlsBackend *tls_backend; -+ GTlsCertificate *cert = NULL; -+ GTlsCertificate *issuer = NULL; -+ GTlsCertificate *retval = NULL; -+ GType tls_certificate_type; -+ gint i; - -- g_assert (reason != NULL); -+ g_return_val_if_fail (error == NULL || *error == NULL, NULL); - -- if (res != GNUTLS_E_SUCCESS) -- { -- retval = FALSE; -+ tls_backend = g_tls_backend_get_default (); -+ tls_certificate_type = g_tls_backend_get_certificate_type (tls_backend); - -- /* the certificate is not structurally valid */ -- switch (res) -- { -- case GNUTLS_E_INSUFFICIENT_CREDENTIALS: -- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED; -- break; -- case GNUTLS_E_CONSTRAINT_ERROR: -- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_LIMIT_EXCEEDED; -- break; -- default: -- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN; -- break; -- } -- -- goto out; -+ for (i = (gint) data->len - 1; i >= 0; --i) -+ { -+ GArray *cert_data; -+ -+ cert_data = g_ptr_array_index (data, i); -+ cert = g_initable_new (tls_certificate_type, -+ NULL, -+ error, -+ "certificate", (GByteArray *) cert_data, -+ "issuer", issuer, -+ NULL); -+ -+ if (cert == NULL) -+ goto out; -+ -+ g_clear_object (&issuer); -+ issuer = g_object_ref (cert); -+ g_clear_object (&cert); - } - -- /* the certificate is structurally valid, check for other errors. */ -- if (verify_output & GNUTLS_CERT_INVALID) -- { -- retval = FALSE; -- -- if (verify_output & GNUTLS_CERT_SIGNER_NOT_FOUND) -- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED; -- else if (verify_output & GNUTLS_CERT_SIGNER_NOT_CA) -- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED; -- else if (verify_output & GNUTLS_CERT_INSECURE_ALGORITHM) -- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_INSECURE; -- else if (verify_output & GNUTLS_CERT_NOT_ACTIVATED) -- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_NOT_ACTIVATED; -- else if (verify_output & GNUTLS_CERT_EXPIRED) -- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_EXPIRED; -- else if (verify_output & GNUTLS_CERT_REVOKED) -- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_REVOKED; -- else -- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN; -+ g_assert_null (cert); -+ g_assert_true (G_IS_TLS_CERTIFICATE (issuer)); - -- goto out; -- } -+ retval = g_object_ref (issuer); - - out: -+ g_clear_object (&cert); -+ g_clear_object (&issuer); - return retval; - } - --static void --build_certificate_list_for_gnutls (GcrCertificateChain *chain, -- gnutls_x509_crt_t **list, -- guint *n_list, -- gnutls_x509_crt_t **anchors, -- guint *n_anchors) -+static TpTLSCertificateRejectReason -+verification_output_to_reason (GTlsCertificateFlags flags) - { -- GcrCertificate *cert; -- guint idx, length; -- gnutls_x509_crt_t *retval; -- gnutls_x509_crt_t gcert; -- gnutls_datum_t datum; -- gsize n_data; -- -- g_assert (list); -- g_assert (n_list); -- g_assert (anchors); -- g_assert (n_anchors); -+ TpTLSCertificateRejectReason retval; - -- *list = *anchors = NULL; -- *n_list = *n_anchors = 0; -+ g_assert (flags != 0); - -- length = gcr_certificate_chain_get_length (chain); -- retval = g_malloc0 (sizeof (gnutls_x509_crt_t) * length); -- -- /* Convert the main body of the chain to gnutls */ -- for (idx = 0; idx < length; ++idx) -- { -- cert = gcr_certificate_chain_get_certificate (chain, idx); -- datum.data = (gpointer)gcr_certificate_get_der_data (cert, &n_data); -- datum.size = n_data; -- -- gnutls_x509_crt_init (&gcert); -- if (gnutls_x509_crt_import (gcert, &datum, GNUTLS_X509_FMT_DER) < 0) -- g_return_if_reached (); -- -- retval[idx] = gcert; -- } -- -- *list = retval; -- *n_list = length; -- -- /* See if we have an anchor */ -- if (gcr_certificate_chain_get_status (chain) == -- GCR_CERTIFICATE_CHAIN_ANCHORED) -+ switch (flags) - { -- cert = gcr_certificate_chain_get_anchor (chain); -- g_return_if_fail (cert); -- -- datum.data = (gpointer)gcr_certificate_get_der_data (cert, &n_data); -- datum.size = n_data; -- -- gnutls_x509_crt_init (&gcert); -- if (gnutls_x509_crt_import (gcert, &datum, GNUTLS_X509_FMT_DER) < 0) -- g_return_if_reached (); -- -- retval = g_malloc0 (sizeof (gnutls_x509_crt_t) * 1); -- retval[0] = gcert; -- *anchors = retval; -- *n_anchors = 1; -+ case G_TLS_CERTIFICATE_UNKNOWN_CA: -+ retval = TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED; -+ break; -+ case G_TLS_CERTIFICATE_BAD_IDENTITY: -+ retval = TP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH; -+ break; -+ case G_TLS_CERTIFICATE_NOT_ACTIVATED: -+ retval = TP_TLS_CERTIFICATE_REJECT_REASON_NOT_ACTIVATED; -+ break; -+ case G_TLS_CERTIFICATE_EXPIRED: -+ retval = TP_TLS_CERTIFICATE_REJECT_REASON_EXPIRED; -+ break; -+ case G_TLS_CERTIFICATE_REVOKED: -+ retval = TP_TLS_CERTIFICATE_REJECT_REASON_REVOKED; -+ break; -+ case G_TLS_CERTIFICATE_INSECURE: -+ retval = TP_TLS_CERTIFICATE_REJECT_REASON_INSECURE; -+ break; -+ case G_TLS_CERTIFICATE_GENERIC_ERROR: -+ default: -+ retval = TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN; -+ break; - } --} - --static void --free_certificate_list_for_gnutls (gnutls_x509_crt_t *list, -- guint n_list) --{ -- guint idx; -- -- for (idx = 0; idx < n_list; idx++) -- gnutls_x509_crt_deinit (list[idx]); -- g_free (list); -+ return retval; - } - - static void -@@ -193,6 +148,7 @@ complete_verification (EmpathyTLSVerifier *self) - - g_simple_async_result_complete_in_idle (priv->verify_result); - -+ g_clear_object (&priv->g_certificate); - tp_clear_object (&priv->verify_result); - } - -@@ -209,6 +165,7 @@ abort_verification (EmpathyTLSVerifier *self, - reason); - g_simple_async_result_complete_in_idle (priv->verify_result); - -+ g_clear_object (&priv->g_certificate); - tp_clear_object (&priv->verify_result); - } - -@@ -221,142 +178,137 @@ debug_certificate (GcrCertificate *cert) - } - - static void --debug_certificate_chain (GcrCertificateChain *chain) -+verify_chain_cb (GObject *object, -+ GAsyncResult *res, -+ gpointer user_data) - { -- GEnumClass *enum_class; -- GEnumValue *enum_value; -- gint idx, length; -- GcrCertificate *cert; -- -- enum_class = G_ENUM_CLASS -- (g_type_class_peek (GCR_TYPE_CERTIFICATE_CHAIN_STATUS)); -- enum_value = g_enum_get_value (enum_class, -- gcr_certificate_chain_get_status (chain)); -- length = gcr_certificate_chain_get_length (chain); -- DEBUG ("Certificate chain: length %u status %s", -- length, enum_value ? enum_value->value_nick : "XXX"); -- -- for (idx = 0; idx < length; ++idx) -- { -- cert = gcr_certificate_chain_get_certificate (chain, idx); -- debug_certificate (cert); -- } --} -+ GError *error = NULL; - --static void --perform_verification (EmpathyTLSVerifier *self, -- GcrCertificateChain *chain) --{ -- gboolean ret = FALSE; -- TpTLSCertificateRejectReason reason = -- TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN; -- gnutls_x509_crt_t *list, *anchors; -- guint n_list, n_anchors; -- guint verify_output; -- gint res; -+ GTlsCertificateFlags flags; -+ GTlsDatabase *tls_database = G_TLS_DATABASE (object); - gint i; -- gboolean matched = FALSE; -+ EmpathyTLSVerifier *self = EMPATHY_TLS_VERIFIER (user_data); - EmpathyTLSVerifierPriv *priv = GET_PRIV (self); - -- DEBUG ("Performing verification"); -- debug_certificate_chain (chain); -- -- list = anchors = NULL; -- n_list = n_anchors = 0; -- -- /* -- * If the first certificate is an pinned certificate then we completely -- * ignore the rest of the verification process. -+ /* FIXME: g_tls_database_verify_chain doesn't set the GError if the -+ * certificate chain couldn't be verified. See: -+ * https://bugzilla.gnome.org/show_bug.cgi?id=780310 - */ -- if (gcr_certificate_chain_get_status (chain) == GCR_CERTIFICATE_CHAIN_PINNED) -+ flags = g_tls_database_verify_chain_finish (tls_database, res, &error); -+ if (flags != 0) - { -- DEBUG ("Found pinned certificate for %s", priv->hostname); -- complete_verification (self); -- goto out; -- } -- -- build_certificate_list_for_gnutls (chain, &list, &n_list, -- &anchors, &n_anchors); -- if (list == NULL || n_list == 0) { -- g_warn_if_reached (); -- abort_verification (self, TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN); -- goto out; -- } -+ TpTLSCertificateRejectReason reason; - -- verify_output = 0; -- res = gnutls_x509_crt_list_verify (list, n_list, anchors, n_anchors, -- NULL, 0, 0, &verify_output); -- ret = verification_output_to_reason (res, verify_output, &reason); -+ /* We don't pass the identity to g_tls_database_verify. */ -+ g_assert_false (flags & G_TLS_CERTIFICATE_BAD_IDENTITY); - -- DEBUG ("Certificate verification gave result %d with reason %u", ret, -+ reason = verification_output_to_reason (flags); -+ DEBUG ("Certificate verification gave flags %d with reason %u", -+ (gint) flags, - reason); - -- if (!ret) { - abort_verification (self, reason); -+ g_clear_error (&error); - goto out; -- } -+ } - -- /* now check if the certificate matches one of the reference identities. */ -- if (priv->reference_identities != NULL) -+ for (i = 0; priv->reference_identities[i] != NULL; i++) - { -- for (i = 0, matched = FALSE; priv->reference_identities[i] != NULL; ++i) -- { -- if (gnutls_x509_crt_check_hostname (list[0], -- priv->reference_identities[i]) == 1) -- { -- matched = TRUE; -- break; -- } -- } -+ GSocketConnectable *identity = NULL; -+ -+ identity = g_network_address_new (priv->reference_identities[i], 0); -+ flags = g_tls_certificate_verify (priv->g_certificate, identity, NULL); -+ -+ g_object_unref (identity); -+ if (flags == 0) -+ break; - } - -- if (!matched) -+ if (flags != 0) - { -- gchar *certified_hostname; -+ TpTLSCertificateRejectReason reason; -+ -+ g_assert_cmpint (flags, ==, G_TLS_CERTIFICATE_BAD_IDENTITY); -+ -+ reason = verification_output_to_reason (flags); -+ DEBUG ("Certificate verification gave flags %d with reason %u", -+ (gint) flags, -+ reason); - -- certified_hostname = empathy_get_x509_certificate_hostname (list[0]); -- tp_asv_set_string (priv->details, -- "expected-hostname", priv->hostname); -- tp_asv_set_string (priv->details, -- "certificate-hostname", certified_hostname); -+ /* FIXME: We don't set "certificate-hostname" because -+ * GTlsCertificate doesn't expose the hostname used in the -+ * certificate. We will temporarily lose some verbosity in -+ * EmpathyTLSDialog, but that's balanced by no longer -+ * relying on a specific encryption library. -+ */ -+ tp_asv_set_string (priv->details, "expected-hostname", priv->hostname); - -- DEBUG ("Hostname mismatch: got %s but expected %s", -- certified_hostname, priv->hostname); -+ DEBUG ("Hostname mismatch: expected %s", priv->hostname); - -- g_free (certified_hostname); -- abort_verification (self, -- TP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH); -+ abort_verification (self, reason); - goto out; - } - -- DEBUG ("Hostname matched"); -+ DEBUG ("Verified certificate chain"); - complete_verification (self); - -- out: -- free_certificate_list_for_gnutls (list, n_list); -- free_certificate_list_for_gnutls (anchors, n_anchors); -+out: -+ /* Matches ref when starting verify chain */ -+ g_object_unref (self); - } - - static void --perform_verification_cb (GObject *object, -- GAsyncResult *res, -- gpointer user_data) -+is_certificate_pinned_cb (GObject *object, -+ GAsyncResult *res, -+ gpointer user_data) - { - GError *error = NULL; -- -- GcrCertificateChain *chain = GCR_CERTIFICATE_CHAIN (object); -+ GPtrArray *cert_data; - EmpathyTLSVerifier *self = EMPATHY_TLS_VERIFIER (user_data); -+ EmpathyTLSVerifierPriv *priv = GET_PRIV (self); -+ -+ if (gcr_trust_is_certificate_pinned_finish (res, &error)) -+ { -+ DEBUG ("Found pinned certificate for %s", priv->hostname); -+ complete_verification (self); -+ goto out; -+ } -+ -+ /* error is set only when there is an actual failure. It won't be -+ * set, if it successfully determined that the ceritificate was not -+ * pinned. */ -+ if (error != NULL) -+ { -+ DEBUG ("Failed to determine if certificate is pinned: %s", -+ error->message); -+ g_clear_error (&error); -+ } - -- /* Even if building the chain fails, try verifying what we have */ -- if (!gcr_certificate_chain_build_finish (chain, res, &error)) -+ cert_data = tp_tls_certificate_get_cert_data (priv->certificate); -+ priv->g_certificate = tls_certificate_new_from_der (cert_data, &error); -+ if (error != NULL) - { -- DEBUG ("Building of certificate chain failed: %s", error->message); -+ DEBUG ("Verification of certificate chain failed: %s", error->message); -+ -+ abort_verification (self, TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN); - g_clear_error (&error); -+ goto out; - } - -- perform_verification (self, chain); -+ DEBUG ("Performing verification"); -+ -+ g_tls_database_verify_chain_async (priv->database, -+ priv->g_certificate, -+ G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER, -+ NULL, -+ NULL, -+ G_TLS_DATABASE_VERIFY_NONE, -+ NULL, -+ verify_chain_cb, -+ g_object_ref (self)); - -- /* Matches ref when staring chain build */ -+out: -+ /* Matches ref when starting is certificate pinned */ - g_object_unref (self); - } - -@@ -420,6 +372,8 @@ empathy_tls_verifier_dispose (GObject *object) - - priv->dispose_run = TRUE; - -+ g_clear_object (&priv->g_certificate); -+ g_clear_object (&priv->database); - tp_clear_object (&priv->certificate); - - G_OBJECT_CLASS (empathy_tls_verifier_parent_class)->dispose (object); -@@ -443,10 +397,14 @@ static void - empathy_tls_verifier_init (EmpathyTLSVerifier *self) - { - EmpathyTLSVerifierPriv *priv; -+ GTlsBackend *tls_backend; - - priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - EMPATHY_TYPE_TLS_VERIFIER, EmpathyTLSVerifierPriv); - priv->details = tp_asv_new (NULL, NULL); -+ -+ tls_backend = g_tls_backend_get_default (); -+ priv->database = g_tls_backend_get_default_database (tls_backend); - } - - static void -@@ -503,16 +461,15 @@ empathy_tls_verifier_verify_async (EmpathyTLSVerifier *self, - GAsyncReadyCallback callback, - gpointer user_data) - { -- GcrCertificateChain *chain; - GcrCertificate *cert; - GPtrArray *cert_data; - GArray *data; -- guint idx; - EmpathyTLSVerifierPriv *priv = GET_PRIV (self); - - DEBUG ("Starting verification"); - - g_return_if_fail (priv->verify_result == NULL); -+ g_return_if_fail (priv->g_certificate == NULL); - - cert_data = tp_tls_certificate_get_cert_data (priv->certificate); - g_return_if_fail (cert_data); -@@ -520,19 +477,22 @@ empathy_tls_verifier_verify_async (EmpathyTLSVerifier *self, - priv->verify_result = g_simple_async_result_new (G_OBJECT (self), - callback, user_data, NULL); - -- /* Create a certificate chain */ -- chain = gcr_certificate_chain_new (); -- for (idx = 0; idx < cert_data->len; ++idx) { -- data = g_ptr_array_index (cert_data, idx); -- cert = gcr_simple_certificate_new ((guchar *) data->data, data->len); -- gcr_certificate_chain_add (chain, cert); -- g_object_unref (cert); -- } -+ /* The first certificate in the chain is for the host */ -+ data = g_ptr_array_index (cert_data, 0); -+ cert = gcr_simple_certificate_new ((gpointer) data->data, -+ (gsize) data->len); -+ -+ DEBUG ("Checking if certificate is pinned:"); -+ debug_certificate (cert); - -- gcr_certificate_chain_build_async (chain, GCR_PURPOSE_SERVER_AUTH, priv->hostname, 0, -- NULL, perform_verification_cb, g_object_ref (self)); -+ gcr_trust_is_certificate_pinned_async (cert, -+ GCR_PURPOSE_SERVER_AUTH, -+ priv->hostname, -+ NULL, -+ is_certificate_pinned_cb, -+ g_object_ref (self)); - -- g_object_unref (chain); -+ g_object_unref (cert); - } - - gboolean -@@ -567,6 +527,21 @@ empathy_tls_verifier_verify_finish (EmpathyTLSVerifier *self, - return TRUE; - } - -+void empathy_tls_verifier_set_database (EmpathyTLSVerifier *self, -+ GTlsDatabase *database) -+{ -+ EmpathyTLSVerifierPriv *priv = GET_PRIV (self); -+ -+ g_return_if_fail (EMPATHY_IS_TLS_VERIFIER (self)); -+ g_return_if_fail (G_IS_TLS_DATABASE (database)); -+ -+ if (database == priv->database) -+ return; -+ -+ g_clear_object (&priv->database); -+ priv->database = g_object_ref (database); -+} -+ - void - empathy_tls_verifier_store_exception (EmpathyTLSVerifier *self) - { -diff --git a/libempathy/empathy-tls-verifier.h b/libempathy/empathy-tls-verifier.h -index c25d9756cb02..f9bf54a612f2 100644 ---- a/libempathy/empathy-tls-verifier.h -+++ b/libempathy/empathy-tls-verifier.h -@@ -72,6 +72,9 @@ gboolean empathy_tls_verifier_verify_finish (EmpathyTLSVerifier *self, - GHashTable **details, - GError **error); - -+void empathy_tls_verifier_set_database (EmpathyTLSVerifier *self, -+ GTlsDatabase *database); -+ - void empathy_tls_verifier_store_exception (EmpathyTLSVerifier *self); - - G_END_DECLS -diff --git a/tests/empathy-tls-test.c b/tests/empathy-tls-test.c -index 422909e7cc2a..b8f9ffcbb9af 100644 ---- a/tests/empathy-tls-test.c -+++ b/tests/empathy-tls-test.c -@@ -270,6 +270,7 @@ mock_tls_certificate_new_and_register (TpDBusDaemon *dbus, - - typedef struct { - GMainLoop *loop; -+ GTlsDatabase *database; - TpDBusDaemon *dbus; - const gchar *dbus_name; - MockTLSCertificate *mock; -@@ -283,9 +284,18 @@ setup (Test *test, gconstpointer data) - GError *error = NULL; - GckModule *module; - const gchar *trust_uris[2] = { MOCK_SLOT_ONE_URI, NULL }; -+ gchar *path = NULL; - - test->loop = g_main_loop_new (NULL, FALSE); - -+ path = g_build_filename (g_getenv ("EMPATHY_SRCDIR"), -+ "tests", -+ "certificates", -+ "certificate-authority.pem", -+ NULL); -+ test->database = g_tls_file_database_new (path, &error); -+ g_assert_no_error (error); -+ - test->dbus = tp_dbus_daemon_dup (&error); - g_assert_no_error (error); - -@@ -301,6 +311,8 @@ setup (Test *test, gconstpointer data) - gcr_pkcs11_set_modules (NULL); - gcr_pkcs11_add_module (module); - gcr_pkcs11_set_trust_lookup_uris (trust_uris); -+ -+ g_free (path); - } - - static void -@@ -325,6 +337,8 @@ teardown (Test *test, gconstpointer data) - g_object_unref (test->cert); - test->cert = NULL; - -+ g_clear_object (&test->database); -+ - g_main_loop_unref (test->loop); - test->loop = NULL; - -@@ -418,6 +432,8 @@ test_certificate_mock_basics (Test *test, - g_assert (test->mock->state == TP_TLS_CERTIFICATE_STATE_ACCEPTED); - } - -+#if 0 -+ - static void - test_certificate_verify_success_with_pkcs11_lookup (Test *test, - gconstpointer data G_GNUC_UNUSED) -@@ -459,6 +475,8 @@ test_certificate_verify_success_with_pkcs11_lookup (Test *test, - g_object_unref (verifier); - } - -+#endif -+ - static void - test_certificate_verify_success_with_full_chain (Test *test, - gconstpointer data G_GNUC_UNUSED) -@@ -486,6 +504,7 @@ test_certificate_verify_success_with_full_chain (Test *test, - - verifier = empathy_tls_verifier_new (test->cert, "test-server.empathy.gnome.org", - reference_identities); -+ empathy_tls_verifier_set_database (verifier, test->database); - empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test); - g_main_loop_run (test->loop); - empathy_tls_verifier_verify_finish (verifier, test->result, &reason, -@@ -525,9 +544,9 @@ test_certificate_verify_root_not_found (Test *test, - empathy_tls_verifier_verify_finish (verifier, test->result, &reason, - NULL, &error); - -- /* And it should say we're self-signed (oddly enough) */ -+ /* And it should say we're untrusted */ - g_assert_error (error, G_IO_ERROR, -- TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED); -+ TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED); - - g_clear_error (&error); - g_object_unref (verifier); -@@ -560,9 +579,9 @@ test_certificate_verify_root_not_anchored (Test *test, - empathy_tls_verifier_verify_finish (verifier, test->result, &reason, - NULL, &error); - -- /* And it should say we're self-signed (oddly enough) */ -+ /* And it should say we're untrusted */ - g_assert_error (error, G_IO_ERROR, -- TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED); -+ TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED); - - g_clear_error (&error); - g_object_unref (verifier); -@@ -590,6 +609,7 @@ test_certificate_verify_identities_invalid (Test *test, - - verifier = empathy_tls_verifier_new (test->cert, "invalid.host.name", - reference_identities); -+ empathy_tls_verifier_set_database (verifier, test->database); - empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test); - g_main_loop_run (test->loop); - -@@ -627,6 +647,7 @@ test_certificate_verify_uses_reference_identities (Test *test, - /* Should be using the reference_identities and not host name for checks */ - verifier = empathy_tls_verifier_new (test->cert, "test-server.empathy.gnome.org", - reference_identities); -+ empathy_tls_verifier_set_database (verifier, test->database); - empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test); - g_main_loop_run (test->loop); - -@@ -708,9 +729,9 @@ test_certificate_verify_pinned_wrong_host (Test *test, - empathy_tls_verifier_verify_finish (verifier, test->result, &reason, - NULL, &error); - -- /* And it should say we're self-signed */ -+ /* And it should say we're untrusted */ - g_assert_error (error, G_IO_ERROR, -- TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED); -+ TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED); - - g_clear_error (&error); - g_object_unref (verifier); -@@ -727,8 +748,10 @@ main (int argc, - - g_test_add ("/tls/certificate_basics", Test, NULL, - setup, test_certificate_mock_basics, teardown); -+#if 0 - g_test_add ("/tls/certificate_verify_success_with_pkcs11_lookup", Test, NULL, - setup, test_certificate_verify_success_with_pkcs11_lookup, teardown); -+#endif - g_test_add ("/tls/certificate_verify_success_with_full_chain", Test, NULL, - setup, test_certificate_verify_success_with_full_chain, teardown); - g_test_add ("/tls/certificate_verify_root_not_found", Test, NULL, --- -2.9.3 - - -From 7df2664ae5996b03c00a48d58c8f05eeba34dd25 Mon Sep 17 00:00:00 2001 -From: Debarshi Ray -Date: Thu, 16 Mar 2017 19:50:40 +0100 -Subject: [PATCH 5/5] Remove the GnuTLS dependency - -GIO, backed by glib-networking, has everything that we need. - -https://bugzilla.gnome.org/show_bug.cgi?id=780160 ---- - configure.ac | 2 -- - libempathy/empathy-utils.c | 35 ----------------------------------- - libempathy/empathy-utils.h | 3 --- - src/empathy-auth-client.c | 2 -- - tests/empathy-tls-test.c | 2 -- - 5 files changed, 44 deletions(-) - -diff --git a/configure.ac b/configure.ac -index cd6f371de799..a1cd48687e27 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -35,7 +35,6 @@ AC_COPYRIGHT([ - - # Hardp deps - FOLKS_REQUIRED=0.9.5 --GNUTLS_REQUIRED=2.8.5 - - GLIB_REQUIRED=2.48.0 - AC_DEFINE(GLIB_VERSION_MIN_REQUIRED, GLIB_VERSION_2_48, [Ignore post 2.48 deprecations]) -@@ -219,7 +218,6 @@ PKG_CHECK_MODULES(EMPATHY, - gio-2.0 >= $GLIB_REQUIRED - gio-unix-2.0 >= $GLIB_REQUIRED - libsecret-1 >= $LIBSECRET_REQUIRED -- gnutls >= $GNUTLS_REQUIRED - gmodule-export-2.0 - gobject-2.0 - gsettings-desktop-schemas -diff --git a/libempathy/empathy-utils.c b/libempathy/empathy-utils.c -index e8349373639f..88e28b8dd92b 100644 ---- a/libempathy/empathy-utils.c -+++ b/libempathy/empathy-utils.c -@@ -20,10 +20,6 @@ - * Authors: Richard Hult - * Martyn Russell - * Xavier Claessens -- * -- * Some snippets are taken from GnuTLS 2.8.6, which is distributed under the -- * same GNU Lesser General Public License 2.1 (or later) version. See -- * empathy_get_x509_certified_hostname (). - */ - - #include "config.h" -@@ -649,37 +645,6 @@ empathy_folks_persona_is_interesting (FolksPersona *persona) - } - - gchar * --empathy_get_x509_certificate_hostname (gnutls_x509_crt_t cert) --{ -- gchar dns_name[256]; -- gsize dns_name_size; -- gint idx; -- gint res = 0; -- -- /* this snippet is taken from GnuTLS. -- * see gnutls/lib/x509/rfc2818_hostname.c -- */ -- for (idx = 0; res >= 0; idx++) -- { -- dns_name_size = sizeof (dns_name); -- res = gnutls_x509_crt_get_subject_alt_name (cert, idx, -- dns_name, &dns_name_size, NULL); -- -- if (res == GNUTLS_SAN_DNSNAME || res == GNUTLS_SAN_IPADDRESS) -- return g_strndup (dns_name, dns_name_size); -- } -- -- dns_name_size = sizeof (dns_name); -- res = gnutls_x509_crt_get_dn_by_oid (cert, GNUTLS_OID_X520_COMMON_NAME, -- 0, 0, dns_name, &dns_name_size); -- -- if (res >= 0) -- return g_strndup (dns_name, dns_name_size); -- -- return NULL; --} -- --gchar * - empathy_format_currency (gint amount, - guint scale, - const gchar *currency) -diff --git a/libempathy/empathy-utils.h b/libempathy/empathy-utils.h -index a9ff0d89060d..deb3ae87b7aa 100644 ---- a/libempathy/empathy-utils.h -+++ b/libempathy/empathy-utils.h -@@ -27,7 +27,6 @@ - - #include - #include --#include - #include - #include - #include -@@ -85,8 +84,6 @@ gboolean empathy_connection_can_group_personas (TpConnection *connection, - FolksIndividual *individual); - gboolean empathy_folks_persona_is_interesting (FolksPersona *persona); - --gchar * empathy_get_x509_certificate_hostname (gnutls_x509_crt_t cert); -- - gchar *empathy_format_currency (gint amount, - guint scale, - const gchar *currency); -diff --git a/src/empathy-auth-client.c b/src/empathy-auth-client.c -index 3ee478d3e29c..6b6482d4b23d 100644 ---- a/src/empathy-auth-client.c -+++ b/src/empathy-auth-client.c -@@ -22,7 +22,6 @@ - #include "config.h" - - #include --#include - - #include "empathy-auth-factory.h" - #include "empathy-bad-password-dialog.h" -@@ -297,7 +296,6 @@ main (int argc, - g_option_context_free (context); - - empathy_gtk_init (); -- gnutls_global_init (); - g_set_application_name (_("Empathy authentication client")); - - /* Make empathy and empathy-auth-client appear as the same app in -diff --git a/tests/empathy-tls-test.c b/tests/empathy-tls-test.c -index b8f9ffcbb9af..9b62ae4e0ec7 100644 ---- a/tests/empathy-tls-test.c -+++ b/tests/empathy-tls-test.c -@@ -1,6 +1,5 @@ - #include "config.h" - --#include - #include - #include - -@@ -744,7 +743,6 @@ main (int argc, - int result; - - test_init (argc, argv); -- gnutls_global_init (); - - g_test_add ("/tls/certificate_basics", Test, NULL, - setup, test_certificate_mock_basics, teardown); --- -2.9.3 - diff --git a/SOURCES/fix-date-icons.patch b/SOURCES/fix-date-icons.patch deleted file mode 100644 index 700be2d..0000000 --- a/SOURCES/fix-date-icons.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 746b5b52c8469d5156a0a94fff4361ec3378246c Mon Sep 17 00:00:00 2001 -From: Hussam Al-Tayeb -Date: Thu, 22 Oct 2015 16:25:00 -0500 -Subject: [PATCH] Fix missing date icons in chat history window - -use x-office-calendar icon instead - -https://bugzilla.gnome.org/show_bug.cgi?id=756990 ---- - libempathy-gtk/empathy-log-window.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/libempathy-gtk/empathy-log-window.c b/libempathy-gtk/empathy-log-window.c -index d58de82..b3a66e7 100644 ---- a/libempathy-gtk/empathy-log-window.c -+++ b/libempathy-gtk/empathy-log-window.c -@@ -204,7 +204,7 @@ enum - COL_EVENTS_COUNT - }; - --#define CALENDAR_ICON "stock_calendar" -+#define CALENDAR_ICON "x-office-calendar" - - /* Seconds between two messages to be considered one conversation */ - #define MAX_GAP 30*60 diff --git a/SOURCES/fix-empathy-call.patch b/SOURCES/fix-empathy-call.patch deleted file mode 100644 index 0693a9b..0000000 --- a/SOURCES/fix-empathy-call.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 9f0d8a6e7444dd59729bac2c24717ea72aea5080 Mon Sep 17 00:00:00 2001 -From: Michael Catanzaro -Date: Thu, 21 Jul 2016 20:48:12 -0500 -Subject: [PATCH] Revert "Don't call XInitThreads in Wayland" - -This reverts commit a9ede294c57bc5738be3c33cba4ef88b9a7d4a0e. - -It causes empathy-call to crash when run in X11, and fixes absolutely -nothing. See the bug for details. - -Thanks to Diane Trout for investigating and preparing a substantially- -identical patch. - -https://bugzilla.gnome.org/show_bug.cgi?id=767516 ---- - src/empathy-call.c | 9 +++------ - 1 file changed, 3 insertions(+), 6 deletions(-) - -diff --git a/src/empathy-call.c b/src/empathy-call.c -index 8821bf3..1ac8a79 100644 ---- a/src/empathy-call.c -+++ b/src/empathy-call.c -@@ -28,7 +28,6 @@ - #include - - #ifdef CLUTTER_WINDOWING_X11 --#include - #include - #endif - -@@ -216,11 +215,9 @@ main (int argc, - g_setenv ("GST_DEBUG_DUMP_DOT_DIR", g_get_tmp_dir (), FALSE); - - #ifdef GDK_WINDOWING_X11 -- if (GDK_IS_X11_DISPLAY (gdk_display_get_default ())) { -- /* We can't call clutter_gst_init() before gtk_clutter_init(), so no choice -- * but to intiialise X11 threading ourself */ -- XInitThreads (); -- } -+ /* We can't call clutter_gst_init() before gtk_clutter_init(), so no choice -+ * but to intiialise X11 threading ourself */ -+ XInitThreads (); - #endif - - optcontext = g_option_context_new (N_("- Empathy Audio/Video Client")); diff --git a/SOURCES/fix-reduce-accuracy-setting.patch b/SOURCES/fix-reduce-accuracy-setting.patch deleted file mode 100644 index ce43fb1..0000000 --- a/SOURCES/fix-reduce-accuracy-setting.patch +++ /dev/null @@ -1,46 +0,0 @@ -From f1b1b75e6772502290cbff5be2c8f31b61bdb6df Mon Sep 17 00:00:00 2001 -From: Fabrice Bellet -Date: Mon, 23 Mar 2015 01:30:50 +0100 -Subject: [PATCH] location-manager: fix reduce accuracy setting - -https://bugzilla.gnome.org/show_bug.cgi?id=746735 ---- - libempathy-gtk/empathy-location-manager.c | 17 +++++++++++++++++ - 1 file changed, 17 insertions(+) - -diff --git a/libempathy-gtk/empathy-location-manager.c b/libempathy-gtk/empathy-location-manager.c -index 8787eb2..6ba39ac 100644 ---- a/libempathy-gtk/empathy-location-manager.c -+++ b/libempathy-gtk/empathy-location-manager.c -@@ -368,6 +368,18 @@ publish_cb (GSettings *gsettings_loc, - } - - static void -+reduce_accuracy_cb (GSettings *gsettings_loc, -+ const gchar *key, -+ gpointer user_data) -+{ -+ EmpathyLocationManager *self = EMPATHY_LOCATION_MANAGER (user_data); -+ -+ DEBUG ("Reduce Accuracy changed"); -+ -+ self->priv->reduce_accuracy = g_settings_get_boolean (gsettings_loc, key); -+} -+ -+static void - account_manager_prepared_cb (GObject *source_object, - GAsyncResult *result, - gpointer user_data) -@@ -416,7 +428,12 @@ empathy_location_manager_init (EmpathyLocationManager *self) - "changed::" EMPATHY_PREFS_LOCATION_PUBLISH, - G_CALLBACK (publish_cb), self); - -+ g_signal_connect (priv->gsettings_loc, -+ "changed::" EMPATHY_PREFS_LOCATION_REDUCE_ACCURACY, -+ G_CALLBACK (reduce_accuracy_cb), self); -+ - publish_cb (priv->gsettings_loc, EMPATHY_PREFS_LOCATION_PUBLISH, self); -+ reduce_accuracy_cb (priv->gsettings_loc, EMPATHY_PREFS_LOCATION_REDUCE_ACCURACY, self); - } - - EmpathyLocationManager * diff --git a/SOURCES/fs-element-notifiers-crash.patch b/SOURCES/fs-element-notifiers-crash.patch deleted file mode 100644 index cfcad8b..0000000 --- a/SOURCES/fs-element-notifiers-crash.patch +++ /dev/null @@ -1,53 +0,0 @@ -From e07685ff5e93346a86690fcf1b8449bf934c8da4 Mon Sep 17 00:00:00 2001 -From: Fabrice Bellet -Date: Wed, 13 Jul 2016 16:00:05 +0200 -Subject: [PATCH] call-window: properly remove the fs element notifiers - -This patch removes the FsElementAddedNotifier from the pipeline -in the conference remove callback, instead of just unreferencing -them. This fixes a crash in the rtp-special-source stop thread -cleanup code. - -https://bugzilla.gnome.org/show_bug.cgi?id=768889 ---- - src/empathy-call-window.c | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - -diff --git a/src/empathy-call-window.c b/src/empathy-call-window.c -index a54346c..2bbbd0f 100644 ---- a/src/empathy-call-window.c -+++ b/src/empathy-call-window.c -@@ -2513,17 +2513,30 @@ empathy_call_window_conference_added_cb (EmpathyCallHandler *handler, - } - - static void -+empathy_call_window_add_notifier_remove (gpointer data, gpointer user_data) -+{ -+ EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data); -+ EmpathyCallWindowPriv *priv = GET_PRIV (self); -+ FsElementAddedNotifier *notifier = data; -+ -+ fs_element_added_notifier_remove (notifier, GST_BIN (priv->pipeline)); -+} -+ -+static void - empathy_call_window_conference_removed_cb (EmpathyCallHandler *handler, - GstElement *conference, gpointer user_data) - { - EmpathyCallWindow *self = EMPATHY_CALL_WINDOW (user_data); - EmpathyCallWindowPriv *priv = GET_PRIV (self); - -- g_list_free_full (priv->notifiers, g_object_unref); -- priv->notifiers = NULL; -- - gst_bin_remove (GST_BIN (priv->pipeline), conference); - gst_element_set_state (conference, GST_STATE_NULL); -+ -+ g_list_foreach (priv->notifiers, -+ empathy_call_window_add_notifier_remove, user_data); -+ -+ g_list_free_full (priv->notifiers, g_object_unref); -+ priv->notifiers = NULL; - } - - static gboolean diff --git a/SPECS/empathy.spec b/SPECS/empathy.spec index e19997f..b224ca5 100644 --- a/SPECS/empathy.spec +++ b/SPECS/empathy.spec @@ -16,9 +16,8 @@ %global gcr_version 2.91.4 Name: empathy -# FIXME: Reenable parallel build for 3.12.13. -Version: 3.12.12 -Release: 4%{?dist} +Version: 3.12.13 +Release: 1%{?dist} Summary: Instant Messaging Client for GNOME License: GPLv2+ @@ -27,18 +26,11 @@ URL: https://wiki.gnome.org/Apps/Empathy Source0: http://download.gnome.org/sources/%{name}/3.12/%{name}-%{version}.tar.xz Source1: %{name}-README.ConnectionManagers -# https://bugzilla.gnome.org/show_bug.cgi?id=756990 -Patch0: fix-date-icons.patch -# https://bugzilla.gnome.org/show_bug.cgi?id=767516 -Patch1: fix-empathy-call.patch -# https://bugzilla.gnome.org/show_bug.cgi?id=746735 -Patch2: fix-reduce-accuracy-setting.patch -# https://bugzilla.gnome.org/show_bug.cgi?id=768889 -Patch3: fs-element-notifiers-crash.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1142832 -Patch4: 0001-help-Remove-IRC-content.patch +Patch0: 0001-help-Remove-IRC-content.patch + # https://bugzilla.redhat.com/show_bug.cgi?id=1386616 -Patch5: fix-certificate-validation.patch +Patch1: %{name}-fix-certificate-validation.patch BuildRequires: autoconf BuildRequires: automake @@ -91,19 +83,13 @@ Requires: telepathy-rakia %endif %description -Empathy is powerful multi-protocol instant messaging client which supports +Empathy is a powerful multi-protocol instant messaging client which supports Jabber, GTalk, MSN, Salut, and other protocols. It is built on top of the Telepathy framework. %prep -%setup -q -%patch0 -p1 -b .fix-date-icons -%patch1 -p1 -b .fix-empathy-call -%patch2 -p1 -b .fix-reduce-accuracy-setting -%patch3 -p1 -b .fs-element-notifiers-crash -%patch4 -p1 -b .remove-irc -%patch5 -p1 -b .fix-certificate-validation +%autosetup -p1 %build @@ -114,15 +100,13 @@ autoreconf -f -i --disable-static \ --enable-ubuntu-online-accounts=no -# Parallel build is broken in 3.12.12, but it will be fixed in the next release. -# TODO: Reenable parallel build. -make +%make_build install -m 0644 %{SOURCE1} ./README.ConnectionManagers %install -make install DESTDIR=$RPM_BUILD_ROOT -find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' +%make_install +find $RPM_BUILD_ROOT -name '*.la' -delete %find_lang %{name} --with-gnome %find_lang empathy-tpaw @@ -215,6 +199,10 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %{_datadir}/adium/message-styles/PlanetGNOME.AdiumMessageStyle/Contents/Resources/main.css %changelog +* Thu Jun 07 2018 Debarshi Ray - 3.12.13-1 +- Update to 3.12.13 +- Resolves: #1569812 + * Tue Mar 21 2017 Debarshi Ray - 3.12.12-4 - Fix certificate validation (use reference identities, handle validation failures correctly, fixed the test suite)