-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <libempathy/empathy-tls-certificate.h>
-#include <libempathy/empathy-tls-verifier.h>
-#include "test-helper.h"
-
-#include <gcr/gcr.h>
+#include "config.h"
#include <gnutls/gnutls.h>
-
-#include <telepathy-glib/dbus-properties-mixin.h>
-#include <telepathy-glib/enums.h>
-#include <telepathy-glib/interfaces.h>
-#include <telepathy-glib/svc-tls.h>
-#include <telepathy-glib/svc-generic.h>
#include <telepathy-glib/telepathy-glib.h>
+#include <telepathy-glib/telepathy-glib-dbus.h>
+
+#include "empathy-tls-verifier.h"
+#include "mock-pkcs11.h"
+#include "test-helper.h"
#define MOCK_TLS_CERTIFICATE_PATH "/mock/certificate"
{
self->state = TP_TLS_CERTIFICATE_STATE_PENDING;
self->cert_type = g_strdup ("x509");
- self->cert_data = g_ptr_array_new_with_free_func((GDestroyNotify) g_array_unref);
+ self->cert_data = g_ptr_array_new_with_free_func ((GDestroyNotify)
+ g_array_unref);
self->rejections = g_ptr_array_new ();
}
pspec = g_param_spec_uint ("state",
"State of this certificate",
"The state of this TLS certificate.",
- 0, NUM_TP_TLS_CERTIFICATE_STATES - 1,
+ 0, TP_NUM_TLS_CERTIFICATE_STATES - 1,
TP_TLS_CERTIFICATE_STATE_PENDING,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_property (oclass, PROP_STATE, pspec);
gpointer iface_data)
{
TpSvcAuthenticationTLSCertificateClass *klass =
- (TpSvcAuthenticationTLSCertificateClass*)g_iface;
+ (TpSvcAuthenticationTLSCertificateClass *) g_iface;
tp_svc_authentication_tls_certificate_implement_accept (klass,
mock_tls_certificate_accept);
#if 0
static void
mock_tls_certificate_assert_rejected (MockTLSCertificate *self,
- EmpTLSCertificateRejectReason reason)
+ TpTLSCertificateRejectReason reason)
{
GValueArray *rejection;
- EmpTLSCertificateRejectReason rejection_reason;
+ TpTLSCertificateRejectReason rejection_reason;
gchar *rejection_error;
GHashTable *rejection_details;
guint i;
}
#endif
-static MockTLSCertificate*
+static MockTLSCertificate *
mock_tls_certificate_new_and_register (TpDBusDaemon *dbus,
const gchar *path,
...)
TpDBusDaemon *dbus;
const gchar *dbus_name;
MockTLSCertificate *mock;
- EmpathyTLSCertificate *cert;
+ TpTLSCertificate *cert;
GAsyncResult *result;
} Test;
setup (Test *test, gconstpointer data)
{
GError *error = NULL;
+ GckModule *module;
+ const gchar *trust_uris[2] = { MOCK_SLOT_ONE_URI, NULL };
+
test->loop = g_main_loop_new (NULL, FALSE);
test->dbus = tp_dbus_daemon_dup (&error);
test->result = NULL;
test->cert = NULL;
- /* No PKCS#11 modules by default, tests add them */
+ /* Add our mock module as the only PKCS#11 module */
+ module = gck_module_new (&mock_default_functions);
+ mock_C_Initialize (NULL);
+
gcr_pkcs11_set_modules (NULL);
+ gcr_pkcs11_add_module (module);
+ gcr_pkcs11_set_trust_lookup_uris (trust_uris);
}
static void
teardown (Test *test, gconstpointer data)
{
+ mock_C_Finalize (NULL);
+
test->dbus_name = NULL;
if (test->mock)
}
static void
-add_pkcs11_module_for_testing (Test *test,
- const gchar *filename,
- const gchar *subdir)
+add_certificate_to_mock (Test *test,
+ const gchar *certificate,
+ const gchar *peer)
{
GError *error = NULL;
- gchar *args, *path, *directory;
- gchar *standalone, *error_output;
- gint exit_status;
+ GcrCertificate *cert;
+ gchar *contents;
+ gsize length;
+ gchar *path;
- directory = g_build_filename (g_getenv ("EMPATHY_SRCDIR"),
- "tests", "certificates", subdir, NULL);
+ path = g_build_filename (g_getenv ("EMPATHY_SRCDIR"),
+ "tests", "certificates", certificate, NULL);
- /*
- * Lookup the directory for standalone pkcs11 modules installed by
- * gnome-keyring. We use these for testing our implementation.
- */
- g_spawn_command_line_sync ("pkg-config --variable=pkcs11standalonedir gcr-3",
- &standalone, &error_output, &exit_status, &error);
+ g_file_get_contents (path, &contents, &length, &error);
g_assert_no_error (error);
- if (exit_status != 0)
- {
- g_warning ("couldn't determine standalone pkcs11 module directory: %d: %s",
- exit_status, error_output);
- g_assert_not_reached ();
- }
- g_strstrip (standalone);
- args = g_strdup_printf ("directory=\"%s\"", directory);
- path = g_build_filename (standalone, filename, NULL);
- gcr_pkcs11_add_module_from_file (path, args, &error);
- g_assert_no_error (error);
+ cert = gcr_simple_certificate_new ((const guchar *)contents, length);
+ mock_module_add_certificate (cert);
+ mock_module_add_assertion (cert,
+ peer ? CKT_X_PINNED_CERTIFICATE : CKT_X_ANCHORED_CERTIFICATE,
+ GCR_PURPOSE_SERVER_AUTH, peer);
+ g_object_unref (cert);
- g_free (directory);
- g_free (standalone);
- g_free (error_output);
- g_free (args);
+ g_free (contents);
g_free (path);
}
ensure_certificate_proxy (Test *test)
{
GError *error = NULL;
+ GQuark features[] = { TP_TLS_CERTIFICATE_FEATURE_CORE, 0 };
if (test->cert)
return;
/* Create and prepare a certificate */
- test->cert = empathy_tls_certificate_new (test->dbus, test->dbus_name,
- MOCK_TLS_CERTIFICATE_PATH, &error);
- g_assert_no_error (error);
- empathy_tls_certificate_prepare_async (test->cert, fetch_callback_result, test);
+ /* We don't use tp_tls_certificate_new() as we don't pass a parent */
+ test->cert = g_object_new (TP_TYPE_TLS_CERTIFICATE,
+ "dbus-daemon", test->dbus,
+ "bus-name", test->dbus_name,
+ "object-path", MOCK_TLS_CERTIFICATE_PATH,
+ NULL);
+
+ tp_proxy_prepare_async (test->cert, features, fetch_callback_result, test);
g_main_loop_run (test->loop);
- empathy_tls_certificate_prepare_finish (test->cert, test->result, &error);
+ tp_proxy_prepare_finish (test->cert, test->result, &error);
g_assert_no_error (error);
/* Clear for any future async stuff */
GError *error = NULL;
test->mock = mock_tls_certificate_new_and_register (test->dbus,
- "dhansak-collabora.cer", NULL);
+ "server-cert.cer", NULL);
ensure_certificate_proxy (test);
- empathy_tls_certificate_accept_async (test->cert, fetch_callback_result, test);
+ tp_tls_certificate_accept_async (test->cert, fetch_callback_result, test);
g_main_loop_run (test->loop);
- empathy_tls_certificate_accept_finish (test->cert, test->result, &error);
+ tp_tls_certificate_accept_finish (test->cert, test->result, &error);
g_assert_no_error (error);
g_assert (test->mock->state == TP_TLS_CERTIFICATE_STATE_ACCEPTED);
test_certificate_verify_success_with_pkcs11_lookup (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
- EmpTLSCertificateRejectReason reason = 0;
+ TpTLSCertificateRejectReason reason = 0;
GError *error = NULL;
EmpathyTLSVerifier *verifier;
const gchar *reference_identities[] = {
- "www.collabora.co.uk",
+ "test-server.empathy.gnome.org",
NULL
};
*/
test->mock = mock_tls_certificate_new_and_register (test->dbus,
- "dhansak-collabora.cer", NULL);
+ "server-cert.cer", NULL);
/* We add the collabora directory with the collabora root */
- add_pkcs11_module_for_testing (test, "gkm-roots-store-standalone.so",
- "collabora-ca");
+ add_certificate_to_mock (test, "certificate-authority.cer", NULL);
ensure_certificate_proxy (test);
- verifier = empathy_tls_verifier_new (test->cert, "www.collabora.co.uk",
+ verifier = empathy_tls_verifier_new (test->cert, "test-server.empathy.gnome.org",
reference_identities);
empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
g_main_loop_run (test->loop);
- if (!empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
- NULL, &error))
- g_assert_not_reached ();
+
+ empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
+ NULL, &error);
+ g_assert_no_error (error);
/* Yay the verification was a success! */
test_certificate_verify_success_with_full_chain (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
- EmpTLSCertificateRejectReason reason = 0;
+ TpTLSCertificateRejectReason reason = 0;
GError *error = NULL;
EmpathyTLSVerifier *verifier;
const gchar *reference_identities[] = {
- "www.collabora.co.uk",
+ "test-server.empathy.gnome.org",
NULL
};
*/
test->mock = mock_tls_certificate_new_and_register (test->dbus,
- "dhansak-collabora.cer", "collabora-ca/collabora-ca.cer", NULL);
+ "server-cert.cer", "certificate-authority.cer", NULL);
/* We add the collabora directory with the collabora root */
- add_pkcs11_module_for_testing (test, "gkm-roots-store-standalone.so",
- "collabora-ca");
+ add_certificate_to_mock (test, "certificate-authority.cer", NULL);
ensure_certificate_proxy (test);
- verifier = empathy_tls_verifier_new (test->cert, "www.collabora.co.uk",
+ verifier = empathy_tls_verifier_new (test->cert, "test-server.empathy.gnome.org",
reference_identities);
empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
g_main_loop_run (test->loop);
- if (!empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
- NULL, &error))
- g_assert_not_reached ();
+ empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
+ NULL, &error);
+ g_assert_no_error (error);
/* Yay the verification was a success! */
test_certificate_verify_root_not_found (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
- EmpTLSCertificateRejectReason reason = 0;
+ TpTLSCertificateRejectReason reason = 0;
GError *error = NULL;
EmpathyTLSVerifier *verifier;
const gchar *reference_identities[] = {
- "www.collabora.co.uk",
+ "test-server.empathy.gnome.org",
NULL
};
test->mock = mock_tls_certificate_new_and_register (test->dbus,
- "dhansak-collabora.cer", NULL);
+ "server-cert.cer", NULL);
/* Note that we're not adding any place to find root certs */
ensure_certificate_proxy (test);
- verifier = empathy_tls_verifier_new (test->cert, "www.collabora.co.uk",
+ verifier = empathy_tls_verifier_new (test->cert, "test-server.empathy.gnome.org",
reference_identities);
empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
g_main_loop_run (test->loop);
- if (empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
- NULL, &error))
- g_assert_not_reached ();
+ empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
+ NULL, &error);
/* And it should say we're self-signed (oddly enough) */
- g_assert_cmpuint (reason, ==, EMP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED);
+ g_assert_error (error, G_IO_ERROR,
+ TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED);
g_clear_error (&error);
g_object_unref (verifier);
test_certificate_verify_root_not_anchored (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
- EmpTLSCertificateRejectReason reason = 0;
+ TpTLSCertificateRejectReason reason = 0;
GError *error = NULL;
EmpathyTLSVerifier *verifier;
const gchar *reference_identities[] = {
- "www.collabora.co.uk",
+ "test-server.empathy.gnome.org",
NULL
};
test->mock = mock_tls_certificate_new_and_register (test->dbus,
- "dhansak-collabora.cer", "collabora-ca/collabora-ca.cer", NULL);
+ "server-cert.cer", "certificate-authority.cer", NULL);
/* Note that we're not adding any place to find root certs */
ensure_certificate_proxy (test);
- verifier = empathy_tls_verifier_new (test->cert, "www.collabora.co.uk",
+ verifier = empathy_tls_verifier_new (test->cert, "test-server.empathy.gnome.org",
reference_identities);
empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
g_main_loop_run (test->loop);
- if (empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
- NULL, &error))
- g_assert_not_reached ();
+ empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
+ NULL, &error);
/* And it should say we're self-signed (oddly enough) */
- g_assert_cmpuint (reason, ==, EMP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED);
+ g_assert_error (error, G_IO_ERROR,
+ TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED);
g_clear_error (&error);
g_object_unref (verifier);
test_certificate_verify_identities_invalid (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
- EmpTLSCertificateRejectReason reason = 0;
+ TpTLSCertificateRejectReason reason = 0;
GError *error = NULL;
EmpathyTLSVerifier *verifier;
const gchar *reference_identities[] = {
};
test->mock = mock_tls_certificate_new_and_register (test->dbus,
- "dhansak-collabora.cer", "collabora-ca/collabora-ca.cer", NULL);
+ "server-cert.cer", "certificate-authority.cer", NULL);
/* We add the collabora directory with the collabora root */
- add_pkcs11_module_for_testing (test, "gkm-roots-store-standalone.so",
- "collabora-ca");
+ add_certificate_to_mock (test, "certificate-authority.cer", NULL);
ensure_certificate_proxy (test);
empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
g_main_loop_run (test->loop);
- if (empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
- NULL, &error))
- g_assert_not_reached ();
+ empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
+ NULL, &error);
/* And it should say we're self-signed (oddly enough) */
- g_assert_cmpuint (reason, ==, EMP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH);
+ g_assert_error (error, G_IO_ERROR,
+ TP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH);
g_clear_error (&error);
g_object_unref (verifier);
test_certificate_verify_uses_reference_identities (Test *test,
gconstpointer data G_GNUC_UNUSED)
{
- EmpTLSCertificateRejectReason reason = 0;
+ TpTLSCertificateRejectReason reason = 0;
GError *error = NULL;
EmpathyTLSVerifier *verifier;
const gchar *reference_identities[] = {
};
test->mock = mock_tls_certificate_new_and_register (test->dbus,
- "dhansak-collabora.cer", "collabora-ca/collabora-ca.cer", NULL);
+ "server-cert.cer", "certificate-authority.cer", NULL);
/* We add the collabora directory with the collabora root */
- add_pkcs11_module_for_testing (test, "gkm-roots-store-standalone.so",
- "collabora-ca");
+ add_certificate_to_mock (test, "certificate-authority.cer", NULL);
ensure_certificate_proxy (test);
/* Should be using the reference_identities and not host name for checks */
- verifier = empathy_tls_verifier_new (test->cert, "www.collabora.co.uk",
+ verifier = empathy_tls_verifier_new (test->cert, "test-server.empathy.gnome.org",
reference_identities);
empathy_tls_verifier_verify_async (verifier, fetch_callback_result, test);
g_main_loop_run (test->loop);
- if (empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
- NULL, &error))
- g_assert_not_reached ();
+ empathy_tls_verifier_verify_finish (verifier, test->result, &reason,
+ NULL, &error);
/* And it should say we're self-signed (oddly enough) */
- g_assert_cmpuint (reason, ==, EMP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH);
+ g_assert_error (error, G_IO_ERROR,
+ TP_TLS_CERTIFICATE_REJECT_REASON_HOSTNAME_MISMATCH);
+
+ g_clear_error (&error);
+ g_object_unref (verifier);
+}
+
+static void
+test_certificate_verify_success_with_pinned (Test *test,
+ gconstpointer data G_GNUC_UNUSED)
+{
+ TpTLSCertificateRejectReason reason = 0;
+ GError *error = NULL;
+ EmpathyTLSVerifier *verifier;
+ const gchar *reference_identities[] = {
+ "test-server.empathy.gnome.org",
+ NULL
+ };
+
+ /*
+ * In this test the mock TLS connection has a full certificate
+ * chain. We look for an anchor certificate in the chain.
+ */
+
+ test->mock = mock_tls_certificate_new_and_register (test->dbus,
+ "server-cert.cer", NULL);
+
+ /* 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);
+
+ verifier = empathy_tls_verifier_new (test->cert, "test-server.empathy.gnome.org",
+ reference_identities);
+ 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,
+ NULL, &error);
+ g_assert_no_error (error);
+
+ /* Yay the verification was a success! */
+
+ g_clear_error (&error);
+ g_object_unref (verifier);
+}
+
+static void
+test_certificate_verify_pinned_wrong_host (Test *test,
+ gconstpointer data G_GNUC_UNUSED)
+{
+ TpTLSCertificateRejectReason reason = 0;
+ GError *error = NULL;
+ EmpathyTLSVerifier *verifier;
+ const gchar *reference_identities[] = {
+ "test-server.empathy.gnome.org",
+ NULL
+ };
+
+ 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 */
+
+ ensure_certificate_proxy (test);
+
+ verifier = empathy_tls_verifier_new (test->cert, "another.gnome.org",
+ reference_identities);
+ 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,
+ NULL, &error);
+
+ /* And it should say we're self-signed */
+ g_assert_error (error, G_IO_ERROR,
+ TP_TLS_CERTIFICATE_REJECT_REASON_SELF_SIGNED);
g_clear_error (&error);
g_object_unref (verifier);
setup, test_certificate_verify_identities_invalid, teardown);
g_test_add ("/tls/certificate_verify_uses_reference_identities", Test, NULL,
setup, test_certificate_verify_uses_reference_identities, teardown);
+ g_test_add ("/tls/certificate_verify_success_with_pinned", Test, NULL,
+ setup, test_certificate_verify_success_with_pinned, teardown);
+ g_test_add ("/tls/certificate_verify_pinned_wrong_host", Test, NULL,
+ setup, test_certificate_verify_pinned_wrong_host, teardown);
result = g_test_run ();
test_deinit ();