|
|
784ac3 |
From 7712a50a4c3dfecda6b6401ba5a9dff52a583ecb Mon Sep 17 00:00:00 2001
|
|
|
784ac3 |
From: Debarshi Ray <debarshir@gnome.org>
|
|
|
784ac3 |
Date: Wed, 15 Mar 2017 20:23:43 +0100
|
|
|
784ac3 |
Subject: [PATCH 1/5] tls-verifier: Handle GNUTLS_CERT_REVOKED
|
|
|
784ac3 |
|
|
|
784ac3 |
... by mapping it to TP_TLS_CERTIFICATE_REJECT_REASON_REVOKED.
|
|
|
784ac3 |
|
|
|
784ac3 |
https://bugzilla.gnome.org/show_bug.cgi?id=780160
|
|
|
784ac3 |
---
|
|
|
784ac3 |
libempathy/empathy-tls-verifier.c | 2 ++
|
|
|
784ac3 |
1 file changed, 2 insertions(+)
|
|
|
784ac3 |
|
|
|
784ac3 |
diff --git a/libempathy/empathy-tls-verifier.c b/libempathy/empathy-tls-verifier.c
|
|
|
784ac3 |
index fcbc559b3f97..8f80b4372de1 100644
|
|
|
784ac3 |
--- a/libempathy/empathy-tls-verifier.c
|
|
|
784ac3 |
+++ b/libempathy/empathy-tls-verifier.c
|
|
|
784ac3 |
@@ -98,6 +98,8 @@ verification_output_to_reason (gint res,
|
|
|
784ac3 |
*reason = TP_TLS_CERTIFICATE_REJECT_REASON_NOT_ACTIVATED;
|
|
|
784ac3 |
else if (verify_output & GNUTLS_CERT_EXPIRED)
|
|
|
784ac3 |
*reason = TP_TLS_CERTIFICATE_REJECT_REASON_EXPIRED;
|
|
|
784ac3 |
+ else if (verify_output & GNUTLS_CERT_REVOKED)
|
|
|
784ac3 |
+ *reason = TP_TLS_CERTIFICATE_REJECT_REASON_REVOKED;
|
|
|
784ac3 |
else
|
|
|
784ac3 |
*reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN;
|
|
|
784ac3 |
|
|
|
784ac3 |
--
|
|
|
784ac3 |
2.14.4
|
|
|
784ac3 |
|
|
|
784ac3 |
|
|
|
784ac3 |
From 8c5dc77f406308b77b4a6c7274ff8096091267a6 Mon Sep 17 00:00:00 2001
|
|
|
784ac3 |
From: Debarshi Ray <debarshir@gnome.org>
|
|
|
784ac3 |
Date: Mon, 20 Mar 2017 19:20:11 +0100
|
|
|
784ac3 |
Subject: [PATCH 2/5] tests: Fix comment
|
|
|
784ac3 |
|
|
|
784ac3 |
The existing comment was mistakenly copied from
|
|
|
784ac3 |
test_certificate_verify_success_with_full_chain.
|
|
|
784ac3 |
|
|
|
784ac3 |
This test case is about a certificate that has been pinned against a
|
|
|
784ac3 |
specific peer. The mock TLS connection doesn't have the full chain,
|
|
|
784ac3 |
but just the leaf-level certificate that has been pinned.
|
|
|
784ac3 |
|
|
|
784ac3 |
https://bugzilla.gnome.org/show_bug.cgi?id=780160
|
|
|
784ac3 |
---
|
|
|
784ac3 |
tests/empathy-tls-test.c | 4 ++--
|
|
|
784ac3 |
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
784ac3 |
|
|
|
784ac3 |
diff --git a/tests/empathy-tls-test.c b/tests/empathy-tls-test.c
|
|
|
784ac3 |
index 91b05761f9b9..0752e1b328c5 100644
|
|
|
784ac3 |
--- a/tests/empathy-tls-test.c
|
|
|
784ac3 |
+++ b/tests/empathy-tls-test.c
|
|
|
784ac3 |
@@ -654,8 +654,8 @@ test_certificate_verify_success_with_pinned (Test *test,
|
|
|
784ac3 |
};
|
|
|
784ac3 |
|
|
|
784ac3 |
/*
|
|
|
784ac3 |
- * In this test the mock TLS connection has a full certificate
|
|
|
784ac3 |
- * chain. We look for an anchor certificate in the chain.
|
|
|
784ac3 |
+ * In this test the mock TLS connection has a certificate that has
|
|
|
784ac3 |
+ * been pinned for the test-server.empathy.gnome.org peer.
|
|
|
784ac3 |
*/
|
|
|
784ac3 |
|
|
|
784ac3 |
test->mock = mock_tls_certificate_new_and_register (test->dbus,
|
|
|
784ac3 |
--
|
|
|
784ac3 |
2.14.4
|
|
|
784ac3 |
|
|
|
784ac3 |
|
|
|
784ac3 |
From 6fe06a78a7538cefa2333b180d58b330325796ab Mon Sep 17 00:00:00 2001
|
|
|
784ac3 |
From: Debarshi Ray <debarshir@gnome.org>
|
|
|
784ac3 |
Date: Mon, 20 Mar 2017 19:31:39 +0100
|
|
|
784ac3 |
Subject: [PATCH 3/5] tests: Actually test that hostnames of pinned
|
|
|
784ac3 |
certificates are verified
|
|
|
784ac3 |
|
|
|
784ac3 |
This test case is about ensuring that a pinned certificate won't be
|
|
|
784ac3 |
validated if the wrong hostname is used.
|
|
|
784ac3 |
|
|
|
784ac3 |
If we don't add the pinned certificate to our database, then checks for
|
|
|
784ac3 |
pinning are going to fail regardless of the hostname being used. The
|
|
|
784ac3 |
correct certificate-hostname pair needs to be in the database to ensure
|
|
|
784ac3 |
that the hostnames are being matched as advertised.
|
|
|
784ac3 |
|
|
|
784ac3 |
https://bugzilla.gnome.org/show_bug.cgi?id=780160
|
|
|
784ac3 |
---
|
|
|
784ac3 |
tests/empathy-tls-test.c | 3 ++-
|
|
|
784ac3 |
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
|
784ac3 |
|
|
|
784ac3 |
diff --git a/tests/empathy-tls-test.c b/tests/empathy-tls-test.c
|
|
|
784ac3 |
index 0752e1b328c5..422909e7cc2a 100644
|
|
|
784ac3 |
--- a/tests/empathy-tls-test.c
|
|
|
784ac3 |
+++ b/tests/empathy-tls-test.c
|
|
|
784ac3 |
@@ -695,7 +695,8 @@ test_certificate_verify_pinned_wrong_host (Test *test,
|
|
|
784ac3 |
test->mock = mock_tls_certificate_new_and_register (test->dbus,
|
|
|
784ac3 |
"server-cert.cer", NULL);
|
|
|
784ac3 |
|
|
|
784ac3 |
- /* Note that we're not adding any place to find root certs */
|
|
|
784ac3 |
+ /* We add the collabora directory with the collabora root */
|
|
|
784ac3 |
+ add_certificate_to_mock (test, "server-cert.cer", "test-server.empathy.gnome.org");
|
|
|
784ac3 |
|
|
|
784ac3 |
ensure_certificate_proxy (test);
|
|
|
784ac3 |
|
|
|
784ac3 |
--
|
|
|
784ac3 |
2.14.4
|
|
|
784ac3 |
|
|
|
784ac3 |
|
|
|
784ac3 |
From f07492434449bcdd74a61aa74596884ef5700d88 Mon Sep 17 00:00:00 2001
|
|
|
784ac3 |
From: Debarshi Ray <debarshir@gnome.org>
|
|
|
784ac3 |
Date: Wed, 15 Mar 2017 20:24:08 +0100
|
|
|
784ac3 |
Subject: [PATCH 4/5] tls-verifier: Use GIO to verify the chain of TLS
|
|
|
784ac3 |
certificates
|
|
|
784ac3 |
|
|
|
784ac3 |
Gcr has its own hand rolled code to complete the certificate chain and
|
|
|
784ac3 |
validate it, which predates the equivalent functionality in GIO. These
|
|
|
784ac3 |
days, GIO's GnuTLS backend is a better option because it defers to
|
|
|
784ac3 |
GnuTLS to do the right thing. It benefits automatically from any
|
|
|
784ac3 |
improvements made to GnuTLS itself.
|
|
|
784ac3 |
|
|
|
784ac3 |
However, GIO doesn't support certificate pinning. Gcr continues to
|
|
|
784ac3 |
provide that feature.
|
|
|
784ac3 |
|
|
|
784ac3 |
Note:
|
|
|
784ac3 |
|
|
|
784ac3 |
(a) We don't set "certificate-hostname" when we encounter
|
|
|
784ac3 |
TP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH. The resulting loss
|
|
|
784ac3 |
of verbosity in EmpathyTLSDialog is balanced by no longer relying on a
|
|
|
784ac3 |
specific encryption library.
|
|
|
784ac3 |
|
|
|
784ac3 |
(b) glib-networking doesn't differentiate between
|
|
|
784ac3 |
GNUTLS_CERT_SIGNER_NOT_FOUND and GNUTLS_CERT_SIGNER_NOT_CA. Hence, we
|
|
|
784ac3 |
club them together as TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED and we
|
|
|
784ac3 |
no longer return TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED.
|
|
|
784ac3 |
|
|
|
784ac3 |
(c) Unlike Gcr, GnuTLS doesn't seem to provide a way to load a PKCS#11
|
|
|
784ac3 |
module that's built into the code, as opposed to being a shared object.
|
|
|
784ac3 |
This makes it hard for us to load our mock PKCS#11 module. Therefore,
|
|
|
784ac3 |
we have disabled the test case that relies on using PKCS#11 storage to
|
|
|
784ac3 |
complete the certificate chain.
|
|
|
784ac3 |
|
|
|
784ac3 |
Bump required GLib version to 2.48. We really do need 2.48 because we
|
|
|
784ac3 |
rely on the improvements to GIO's GnuTLS backend.
|
|
|
784ac3 |
|
|
|
784ac3 |
https://bugzilla.gnome.org/show_bug.cgi?id=780160
|
|
|
784ac3 |
---
|
|
|
784ac3 |
configure.ac | 6 +-
|
|
|
784ac3 |
libempathy/empathy-tls-verifier.c | 419 ++++++++++++++++++--------------------
|
|
|
784ac3 |
libempathy/empathy-tls-verifier.h | 3 +
|
|
|
784ac3 |
tests/empathy-tls-test.c | 35 +++-
|
|
|
784ac3 |
4 files changed, 232 insertions(+), 231 deletions(-)
|
|
|
784ac3 |
|
|
|
784ac3 |
diff --git a/configure.ac b/configure.ac
|
|
|
784ac3 |
index a427eba3af56..cd6f371de799 100644
|
|
|
784ac3 |
--- a/configure.ac
|
|
|
784ac3 |
+++ b/configure.ac
|
|
|
784ac3 |
@@ -37,9 +37,9 @@ AC_COPYRIGHT([
|
|
|
784ac3 |
FOLKS_REQUIRED=0.9.5
|
|
|
784ac3 |
GNUTLS_REQUIRED=2.8.5
|
|
|
784ac3 |
|
|
|
784ac3 |
-GLIB_REQUIRED=2.37.6
|
|
|
784ac3 |
-AC_DEFINE(GLIB_VERSION_MIN_REQUIRED, GLIB_VERSION_2_30, [Ignore post 2.30 deprecations])
|
|
|
784ac3 |
-AC_DEFINE(GLIB_VERSION_MAX_ALLOWED, GLIB_VERSION_2_38, [Prevent post 2.38 APIs])
|
|
|
784ac3 |
+GLIB_REQUIRED=2.48.0
|
|
|
784ac3 |
+AC_DEFINE(GLIB_VERSION_MIN_REQUIRED, GLIB_VERSION_2_48, [Ignore post 2.48 deprecations])
|
|
|
784ac3 |
+AC_DEFINE(GLIB_VERSION_MAX_ALLOWED, GLIB_VERSION_2_48, [Prevent post 2.48 APIs])
|
|
|
784ac3 |
|
|
|
784ac3 |
GTK_REQUIRED=3.9.4
|
|
|
784ac3 |
AC_DEFINE(GDK_VERSION_MIN_REQUIRED, GDK_VERSION_3_8, [Ignore post 3.8 deprecations])
|
|
|
784ac3 |
diff --git a/libempathy/empathy-tls-verifier.c b/libempathy/empathy-tls-verifier.c
|
|
|
784ac3 |
index 8f80b4372de1..a8306bb569ea 100644
|
|
|
784ac3 |
--- a/libempathy/empathy-tls-verifier.c
|
|
|
784ac3 |
+++ b/libempathy/empathy-tls-verifier.c
|
|
|
784ac3 |
@@ -1,7 +1,9 @@
|
|
|
784ac3 |
/*
|
|
|
784ac3 |
* empathy-tls-verifier.c - Source for EmpathyTLSVerifier
|
|
|
784ac3 |
* Copyright (C) 2010 Collabora Ltd.
|
|
|
784ac3 |
+ * Copyright (C) 2017 Red Hat, Inc.
|
|
|
784ac3 |
* @author Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
|
|
|
784ac3 |
+ * @author Debarshi Ray <debarshir@gnome.org>
|
|
|
784ac3 |
* @author Stef Walter <stefw@collabora.co.uk>
|
|
|
784ac3 |
*
|
|
|
784ac3 |
* This library is free software; you can redistribute it and/or
|
|
|
784ac3 |
@@ -43,6 +45,8 @@ enum {
|
|
|
784ac3 |
};
|
|
|
784ac3 |
|
|
|
784ac3 |
typedef struct {
|
|
|
784ac3 |
+ GTlsCertificate *g_certificate;
|
|
|
784ac3 |
+ GTlsDatabase *database;
|
|
|
784ac3 |
TpTLSCertificate *certificate;
|
|
|
784ac3 |
gchar *hostname;
|
|
|
784ac3 |
gchar **reference_identities;
|
|
|
784ac3 |
@@ -53,135 +57,86 @@ typedef struct {
|
|
|
784ac3 |
gboolean dispose_run;
|
|
|
784ac3 |
} EmpathyTLSVerifierPriv;
|
|
|
784ac3 |
|
|
|
784ac3 |
-static gboolean
|
|
|
784ac3 |
-verification_output_to_reason (gint res,
|
|
|
784ac3 |
- guint verify_output,
|
|
|
784ac3 |
- TpTLSCertificateRejectReason *reason)
|
|
|
784ac3 |
+static GTlsCertificate *
|
|
|
784ac3 |
+tls_certificate_new_from_der (GPtrArray *data, GError **error)
|
|
|
784ac3 |
{
|
|
|
784ac3 |
- gboolean retval = TRUE;
|
|
|
784ac3 |
+ GTlsBackend *tls_backend;
|
|
|
784ac3 |
+ GTlsCertificate *cert = NULL;
|
|
|
784ac3 |
+ GTlsCertificate *issuer = NULL;
|
|
|
784ac3 |
+ GTlsCertificate *retval = NULL;
|
|
|
784ac3 |
+ GType tls_certificate_type;
|
|
|
784ac3 |
+ gint i;
|
|
|
784ac3 |
|
|
|
784ac3 |
- g_assert (reason != NULL);
|
|
|
784ac3 |
+ g_return_val_if_fail (error == NULL || *error == NULL, NULL);
|
|
|
784ac3 |
|
|
|
784ac3 |
- if (res != GNUTLS_E_SUCCESS)
|
|
|
784ac3 |
- {
|
|
|
784ac3 |
- retval = FALSE;
|
|
|
784ac3 |
+ tls_backend = g_tls_backend_get_default ();
|
|
|
784ac3 |
+ tls_certificate_type = g_tls_backend_get_certificate_type (tls_backend);
|
|
|
784ac3 |
|
|
|
784ac3 |
- /* the certificate is not structurally valid */
|
|
|
784ac3 |
- switch (res)
|
|
|
784ac3 |
- {
|
|
|
784ac3 |
- case GNUTLS_E_INSUFFICIENT_CREDENTIALS:
|
|
|
784ac3 |
- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED;
|
|
|
784ac3 |
- break;
|
|
|
784ac3 |
- case GNUTLS_E_CONSTRAINT_ERROR:
|
|
|
784ac3 |
- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_LIMIT_EXCEEDED;
|
|
|
784ac3 |
- break;
|
|
|
784ac3 |
- default:
|
|
|
784ac3 |
- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN;
|
|
|
784ac3 |
- break;
|
|
|
784ac3 |
- }
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- goto out;
|
|
|
784ac3 |
+ for (i = (gint) data->len - 1; i >= 0; --i)
|
|
|
784ac3 |
+ {
|
|
|
784ac3 |
+ GArray *cert_data;
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ cert_data = g_ptr_array_index (data, i);
|
|
|
784ac3 |
+ cert = g_initable_new (tls_certificate_type,
|
|
|
784ac3 |
+ NULL,
|
|
|
784ac3 |
+ error,
|
|
|
784ac3 |
+ "certificate", (GByteArray *) cert_data,
|
|
|
784ac3 |
+ "issuer", issuer,
|
|
|
784ac3 |
+ NULL);
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ if (cert == NULL)
|
|
|
784ac3 |
+ goto out;
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ g_clear_object (&issuer);
|
|
|
784ac3 |
+ issuer = g_object_ref (cert);
|
|
|
784ac3 |
+ g_clear_object (&cert);
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
- /* the certificate is structurally valid, check for other errors. */
|
|
|
784ac3 |
- if (verify_output & GNUTLS_CERT_INVALID)
|
|
|
784ac3 |
- {
|
|
|
784ac3 |
- retval = FALSE;
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- if (verify_output & GNUTLS_CERT_SIGNER_NOT_FOUND)
|
|
|
784ac3 |
- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED;
|
|
|
784ac3 |
- else if (verify_output & GNUTLS_CERT_SIGNER_NOT_CA)
|
|
|
784ac3 |
- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED;
|
|
|
784ac3 |
- else if (verify_output & GNUTLS_CERT_INSECURE_ALGORITHM)
|
|
|
784ac3 |
- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_INSECURE;
|
|
|
784ac3 |
- else if (verify_output & GNUTLS_CERT_NOT_ACTIVATED)
|
|
|
784ac3 |
- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_NOT_ACTIVATED;
|
|
|
784ac3 |
- else if (verify_output & GNUTLS_CERT_EXPIRED)
|
|
|
784ac3 |
- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_EXPIRED;
|
|
|
784ac3 |
- else if (verify_output & GNUTLS_CERT_REVOKED)
|
|
|
784ac3 |
- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_REVOKED;
|
|
|
784ac3 |
- else
|
|
|
784ac3 |
- *reason = TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN;
|
|
|
784ac3 |
+ g_assert_null (cert);
|
|
|
784ac3 |
+ g_assert_true (G_IS_TLS_CERTIFICATE (issuer));
|
|
|
784ac3 |
|
|
|
784ac3 |
- goto out;
|
|
|
784ac3 |
- }
|
|
|
784ac3 |
+ retval = g_object_ref (issuer);
|
|
|
784ac3 |
|
|
|
784ac3 |
out:
|
|
|
784ac3 |
+ g_clear_object (&cert);
|
|
|
784ac3 |
+ g_clear_object (&issuer);
|
|
|
784ac3 |
return retval;
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
-static void
|
|
|
784ac3 |
-build_certificate_list_for_gnutls (GcrCertificateChain *chain,
|
|
|
784ac3 |
- gnutls_x509_crt_t **list,
|
|
|
784ac3 |
- guint *n_list,
|
|
|
784ac3 |
- gnutls_x509_crt_t **anchors,
|
|
|
784ac3 |
- guint *n_anchors)
|
|
|
784ac3 |
+static TpTLSCertificateRejectReason
|
|
|
784ac3 |
+verification_output_to_reason (GTlsCertificateFlags flags)
|
|
|
784ac3 |
{
|
|
|
784ac3 |
- GcrCertificate *cert;
|
|
|
784ac3 |
- guint idx, length;
|
|
|
784ac3 |
- gnutls_x509_crt_t *retval;
|
|
|
784ac3 |
- gnutls_x509_crt_t gcert;
|
|
|
784ac3 |
- gnutls_datum_t datum;
|
|
|
784ac3 |
- gsize n_data;
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- g_assert (list);
|
|
|
784ac3 |
- g_assert (n_list);
|
|
|
784ac3 |
- g_assert (anchors);
|
|
|
784ac3 |
- g_assert (n_anchors);
|
|
|
784ac3 |
+ TpTLSCertificateRejectReason retval;
|
|
|
784ac3 |
|
|
|
784ac3 |
- *list = *anchors = NULL;
|
|
|
784ac3 |
- *n_list = *n_anchors = 0;
|
|
|
784ac3 |
+ g_assert (flags != 0);
|
|
|
784ac3 |
|
|
|
784ac3 |
- length = gcr_certificate_chain_get_length (chain);
|
|
|
784ac3 |
- retval = g_malloc0 (sizeof (gnutls_x509_crt_t) * length);
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- /* Convert the main body of the chain to gnutls */
|
|
|
784ac3 |
- for (idx = 0; idx < length; ++idx)
|
|
|
784ac3 |
- {
|
|
|
784ac3 |
- cert = gcr_certificate_chain_get_certificate (chain, idx);
|
|
|
784ac3 |
- datum.data = (gpointer)gcr_certificate_get_der_data (cert, &n_data);
|
|
|
784ac3 |
- datum.size = n_data;
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- gnutls_x509_crt_init (&gcert);
|
|
|
784ac3 |
- if (gnutls_x509_crt_import (gcert, &datum, GNUTLS_X509_FMT_DER) < 0)
|
|
|
784ac3 |
- g_return_if_reached ();
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- retval[idx] = gcert;
|
|
|
784ac3 |
- }
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- *list = retval;
|
|
|
784ac3 |
- *n_list = length;
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- /* See if we have an anchor */
|
|
|
784ac3 |
- if (gcr_certificate_chain_get_status (chain) ==
|
|
|
784ac3 |
- GCR_CERTIFICATE_CHAIN_ANCHORED)
|
|
|
784ac3 |
+ switch (flags)
|
|
|
784ac3 |
{
|
|
|
784ac3 |
- cert = gcr_certificate_chain_get_anchor (chain);
|
|
|
784ac3 |
- g_return_if_fail (cert);
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- datum.data = (gpointer)gcr_certificate_get_der_data (cert, &n_data);
|
|
|
784ac3 |
- datum.size = n_data;
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- gnutls_x509_crt_init (&gcert);
|
|
|
784ac3 |
- if (gnutls_x509_crt_import (gcert, &datum, GNUTLS_X509_FMT_DER) < 0)
|
|
|
784ac3 |
- g_return_if_reached ();
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- retval = g_malloc0 (sizeof (gnutls_x509_crt_t) * 1);
|
|
|
784ac3 |
- retval[0] = gcert;
|
|
|
784ac3 |
- *anchors = retval;
|
|
|
784ac3 |
- *n_anchors = 1;
|
|
|
784ac3 |
+ case G_TLS_CERTIFICATE_UNKNOWN_CA:
|
|
|
784ac3 |
+ retval = TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED;
|
|
|
784ac3 |
+ break;
|
|
|
784ac3 |
+ case G_TLS_CERTIFICATE_BAD_IDENTITY:
|
|
|
784ac3 |
+ retval = TP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH;
|
|
|
784ac3 |
+ break;
|
|
|
784ac3 |
+ case G_TLS_CERTIFICATE_NOT_ACTIVATED:
|
|
|
784ac3 |
+ retval = TP_TLS_CERTIFICATE_REJECT_REASON_NOT_ACTIVATED;
|
|
|
784ac3 |
+ break;
|
|
|
784ac3 |
+ case G_TLS_CERTIFICATE_EXPIRED:
|
|
|
784ac3 |
+ retval = TP_TLS_CERTIFICATE_REJECT_REASON_EXPIRED;
|
|
|
784ac3 |
+ break;
|
|
|
784ac3 |
+ case G_TLS_CERTIFICATE_REVOKED:
|
|
|
784ac3 |
+ retval = TP_TLS_CERTIFICATE_REJECT_REASON_REVOKED;
|
|
|
784ac3 |
+ break;
|
|
|
784ac3 |
+ case G_TLS_CERTIFICATE_INSECURE:
|
|
|
784ac3 |
+ retval = TP_TLS_CERTIFICATE_REJECT_REASON_INSECURE;
|
|
|
784ac3 |
+ break;
|
|
|
784ac3 |
+ case G_TLS_CERTIFICATE_GENERIC_ERROR:
|
|
|
784ac3 |
+ default:
|
|
|
784ac3 |
+ retval = TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN;
|
|
|
784ac3 |
+ break;
|
|
|
784ac3 |
}
|
|
|
784ac3 |
-}
|
|
|
784ac3 |
|
|
|
784ac3 |
-static void
|
|
|
784ac3 |
-free_certificate_list_for_gnutls (gnutls_x509_crt_t *list,
|
|
|
784ac3 |
- guint n_list)
|
|
|
784ac3 |
-{
|
|
|
784ac3 |
- guint idx;
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- for (idx = 0; idx < n_list; idx++)
|
|
|
784ac3 |
- gnutls_x509_crt_deinit (list[idx]);
|
|
|
784ac3 |
- g_free (list);
|
|
|
784ac3 |
+ return retval;
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
static void
|
|
|
784ac3 |
@@ -193,6 +148,7 @@ complete_verification (EmpathyTLSVerifier *self)
|
|
|
784ac3 |
|
|
|
784ac3 |
g_simple_async_result_complete_in_idle (priv->verify_result);
|
|
|
784ac3 |
|
|
|
784ac3 |
+ g_clear_object (&priv->g_certificate);
|
|
|
784ac3 |
tp_clear_object (&priv->verify_result);
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
@@ -209,6 +165,7 @@ abort_verification (EmpathyTLSVerifier *self,
|
|
|
784ac3 |
reason);
|
|
|
784ac3 |
g_simple_async_result_complete_in_idle (priv->verify_result);
|
|
|
784ac3 |
|
|
|
784ac3 |
+ g_clear_object (&priv->g_certificate);
|
|
|
784ac3 |
tp_clear_object (&priv->verify_result);
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
@@ -221,142 +178,137 @@ debug_certificate (GcrCertificate *cert)
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
static void
|
|
|
784ac3 |
-debug_certificate_chain (GcrCertificateChain *chain)
|
|
|
784ac3 |
+verify_chain_cb (GObject *object,
|
|
|
784ac3 |
+ GAsyncResult *res,
|
|
|
784ac3 |
+ gpointer user_data)
|
|
|
784ac3 |
{
|
|
|
784ac3 |
- GEnumClass *enum_class;
|
|
|
784ac3 |
- GEnumValue *enum_value;
|
|
|
784ac3 |
- gint idx, length;
|
|
|
784ac3 |
- GcrCertificate *cert;
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- enum_class = G_ENUM_CLASS
|
|
|
784ac3 |
- (g_type_class_peek (GCR_TYPE_CERTIFICATE_CHAIN_STATUS));
|
|
|
784ac3 |
- enum_value = g_enum_get_value (enum_class,
|
|
|
784ac3 |
- gcr_certificate_chain_get_status (chain));
|
|
|
784ac3 |
- length = gcr_certificate_chain_get_length (chain);
|
|
|
784ac3 |
- DEBUG ("Certificate chain: length %u status %s",
|
|
|
784ac3 |
- length, enum_value ? enum_value->value_nick : "XXX");
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- for (idx = 0; idx < length; ++idx)
|
|
|
784ac3 |
- {
|
|
|
784ac3 |
- cert = gcr_certificate_chain_get_certificate (chain, idx);
|
|
|
784ac3 |
- debug_certificate (cert);
|
|
|
784ac3 |
- }
|
|
|
784ac3 |
-}
|
|
|
784ac3 |
+ GError *error = NULL;
|
|
|
784ac3 |
|
|
|
784ac3 |
-static void
|
|
|
784ac3 |
-perform_verification (EmpathyTLSVerifier *self,
|
|
|
784ac3 |
- GcrCertificateChain *chain)
|
|
|
784ac3 |
-{
|
|
|
784ac3 |
- gboolean ret = FALSE;
|
|
|
784ac3 |
- TpTLSCertificateRejectReason reason =
|
|
|
784ac3 |
- TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN;
|
|
|
784ac3 |
- gnutls_x509_crt_t *list, *anchors;
|
|
|
784ac3 |
- guint n_list, n_anchors;
|
|
|
784ac3 |
- guint verify_output;
|
|
|
784ac3 |
- gint res;
|
|
|
784ac3 |
+ GTlsCertificateFlags flags;
|
|
|
784ac3 |
+ GTlsDatabase *tls_database = G_TLS_DATABASE (object);
|
|
|
784ac3 |
gint i;
|
|
|
784ac3 |
- gboolean matched = FALSE;
|
|
|
784ac3 |
+ EmpathyTLSVerifier *self = EMPATHY_TLS_VERIFIER (user_data);
|
|
|
784ac3 |
EmpathyTLSVerifierPriv *priv = GET_PRIV (self);
|
|
|
784ac3 |
|
|
|
784ac3 |
- DEBUG ("Performing verification");
|
|
|
784ac3 |
- debug_certificate_chain (chain);
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- list = anchors = NULL;
|
|
|
784ac3 |
- n_list = n_anchors = 0;
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- /*
|
|
|
784ac3 |
- * If the first certificate is an pinned certificate then we completely
|
|
|
784ac3 |
- * ignore the rest of the verification process.
|
|
|
784ac3 |
+ /* FIXME: g_tls_database_verify_chain doesn't set the GError if the
|
|
|
784ac3 |
+ * certificate chain couldn't be verified. See:
|
|
|
784ac3 |
+ * https://bugzilla.gnome.org/show_bug.cgi?id=780310
|
|
|
784ac3 |
*/
|
|
|
784ac3 |
- if (gcr_certificate_chain_get_status (chain) == GCR_CERTIFICATE_CHAIN_PINNED)
|
|
|
784ac3 |
+ flags = g_tls_database_verify_chain_finish (tls_database, res, &error);
|
|
|
784ac3 |
+ if (flags != 0)
|
|
|
784ac3 |
{
|
|
|
784ac3 |
- DEBUG ("Found pinned certificate for %s", priv->hostname);
|
|
|
784ac3 |
- complete_verification (self);
|
|
|
784ac3 |
- goto out;
|
|
|
784ac3 |
- }
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- build_certificate_list_for_gnutls (chain, &list, &n_list,
|
|
|
784ac3 |
- &anchors, &n_anchors);
|
|
|
784ac3 |
- if (list == NULL || n_list == 0) {
|
|
|
784ac3 |
- g_warn_if_reached ();
|
|
|
784ac3 |
- abort_verification (self, TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN);
|
|
|
784ac3 |
- goto out;
|
|
|
784ac3 |
- }
|
|
|
784ac3 |
+ TpTLSCertificateRejectReason reason;
|
|
|
784ac3 |
|
|
|
784ac3 |
- verify_output = 0;
|
|
|
784ac3 |
- res = gnutls_x509_crt_list_verify (list, n_list, anchors, n_anchors,
|
|
|
784ac3 |
- NULL, 0, 0, &verify_output);
|
|
|
784ac3 |
- ret = verification_output_to_reason (res, verify_output, &reason);
|
|
|
784ac3 |
+ /* We don't pass the identity to g_tls_database_verify. */
|
|
|
784ac3 |
+ g_assert_false (flags & G_TLS_CERTIFICATE_BAD_IDENTITY);
|
|
|
784ac3 |
|
|
|
784ac3 |
- DEBUG ("Certificate verification gave result %d with reason %u", ret,
|
|
|
784ac3 |
+ reason = verification_output_to_reason (flags);
|
|
|
784ac3 |
+ DEBUG ("Certificate verification gave flags %d with reason %u",
|
|
|
784ac3 |
+ (gint) flags,
|
|
|
784ac3 |
reason);
|
|
|
784ac3 |
|
|
|
784ac3 |
- if (!ret) {
|
|
|
784ac3 |
abort_verification (self, reason);
|
|
|
784ac3 |
+ g_clear_error (&error);
|
|
|
784ac3 |
goto out;
|
|
|
784ac3 |
- }
|
|
|
784ac3 |
+ }
|
|
|
784ac3 |
|
|
|
784ac3 |
- /* now check if the certificate matches one of the reference identities. */
|
|
|
784ac3 |
- if (priv->reference_identities != NULL)
|
|
|
784ac3 |
+ for (i = 0; priv->reference_identities[i] != NULL; i++)
|
|
|
784ac3 |
{
|
|
|
784ac3 |
- for (i = 0, matched = FALSE; priv->reference_identities[i] != NULL; ++i)
|
|
|
784ac3 |
- {
|
|
|
784ac3 |
- if (gnutls_x509_crt_check_hostname (list[0],
|
|
|
784ac3 |
- priv->reference_identities[i]) == 1)
|
|
|
784ac3 |
- {
|
|
|
784ac3 |
- matched = TRUE;
|
|
|
784ac3 |
- break;
|
|
|
784ac3 |
- }
|
|
|
784ac3 |
- }
|
|
|
784ac3 |
+ GSocketConnectable *identity = NULL;
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ identity = g_network_address_new (priv->reference_identities[i], 0);
|
|
|
784ac3 |
+ flags = g_tls_certificate_verify (priv->g_certificate, identity, NULL);
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ g_object_unref (identity);
|
|
|
784ac3 |
+ if (flags == 0)
|
|
|
784ac3 |
+ break;
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
- if (!matched)
|
|
|
784ac3 |
+ if (flags != 0)
|
|
|
784ac3 |
{
|
|
|
784ac3 |
- gchar *certified_hostname;
|
|
|
784ac3 |
+ TpTLSCertificateRejectReason reason;
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ g_assert_cmpint (flags, ==, G_TLS_CERTIFICATE_BAD_IDENTITY);
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ reason = verification_output_to_reason (flags);
|
|
|
784ac3 |
+ DEBUG ("Certificate verification gave flags %d with reason %u",
|
|
|
784ac3 |
+ (gint) flags,
|
|
|
784ac3 |
+ reason);
|
|
|
784ac3 |
|
|
|
784ac3 |
- certified_hostname = empathy_get_x509_certificate_hostname (list[0]);
|
|
|
784ac3 |
- tp_asv_set_string (priv->details,
|
|
|
784ac3 |
- "expected-hostname", priv->hostname);
|
|
|
784ac3 |
- tp_asv_set_string (priv->details,
|
|
|
784ac3 |
- "certificate-hostname", certified_hostname);
|
|
|
784ac3 |
+ /* FIXME: We don't set "certificate-hostname" because
|
|
|
784ac3 |
+ * GTlsCertificate doesn't expose the hostname used in the
|
|
|
784ac3 |
+ * certificate. We will temporarily lose some verbosity in
|
|
|
784ac3 |
+ * EmpathyTLSDialog, but that's balanced by no longer
|
|
|
784ac3 |
+ * relying on a specific encryption library.
|
|
|
784ac3 |
+ */
|
|
|
784ac3 |
+ tp_asv_set_string (priv->details, "expected-hostname", priv->hostname);
|
|
|
784ac3 |
|
|
|
784ac3 |
- DEBUG ("Hostname mismatch: got %s but expected %s",
|
|
|
784ac3 |
- certified_hostname, priv->hostname);
|
|
|
784ac3 |
+ DEBUG ("Hostname mismatch: expected %s", priv->hostname);
|
|
|
784ac3 |
|
|
|
784ac3 |
- g_free (certified_hostname);
|
|
|
784ac3 |
- abort_verification (self,
|
|
|
784ac3 |
- TP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH);
|
|
|
784ac3 |
+ abort_verification (self, reason);
|
|
|
784ac3 |
goto out;
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
- DEBUG ("Hostname matched");
|
|
|
784ac3 |
+ DEBUG ("Verified certificate chain");
|
|
|
784ac3 |
complete_verification (self);
|
|
|
784ac3 |
|
|
|
784ac3 |
- out:
|
|
|
784ac3 |
- free_certificate_list_for_gnutls (list, n_list);
|
|
|
784ac3 |
- free_certificate_list_for_gnutls (anchors, n_anchors);
|
|
|
784ac3 |
+out:
|
|
|
784ac3 |
+ /* Matches ref when starting verify chain */
|
|
|
784ac3 |
+ g_object_unref (self);
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
static void
|
|
|
784ac3 |
-perform_verification_cb (GObject *object,
|
|
|
784ac3 |
- GAsyncResult *res,
|
|
|
784ac3 |
- gpointer user_data)
|
|
|
784ac3 |
+is_certificate_pinned_cb (GObject *object,
|
|
|
784ac3 |
+ GAsyncResult *res,
|
|
|
784ac3 |
+ gpointer user_data)
|
|
|
784ac3 |
{
|
|
|
784ac3 |
GError *error = NULL;
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- GcrCertificateChain *chain = GCR_CERTIFICATE_CHAIN (object);
|
|
|
784ac3 |
+ GPtrArray *cert_data;
|
|
|
784ac3 |
EmpathyTLSVerifier *self = EMPATHY_TLS_VERIFIER (user_data);
|
|
|
784ac3 |
+ EmpathyTLSVerifierPriv *priv = GET_PRIV (self);
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ if (gcr_trust_is_certificate_pinned_finish (res, &error))
|
|
|
784ac3 |
+ {
|
|
|
784ac3 |
+ DEBUG ("Found pinned certificate for %s", priv->hostname);
|
|
|
784ac3 |
+ complete_verification (self);
|
|
|
784ac3 |
+ goto out;
|
|
|
784ac3 |
+ }
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ /* error is set only when there is an actual failure. It won't be
|
|
|
784ac3 |
+ * set, if it successfully determined that the ceritificate was not
|
|
|
784ac3 |
+ * pinned. */
|
|
|
784ac3 |
+ if (error != NULL)
|
|
|
784ac3 |
+ {
|
|
|
784ac3 |
+ DEBUG ("Failed to determine if certificate is pinned: %s",
|
|
|
784ac3 |
+ error->message);
|
|
|
784ac3 |
+ g_clear_error (&error);
|
|
|
784ac3 |
+ }
|
|
|
784ac3 |
|
|
|
784ac3 |
- /* Even if building the chain fails, try verifying what we have */
|
|
|
784ac3 |
- if (!gcr_certificate_chain_build_finish (chain, res, &error))
|
|
|
784ac3 |
+ cert_data = tp_tls_certificate_get_cert_data (priv->certificate);
|
|
|
784ac3 |
+ priv->g_certificate = tls_certificate_new_from_der (cert_data, &error);
|
|
|
784ac3 |
+ if (error != NULL)
|
|
|
784ac3 |
{
|
|
|
784ac3 |
- DEBUG ("Building of certificate chain failed: %s", error->message);
|
|
|
784ac3 |
+ DEBUG ("Verification of certificate chain failed: %s", error->message);
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ abort_verification (self, TP_TLS_CERTIFICATE_REJECT_REASON_UNKNOWN);
|
|
|
784ac3 |
g_clear_error (&error);
|
|
|
784ac3 |
+ goto out;
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
- perform_verification (self, chain);
|
|
|
784ac3 |
+ DEBUG ("Performing verification");
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ g_tls_database_verify_chain_async (priv->database,
|
|
|
784ac3 |
+ priv->g_certificate,
|
|
|
784ac3 |
+ G_TLS_DATABASE_PURPOSE_AUTHENTICATE_SERVER,
|
|
|
784ac3 |
+ NULL,
|
|
|
784ac3 |
+ NULL,
|
|
|
784ac3 |
+ G_TLS_DATABASE_VERIFY_NONE,
|
|
|
784ac3 |
+ NULL,
|
|
|
784ac3 |
+ verify_chain_cb,
|
|
|
784ac3 |
+ g_object_ref (self));
|
|
|
784ac3 |
|
|
|
784ac3 |
- /* Matches ref when staring chain build */
|
|
|
784ac3 |
+out:
|
|
|
784ac3 |
+ /* Matches ref when starting is certificate pinned */
|
|
|
784ac3 |
g_object_unref (self);
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
@@ -420,6 +372,8 @@ empathy_tls_verifier_dispose (GObject *object)
|
|
|
784ac3 |
|
|
|
784ac3 |
priv->dispose_run = TRUE;
|
|
|
784ac3 |
|
|
|
784ac3 |
+ g_clear_object (&priv->g_certificate);
|
|
|
784ac3 |
+ g_clear_object (&priv->database);
|
|
|
784ac3 |
tp_clear_object (&priv->certificate);
|
|
|
784ac3 |
|
|
|
784ac3 |
G_OBJECT_CLASS (empathy_tls_verifier_parent_class)->dispose (object);
|
|
|
784ac3 |
@@ -443,10 +397,14 @@ static void
|
|
|
784ac3 |
empathy_tls_verifier_init (EmpathyTLSVerifier *self)
|
|
|
784ac3 |
{
|
|
|
784ac3 |
EmpathyTLSVerifierPriv *priv;
|
|
|
784ac3 |
+ GTlsBackend *tls_backend;
|
|
|
784ac3 |
|
|
|
784ac3 |
priv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
|
|
|
784ac3 |
EMPATHY_TYPE_TLS_VERIFIER, EmpathyTLSVerifierPriv);
|
|
|
784ac3 |
priv->details = tp_asv_new (NULL, NULL);
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ tls_backend = g_tls_backend_get_default ();
|
|
|
784ac3 |
+ priv->database = g_tls_backend_get_default_database (tls_backend);
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
static void
|
|
|
784ac3 |
@@ -503,16 +461,15 @@ empathy_tls_verifier_verify_async (EmpathyTLSVerifier *self,
|
|
|
784ac3 |
GAsyncReadyCallback callback,
|
|
|
784ac3 |
gpointer user_data)
|
|
|
784ac3 |
{
|
|
|
784ac3 |
- GcrCertificateChain *chain;
|
|
|
784ac3 |
GcrCertificate *cert;
|
|
|
784ac3 |
GPtrArray *cert_data;
|
|
|
784ac3 |
GArray *data;
|
|
|
784ac3 |
- guint idx;
|
|
|
784ac3 |
EmpathyTLSVerifierPriv *priv = GET_PRIV (self);
|
|
|
784ac3 |
|
|
|
784ac3 |
DEBUG ("Starting verification");
|
|
|
784ac3 |
|
|
|
784ac3 |
g_return_if_fail (priv->verify_result == NULL);
|
|
|
784ac3 |
+ g_return_if_fail (priv->g_certificate == NULL);
|
|
|
784ac3 |
|
|
|
784ac3 |
cert_data = tp_tls_certificate_get_cert_data (priv->certificate);
|
|
|
784ac3 |
g_return_if_fail (cert_data);
|
|
|
784ac3 |
@@ -520,19 +477,22 @@ empathy_tls_verifier_verify_async (EmpathyTLSVerifier *self,
|
|
|
784ac3 |
priv->verify_result = g_simple_async_result_new (G_OBJECT (self),
|
|
|
784ac3 |
callback, user_data, NULL);
|
|
|
784ac3 |
|
|
|
784ac3 |
- /* Create a certificate chain */
|
|
|
784ac3 |
- chain = gcr_certificate_chain_new ();
|
|
|
784ac3 |
- for (idx = 0; idx < cert_data->len; ++idx) {
|
|
|
784ac3 |
- data = g_ptr_array_index (cert_data, idx);
|
|
|
784ac3 |
- cert = gcr_simple_certificate_new ((guchar *) data->data, data->len);
|
|
|
784ac3 |
- gcr_certificate_chain_add (chain, cert);
|
|
|
784ac3 |
- g_object_unref (cert);
|
|
|
784ac3 |
- }
|
|
|
784ac3 |
+ /* The first certificate in the chain is for the host */
|
|
|
784ac3 |
+ data = g_ptr_array_index (cert_data, 0);
|
|
|
784ac3 |
+ cert = gcr_simple_certificate_new ((gpointer) data->data,
|
|
|
784ac3 |
+ (gsize) data->len);
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ DEBUG ("Checking if certificate is pinned:");
|
|
|
784ac3 |
+ debug_certificate (cert);
|
|
|
784ac3 |
|
|
|
784ac3 |
- gcr_certificate_chain_build_async (chain, GCR_PURPOSE_SERVER_AUTH, priv->hostname, 0,
|
|
|
784ac3 |
- NULL, perform_verification_cb, g_object_ref (self));
|
|
|
784ac3 |
+ gcr_trust_is_certificate_pinned_async (cert,
|
|
|
784ac3 |
+ GCR_PURPOSE_SERVER_AUTH,
|
|
|
784ac3 |
+ priv->hostname,
|
|
|
784ac3 |
+ NULL,
|
|
|
784ac3 |
+ is_certificate_pinned_cb,
|
|
|
784ac3 |
+ g_object_ref (self));
|
|
|
784ac3 |
|
|
|
784ac3 |
- g_object_unref (chain);
|
|
|
784ac3 |
+ g_object_unref (cert);
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
gboolean
|
|
|
784ac3 |
@@ -567,6 +527,21 @@ empathy_tls_verifier_verify_finish (EmpathyTLSVerifier *self,
|
|
|
784ac3 |
return TRUE;
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
+void empathy_tls_verifier_set_database (EmpathyTLSVerifier *self,
|
|
|
784ac3 |
+ GTlsDatabase *database)
|
|
|
784ac3 |
+{
|
|
|
784ac3 |
+ EmpathyTLSVerifierPriv *priv = GET_PRIV (self);
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ g_return_if_fail (EMPATHY_IS_TLS_VERIFIER (self));
|
|
|
784ac3 |
+ g_return_if_fail (G_IS_TLS_DATABASE (database));
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ if (database == priv->database)
|
|
|
784ac3 |
+ return;
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ g_clear_object (&priv->database);
|
|
|
784ac3 |
+ priv->database = g_object_ref (database);
|
|
|
784ac3 |
+}
|
|
|
784ac3 |
+
|
|
|
784ac3 |
void
|
|
|
784ac3 |
empathy_tls_verifier_store_exception (EmpathyTLSVerifier *self)
|
|
|
784ac3 |
{
|
|
|
784ac3 |
diff --git a/libempathy/empathy-tls-verifier.h b/libempathy/empathy-tls-verifier.h
|
|
|
784ac3 |
index c25d9756cb02..f9bf54a612f2 100644
|
|
|
784ac3 |
--- a/libempathy/empathy-tls-verifier.h
|
|
|
784ac3 |
+++ b/libempathy/empathy-tls-verifier.h
|
|
|
784ac3 |
@@ -72,6 +72,9 @@ gboolean empathy_tls_verifier_verify_finish (EmpathyTLSVerifier *self,
|
|
|
784ac3 |
GHashTable **details,
|
|
|
784ac3 |
GError **error);
|
|
|
784ac3 |
|
|
|
784ac3 |
+void empathy_tls_verifier_set_database (EmpathyTLSVerifier *self,
|
|
|
784ac3 |
+ GTlsDatabase *database);
|
|
|
784ac3 |
+
|
|
|
784ac3 |
void empathy_tls_verifier_store_exception (EmpathyTLSVerifier *self);
|
|
|
784ac3 |
|
|
|
784ac3 |
G_END_DECLS
|
|
|
784ac3 |
diff --git a/tests/empathy-tls-test.c b/tests/empathy-tls-test.c
|
|
|
784ac3 |
index 422909e7cc2a..b8f9ffcbb9af 100644
|
|
|
784ac3 |
--- a/tests/empathy-tls-test.c
|
|
|
784ac3 |
+++ b/tests/empathy-tls-test.c
|
|
|
784ac3 |
@@ -270,6 +270,7 @@ mock_tls_certificate_new_and_register (TpDBusDaemon *dbus,
|
|
|
784ac3 |
|
|
|
784ac3 |
typedef struct {
|
|
|
784ac3 |
GMainLoop *loop;
|
|
|
784ac3 |
+ GTlsDatabase *database;
|
|
|
784ac3 |
TpDBusDaemon *dbus;
|
|
|
784ac3 |
const gchar *dbus_name;
|
|
|
784ac3 |
MockTLSCertificate *mock;
|
|
|
784ac3 |
@@ -283,9 +284,18 @@ setup (Test *test, gconstpointer data)
|
|
|
784ac3 |
GError *error = NULL;
|
|
|
784ac3 |
GckModule *module;
|
|
|
784ac3 |
const gchar *trust_uris[2] = { MOCK_SLOT_ONE_URI, NULL };
|
|
|
784ac3 |
+ gchar *path = NULL;
|
|
|
784ac3 |
|
|
|
784ac3 |
test->loop = g_main_loop_new (NULL, FALSE);
|
|
|
784ac3 |
|
|
|
784ac3 |
+ path = g_build_filename (g_getenv ("EMPATHY_SRCDIR"),
|
|
|
784ac3 |
+ "tests",
|
|
|
784ac3 |
+ "certificates",
|
|
|
784ac3 |
+ "certificate-authority.pem",
|
|
|
784ac3 |
+ NULL);
|
|
|
784ac3 |
+ test->database = g_tls_file_database_new (path, &error);
|
|
|
784ac3 |
+ g_assert_no_error (error);
|
|
|
784ac3 |
+
|
|
|
784ac3 |
test->dbus = tp_dbus_daemon_dup (&error);
|
|
|
784ac3 |
g_assert_no_error (error);
|
|
|
784ac3 |
|
|
|
784ac3 |
@@ -301,6 +311,8 @@ setup (Test *test, gconstpointer data)
|
|
|
784ac3 |
gcr_pkcs11_set_modules (NULL);
|
|
|
784ac3 |
gcr_pkcs11_add_module (module);
|
|
|
784ac3 |
gcr_pkcs11_set_trust_lookup_uris (trust_uris);
|
|
|
784ac3 |
+
|
|
|
784ac3 |
+ g_free (path);
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
static void
|
|
|
784ac3 |
@@ -325,6 +337,8 @@ teardown (Test *test, gconstpointer data)
|
|
|
784ac3 |
g_object_unref (test->cert);
|
|
|
784ac3 |
test->cert = NULL;
|
|
|
784ac3 |
|
|
|
784ac3 |
+ g_clear_object (&test->database);
|
|
|
784ac3 |
+
|
|
|
784ac3 |
g_main_loop_unref (test->loop);
|
|
|
784ac3 |
test->loop = NULL;
|
|
|
784ac3 |
|
|
|
784ac3 |
@@ -418,6 +432,8 @@ test_certificate_mock_basics (Test *test,
|
|
|
784ac3 |
g_assert (test->mock->state == TP_TLS_CERTIFICATE_STATE_ACCEPTED);
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
+#if 0
|
|
|
784ac3 |
+
|
|
|
784ac3 |
static void
|
|
|
784ac3 |
test_certificate_verify_success_with_pkcs11_lookup (Test *test,
|
|
|
784ac3 |
gconstpointer data G_GNUC_UNUSED)
|
|
|
784ac3 |
@@ -459,6 +475,8 @@ test_certificate_verify_success_with_pkcs11_lookup (Test *test,
|
|
|
784ac3 |
g_object_unref (verifier);
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
+#endif
|
|
|
784ac3 |
+
|
|
|
784ac3 |
static void
|
|
|
784ac3 |
test_certificate_verify_success_with_full_chain (Test *test,
|
|
|
784ac3 |
gconstpointer data G_GNUC_UNUSED)
|
|
|
784ac3 |
@@ -486,6 +504,7 @@ test_certificate_verify_success_with_full_chain (Test *test,
|
|
|
784ac3 |
|
|
|
784ac3 |
verifier = empathy_tls_verifier_new (test->cert, "test-server.empathy.gnome.org",
|
|
|
784ac3 |
reference_identities);
|
|
|
784ac3 |
+ empathy_tls_verifier_set_database (verifier, test->database);
|
|
|
784ac3 |
empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
|
|
|
784ac3 |
g_main_loop_run (test->loop);
|
|
|
784ac3 |
empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
|
|
|
784ac3 |
@@ -525,9 +544,9 @@ test_certificate_verify_root_not_found (Test *test,
|
|
|
784ac3 |
empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
|
|
|
784ac3 |
NULL, &error);
|
|
|
784ac3 |
|
|
|
784ac3 |
- /* And it should say we're self-signed (oddly enough) */
|
|
|
784ac3 |
+ /* And it should say we're untrusted */
|
|
|
784ac3 |
g_assert_error (error, G_IO_ERROR,
|
|
|
784ac3 |
- TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED);
|
|
|
784ac3 |
+ TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED);
|
|
|
784ac3 |
|
|
|
784ac3 |
g_clear_error (&error);
|
|
|
784ac3 |
g_object_unref (verifier);
|
|
|
784ac3 |
@@ -560,9 +579,9 @@ test_certificate_verify_root_not_anchored (Test *test,
|
|
|
784ac3 |
empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
|
|
|
784ac3 |
NULL, &error);
|
|
|
784ac3 |
|
|
|
784ac3 |
- /* And it should say we're self-signed (oddly enough) */
|
|
|
784ac3 |
+ /* And it should say we're untrusted */
|
|
|
784ac3 |
g_assert_error (error, G_IO_ERROR,
|
|
|
784ac3 |
- TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED);
|
|
|
784ac3 |
+ TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED);
|
|
|
784ac3 |
|
|
|
784ac3 |
g_clear_error (&error);
|
|
|
784ac3 |
g_object_unref (verifier);
|
|
|
784ac3 |
@@ -590,6 +609,7 @@ test_certificate_verify_identities_invalid (Test *test,
|
|
|
784ac3 |
|
|
|
784ac3 |
verifier = empathy_tls_verifier_new (test->cert, "invalid.host.name",
|
|
|
784ac3 |
reference_identities);
|
|
|
784ac3 |
+ empathy_tls_verifier_set_database (verifier, test->database);
|
|
|
784ac3 |
empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
|
|
|
784ac3 |
g_main_loop_run (test->loop);
|
|
|
784ac3 |
|
|
|
784ac3 |
@@ -627,6 +647,7 @@ test_certificate_verify_uses_reference_identities (Test *test,
|
|
|
784ac3 |
/* Should be using the reference_identities and not host name for checks */
|
|
|
784ac3 |
verifier = empathy_tls_verifier_new (test->cert, "test-server.empathy.gnome.org",
|
|
|
784ac3 |
reference_identities);
|
|
|
784ac3 |
+ empathy_tls_verifier_set_database (verifier, test->database);
|
|
|
784ac3 |
empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
|
|
|
784ac3 |
g_main_loop_run (test->loop);
|
|
|
784ac3 |
|
|
|
784ac3 |
@@ -708,9 +729,9 @@ test_certificate_verify_pinned_wrong_host (Test *test,
|
|
|
784ac3 |
empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
|
|
|
784ac3 |
NULL, &error);
|
|
|
784ac3 |
|
|
|
784ac3 |
- /* And it should say we're self-signed */
|
|
|
784ac3 |
+ /* And it should say we're untrusted */
|
|
|
784ac3 |
g_assert_error (error, G_IO_ERROR,
|
|
|
784ac3 |
- TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED);
|
|
|
784ac3 |
+ TP_TLS_CERTIFICATE_REJECT_REASON_UNTRUSTED);
|
|
|
784ac3 |
|
|
|
784ac3 |
g_clear_error (&error);
|
|
|
784ac3 |
g_object_unref (verifier);
|
|
|
784ac3 |
@@ -727,8 +748,10 @@ main (int argc,
|
|
|
784ac3 |
|
|
|
784ac3 |
g_test_add ("/tls/certificate_basics", Test, NULL,
|
|
|
784ac3 |
setup, test_certificate_mock_basics, teardown);
|
|
|
784ac3 |
+#if 0
|
|
|
784ac3 |
g_test_add ("/tls/certificate_verify_success_with_pkcs11_lookup", Test, NULL,
|
|
|
784ac3 |
setup, test_certificate_verify_success_with_pkcs11_lookup, teardown);
|
|
|
784ac3 |
+#endif
|
|
|
784ac3 |
g_test_add ("/tls/certificate_verify_success_with_full_chain", Test, NULL,
|
|
|
784ac3 |
setup, test_certificate_verify_success_with_full_chain, teardown);
|
|
|
784ac3 |
g_test_add ("/tls/certificate_verify_root_not_found", Test, NULL,
|
|
|
784ac3 |
--
|
|
|
784ac3 |
2.14.4
|
|
|
784ac3 |
|
|
|
784ac3 |
|
|
|
784ac3 |
From a5ef984c6219070253f382d41101de9f904563c6 Mon Sep 17 00:00:00 2001
|
|
|
784ac3 |
From: Debarshi Ray <debarshir@gnome.org>
|
|
|
784ac3 |
Date: Thu, 16 Mar 2017 19:50:40 +0100
|
|
|
784ac3 |
Subject: [PATCH 5/5] Remove the GnuTLS dependency
|
|
|
784ac3 |
|
|
|
784ac3 |
GIO, backed by glib-networking, has everything that we need.
|
|
|
784ac3 |
|
|
|
784ac3 |
https://bugzilla.gnome.org/show_bug.cgi?id=780160
|
|
|
784ac3 |
---
|
|
|
784ac3 |
configure.ac | 2 --
|
|
|
784ac3 |
libempathy/empathy-utils.c | 35 -----------------------------------
|
|
|
784ac3 |
libempathy/empathy-utils.h | 3 ---
|
|
|
784ac3 |
src/empathy-auth-client.c | 2 --
|
|
|
784ac3 |
tests/empathy-tls-test.c | 2 --
|
|
|
784ac3 |
5 files changed, 44 deletions(-)
|
|
|
784ac3 |
|
|
|
784ac3 |
diff --git a/configure.ac b/configure.ac
|
|
|
784ac3 |
index cd6f371de799..a1cd48687e27 100644
|
|
|
784ac3 |
--- a/configure.ac
|
|
|
784ac3 |
+++ b/configure.ac
|
|
|
784ac3 |
@@ -35,7 +35,6 @@ AC_COPYRIGHT([
|
|
|
784ac3 |
|
|
|
784ac3 |
# Hardp deps
|
|
|
784ac3 |
FOLKS_REQUIRED=0.9.5
|
|
|
784ac3 |
-GNUTLS_REQUIRED=2.8.5
|
|
|
784ac3 |
|
|
|
784ac3 |
GLIB_REQUIRED=2.48.0
|
|
|
784ac3 |
AC_DEFINE(GLIB_VERSION_MIN_REQUIRED, GLIB_VERSION_2_48, [Ignore post 2.48 deprecations])
|
|
|
784ac3 |
@@ -219,7 +218,6 @@ PKG_CHECK_MODULES(EMPATHY,
|
|
|
784ac3 |
gio-2.0 >= $GLIB_REQUIRED
|
|
|
784ac3 |
gio-unix-2.0 >= $GLIB_REQUIRED
|
|
|
784ac3 |
libsecret-1 >= $LIBSECRET_REQUIRED
|
|
|
784ac3 |
- gnutls >= $GNUTLS_REQUIRED
|
|
|
784ac3 |
gmodule-export-2.0
|
|
|
784ac3 |
gobject-2.0
|
|
|
784ac3 |
gsettings-desktop-schemas
|
|
|
784ac3 |
diff --git a/libempathy/empathy-utils.c b/libempathy/empathy-utils.c
|
|
|
784ac3 |
index e8349373639f..88e28b8dd92b 100644
|
|
|
784ac3 |
--- a/libempathy/empathy-utils.c
|
|
|
784ac3 |
+++ b/libempathy/empathy-utils.c
|
|
|
784ac3 |
@@ -20,10 +20,6 @@
|
|
|
784ac3 |
* Authors: Richard Hult <richard@imendio.com>
|
|
|
784ac3 |
* Martyn Russell <martyn@imendio.com>
|
|
|
784ac3 |
* Xavier Claessens <xclaesse@gmail.com>
|
|
|
784ac3 |
- *
|
|
|
784ac3 |
- * Some snippets are taken from GnuTLS 2.8.6, which is distributed under the
|
|
|
784ac3 |
- * same GNU Lesser General Public License 2.1 (or later) version. See
|
|
|
784ac3 |
- * empathy_get_x509_certified_hostname ().
|
|
|
784ac3 |
*/
|
|
|
784ac3 |
|
|
|
784ac3 |
#include "config.h"
|
|
|
784ac3 |
@@ -648,37 +644,6 @@ empathy_folks_persona_is_interesting (FolksPersona *persona)
|
|
|
784ac3 |
return TRUE;
|
|
|
784ac3 |
}
|
|
|
784ac3 |
|
|
|
784ac3 |
-gchar *
|
|
|
784ac3 |
-empathy_get_x509_certificate_hostname (gnutls_x509_crt_t cert)
|
|
|
784ac3 |
-{
|
|
|
784ac3 |
- gchar dns_name[256];
|
|
|
784ac3 |
- gsize dns_name_size;
|
|
|
784ac3 |
- gint idx;
|
|
|
784ac3 |
- gint res = 0;
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- /* this snippet is taken from GnuTLS.
|
|
|
784ac3 |
- * see gnutls/lib/x509/rfc2818_hostname.c
|
|
|
784ac3 |
- */
|
|
|
784ac3 |
- for (idx = 0; res >= 0; idx++)
|
|
|
784ac3 |
- {
|
|
|
784ac3 |
- dns_name_size = sizeof (dns_name);
|
|
|
784ac3 |
- res = gnutls_x509_crt_get_subject_alt_name (cert, idx,
|
|
|
784ac3 |
- dns_name, &dns_name_size, NULL);
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- if (res == GNUTLS_SAN_DNSNAME || res == GNUTLS_SAN_IPADDRESS)
|
|
|
784ac3 |
- return g_strndup (dns_name, dns_name_size);
|
|
|
784ac3 |
- }
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- dns_name_size = sizeof (dns_name);
|
|
|
784ac3 |
- res = gnutls_x509_crt_get_dn_by_oid (cert, GNUTLS_OID_X520_COMMON_NAME,
|
|
|
784ac3 |
- 0, 0, dns_name, &dns_name_size);
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- if (res >= 0)
|
|
|
784ac3 |
- return g_strndup (dns_name, dns_name_size);
|
|
|
784ac3 |
-
|
|
|
784ac3 |
- return NULL;
|
|
|
784ac3 |
-}
|
|
|
784ac3 |
-
|
|
|
784ac3 |
gchar *
|
|
|
784ac3 |
empathy_format_currency (gint amount,
|
|
|
784ac3 |
guint scale,
|
|
|
784ac3 |
diff --git a/libempathy/empathy-utils.h b/libempathy/empathy-utils.h
|
|
|
784ac3 |
index a9ff0d89060d..deb3ae87b7aa 100644
|
|
|
784ac3 |
--- a/libempathy/empathy-utils.h
|
|
|
784ac3 |
+++ b/libempathy/empathy-utils.h
|
|
|
784ac3 |
@@ -27,7 +27,6 @@
|
|
|
784ac3 |
|
|
|
784ac3 |
#include <glib.h>
|
|
|
784ac3 |
#include <glib-object.h>
|
|
|
784ac3 |
-#include <gnutls/x509.h>
|
|
|
784ac3 |
#include <libxml/tree.h>
|
|
|
784ac3 |
#include <folks/folks.h>
|
|
|
784ac3 |
#include <folks/folks-telepathy.h>
|
|
|
784ac3 |
@@ -85,8 +84,6 @@ gboolean empathy_connection_can_group_personas (TpConnection *connection,
|
|
|
784ac3 |
FolksIndividual *individual);
|
|
|
784ac3 |
gboolean empathy_folks_persona_is_interesting (FolksPersona *persona);
|
|
|
784ac3 |
|
|
|
784ac3 |
-gchar * empathy_get_x509_certificate_hostname (gnutls_x509_crt_t cert);
|
|
|
784ac3 |
-
|
|
|
784ac3 |
gchar *empathy_format_currency (gint amount,
|
|
|
784ac3 |
guint scale,
|
|
|
784ac3 |
const gchar *currency);
|
|
|
784ac3 |
diff --git a/src/empathy-auth-client.c b/src/empathy-auth-client.c
|
|
|
784ac3 |
index 3ee478d3e29c..6b6482d4b23d 100644
|
|
|
784ac3 |
--- a/src/empathy-auth-client.c
|
|
|
784ac3 |
+++ b/src/empathy-auth-client.c
|
|
|
784ac3 |
@@ -22,7 +22,6 @@
|
|
|
784ac3 |
#include "config.h"
|
|
|
784ac3 |
|
|
|
784ac3 |
#include <glib/gi18n.h>
|
|
|
784ac3 |
-#include <gnutls/gnutls.h>
|
|
|
784ac3 |
|
|
|
784ac3 |
#include "empathy-auth-factory.h"
|
|
|
784ac3 |
#include "empathy-bad-password-dialog.h"
|
|
|
784ac3 |
@@ -297,7 +296,6 @@ main (int argc,
|
|
|
784ac3 |
g_option_context_free (context);
|
|
|
784ac3 |
|
|
|
784ac3 |
empathy_gtk_init ();
|
|
|
784ac3 |
- gnutls_global_init ();
|
|
|
784ac3 |
g_set_application_name (_("Empathy authentication client"));
|
|
|
784ac3 |
|
|
|
784ac3 |
/* Make empathy and empathy-auth-client appear as the same app in
|
|
|
784ac3 |
diff --git a/tests/empathy-tls-test.c b/tests/empathy-tls-test.c
|
|
|
784ac3 |
index b8f9ffcbb9af..9b62ae4e0ec7 100644
|
|
|
784ac3 |
--- a/tests/empathy-tls-test.c
|
|
|
784ac3 |
+++ b/tests/empathy-tls-test.c
|
|
|
784ac3 |
@@ -1,6 +1,5 @@
|
|
|
784ac3 |
#include "config.h"
|
|
|
784ac3 |
|
|
|
784ac3 |
-#include <gnutls/gnutls.h>
|
|
|
784ac3 |
#include <telepathy-glib/telepathy-glib.h>
|
|
|
784ac3 |
#include <telepathy-glib/telepathy-glib-dbus.h>
|
|
|
784ac3 |
|
|
|
784ac3 |
@@ -744,7 +743,6 @@ main (int argc,
|
|
|
784ac3 |
int result;
|
|
|
784ac3 |
|
|
|
784ac3 |
test_init (argc, argv);
|
|
|
784ac3 |
- gnutls_global_init ();
|
|
|
784ac3 |
|
|
|
784ac3 |
g_test_add ("/tls/certificate_basics", Test, NULL,
|
|
|
784ac3 |
setup, test_certificate_mock_basics, teardown);
|
|
|
784ac3 |
--
|
|
|
784ac3 |
2.14.4
|
|
|
784ac3 |
|