Blame gck/test-gck-crypto.c

Packit b00eeb
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
Packit b00eeb
/* test-gck-crypto.c - the GObject PKCS#11 wrapper library
Packit b00eeb
Packit b00eeb
   Copyright (C) 2011 Collabora Ltd.
Packit b00eeb
Packit b00eeb
   The Gnome Keyring Library is free software; you can redistribute it and/or
Packit b00eeb
   modify it under the terms of the GNU Library General Public License as
Packit b00eeb
   published by the Free Software Foundation; either version 2 of the
Packit b00eeb
   License, or (at your option) any later version.
Packit b00eeb
Packit b00eeb
   The Gnome Keyring Library is distributed in the hope that it will be useful,
Packit b00eeb
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit b00eeb
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit b00eeb
   Library General Public License for more details.
Packit b00eeb
Packit b00eeb
   You should have received a copy of the GNU Library General Public
Packit b00eeb
   License along with the Gnome Library; see the file COPYING.LIB.  If not,
Packit b00eeb
   see <http://www.gnu.org/licenses/>.
Packit b00eeb
Packit b00eeb
   Author: Stef Walter <stefw@collabora.co.uk>
Packit b00eeb
*/
Packit b00eeb
Packit b00eeb
#include "config.h"
Packit b00eeb
Packit b00eeb
#include "gck/gck.h"
Packit b00eeb
#include "gck/gck-mock.h"
Packit b00eeb
#include "gck/gck-test.h"
Packit b00eeb
Packit b00eeb
#include "egg/egg-testing.h"
Packit b00eeb
Packit b00eeb
#include <glib.h>
Packit b00eeb
Packit b00eeb
#include <errno.h>
Packit b00eeb
#include <stdlib.h>
Packit b00eeb
#include <stdio.h>
Packit b00eeb
#include <string.h>
Packit b00eeb
Packit b00eeb
typedef struct {
Packit b00eeb
	GckModule *module;
Packit b00eeb
	GckSession *session;
Packit b00eeb
	GckSession *session_with_auth;
Packit b00eeb
} Test;
Packit b00eeb
Packit b00eeb
static gboolean
Packit b00eeb
on_discard_handle_ignore (GckSession *self, CK_OBJECT_HANDLE handle, gpointer unused)
Packit b00eeb
{
Packit b00eeb
	/* Don't close the handle for this session, since it's a duplicate */
Packit b00eeb
	return TRUE;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
setup (Test *test, gconstpointer unused)
Packit b00eeb
{
Packit b00eeb
	GError *err = NULL;
Packit b00eeb
	GList *slots;
Packit b00eeb
	GckSlot *slot;
Packit b00eeb
Packit b00eeb
	/* Successful load */
Packit b00eeb
	test->module = gck_module_initialize (BUILDDIR "/.libs/libmock-test-module.so", NULL, &err;;
Packit b00eeb
	g_assert_no_error (err);
Packit b00eeb
	g_assert (GCK_IS_MODULE (test->module));
Packit b00eeb
	g_object_add_weak_pointer (G_OBJECT (test->module), (gpointer *)&test->module);
Packit b00eeb
Packit b00eeb
	slots = gck_module_get_slots (test->module, TRUE);
Packit b00eeb
	g_assert (slots != NULL);
Packit b00eeb
Packit b00eeb
	test->session = gck_slot_open_session (slots->data, 0, NULL, &err;;
Packit b00eeb
	g_assert_no_error (err);
Packit b00eeb
	g_assert (GCK_IS_SESSION (test->session));
Packit b00eeb
	g_object_add_weak_pointer (G_OBJECT (test->session), (gpointer *)&test->session);
Packit b00eeb
Packit b00eeb
	slot = gck_session_get_slot (test->session);
Packit b00eeb
	g_assert (slot);
Packit b00eeb
Packit b00eeb
	test->session_with_auth = gck_session_from_handle (slot, gck_session_get_handle (test->session), GCK_SESSION_AUTHENTICATE);
Packit b00eeb
	g_signal_connect (test->session_with_auth, "discard-handle", G_CALLBACK (on_discard_handle_ignore), NULL);
Packit b00eeb
	g_assert (test->session_with_auth);
Packit b00eeb
	g_object_add_weak_pointer (G_OBJECT (test->session_with_auth), (gpointer *)&test->session_with_auth);
Packit b00eeb
Packit b00eeb
	g_object_unref (slot);
Packit b00eeb
	gck_list_unref_free (slots);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
teardown (Test *test, gconstpointer unused)
Packit b00eeb
{
Packit b00eeb
	g_object_unref (test->session);
Packit b00eeb
	g_object_unref (test->module);
Packit b00eeb
	g_object_unref (test->session_with_auth);
Packit b00eeb
Packit b00eeb
	g_assert (test->session == NULL);
Packit b00eeb
	g_assert (test->session_with_auth == NULL);
Packit b00eeb
	g_assert (test->module == NULL);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
fetch_async_result (GObject *source, GAsyncResult *result, gpointer user_data)
Packit b00eeb
{
Packit b00eeb
	*((GAsyncResult**)user_data) = result;
Packit b00eeb
	g_object_ref (result);
Packit b00eeb
	egg_test_wait_stop ();
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static GckObject*
Packit b00eeb
find_key (GckSession *session, CK_ATTRIBUTE_TYPE method, CK_MECHANISM_TYPE mech)
Packit b00eeb
{
Packit b00eeb
	GckBuilder builder = GCK_BUILDER_INIT;
Packit b00eeb
	GList *objects, *l;
Packit b00eeb
	GckObject *object = NULL;
Packit b00eeb
	CK_MECHANISM_TYPE_PTR mechs;
Packit b00eeb
	gboolean match;
Packit b00eeb
	gsize n_mechs;
Packit b00eeb
Packit b00eeb
	gck_builder_add_boolean (&builder, method, TRUE);
Packit b00eeb
	objects = gck_session_find_objects (session, gck_builder_end (&builder), NULL, NULL);
Packit b00eeb
	g_assert (objects);
Packit b00eeb
Packit b00eeb
	for (l = objects; l; l = g_list_next (l)) {
Packit b00eeb
		if (mech) {
Packit b00eeb
			mechs = (gulong *)gck_object_get_data (l->data, CKA_ALLOWED_MECHANISMS,
Packit b00eeb
			                                       NULL, &n_mechs, NULL);
Packit b00eeb
			g_assert (mechs);
Packit b00eeb
			g_assert (n_mechs == sizeof (CK_MECHANISM_TYPE));
Packit b00eeb
Packit b00eeb
			/* We know all of them only have one allowed mech */
Packit b00eeb
			match = (*mechs != mech);
Packit b00eeb
			g_free (mechs);
Packit b00eeb
Packit b00eeb
			if (match)
Packit b00eeb
				continue;
Packit b00eeb
		}
Packit b00eeb
		object = l->data;
Packit b00eeb
		g_object_ref (object);
Packit b00eeb
		break;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	gck_list_unref_free (objects);
Packit b00eeb
	return object;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static GckObject*
Packit b00eeb
find_key_with_value (GckSession *session, const gchar *value)
Packit b00eeb
{
Packit b00eeb
	GckBuilder builder = GCK_BUILDER_INIT;
Packit b00eeb
	GList *objects;
Packit b00eeb
	GckObject *object;
Packit b00eeb
Packit b00eeb
	gck_builder_add_string (&builder, CKA_VALUE, value);
Packit b00eeb
	objects = gck_session_find_objects (session, gck_builder_end (&builder), NULL, NULL);
Packit b00eeb
	g_assert (objects);
Packit b00eeb
Packit b00eeb
	object = g_object_ref (objects->data);
Packit b00eeb
	gck_list_unref_free (objects);
Packit b00eeb
	return object;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
check_key_with_value (GckSession *session, GckObject *key, CK_OBJECT_CLASS klass, const gchar *value)
Packit b00eeb
{
Packit b00eeb
	GckAttributes *attrs;
Packit b00eeb
	const GckAttribute *attr;
Packit b00eeb
	gulong check;
Packit b00eeb
Packit b00eeb
	attrs = gck_object_get (key, NULL, NULL, CKA_CLASS, CKA_VALUE, GCK_INVALID);
Packit b00eeb
	g_assert (attrs);
Packit b00eeb
Packit b00eeb
	if (!gck_attributes_find_ulong (attrs, CKA_CLASS, &check))
Packit b00eeb
		g_assert_not_reached ();
Packit b00eeb
	g_assert (check == klass);
Packit b00eeb
Packit b00eeb
	attr = gck_attributes_find (attrs, CKA_VALUE);
Packit b00eeb
	g_assert (attr);
Packit b00eeb
	g_assert (!gck_attribute_is_invalid (attr));
Packit b00eeb
	egg_assert_cmpsize (attr->length, ==, strlen (value));
Packit b00eeb
	g_assert (memcmp (attr->value, value, attr->length) == 0);
Packit b00eeb
Packit b00eeb
	gck_attributes_unref (attrs);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static gboolean
Packit b00eeb
authenticate_object (GckSlot *module, GckObject *object, gchar *label, gchar **password)
Packit b00eeb
{
Packit b00eeb
	g_assert (GCK_IS_MODULE (module));
Packit b00eeb
	g_assert (GCK_IS_OBJECT (object));
Packit b00eeb
	g_assert (password);
Packit b00eeb
	g_assert (!*password);
Packit b00eeb
Packit b00eeb
	*password = g_strdup ("booo");
Packit b00eeb
	return TRUE;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
test_encrypt (Test *test, gconstpointer unused)
Packit b00eeb
{
Packit b00eeb
	GckMechanism mech = { CKM_MOCK_CAPITALIZE, NULL, 0 };
Packit b00eeb
	GError *error = NULL;
Packit b00eeb
	GAsyncResult *result = NULL;
Packit b00eeb
	GckObject *key;
Packit b00eeb
	guchar *output;
Packit b00eeb
	gsize n_output;
Packit b00eeb
Packit b00eeb
	/* Find the right key */
Packit b00eeb
	key = find_key (test->session, CKA_ENCRYPT, CKM_MOCK_CAPITALIZE);
Packit b00eeb
	g_assert (key);
Packit b00eeb
Packit b00eeb
	/* Simple one */
Packit b00eeb
	output = gck_session_encrypt (test->session, key, CKM_MOCK_CAPITALIZE, (const guchar*)"blah blah", 10, &n_output, NULL, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (output);
Packit b00eeb
	g_assert (n_output == 10);
Packit b00eeb
	g_assert_cmpstr ((gchar*)output, ==, "BLAH BLAH");
Packit b00eeb
	g_free (output);
Packit b00eeb
Packit b00eeb
	/* Asynchronous one */
Packit b00eeb
	gck_session_encrypt_async (test->session, key, &mech, (const guchar*)"second chance", 14, NULL, fetch_async_result, &result);
Packit b00eeb
Packit b00eeb
	egg_test_wait_until (500);
Packit b00eeb
	g_assert (result != NULL);
Packit b00eeb
Packit b00eeb
	/* Get the result */
Packit b00eeb
	output = gck_session_encrypt_finish (test->session, result, &n_output, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (output);
Packit b00eeb
	g_assert (n_output == 14);
Packit b00eeb
	g_assert_cmpstr ((gchar*)output, ==, "SECOND CHANCE");
Packit b00eeb
	g_free (output);
Packit b00eeb
Packit b00eeb
	g_object_unref (result);
Packit b00eeb
	g_object_unref (key);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
test_decrypt (Test *test, gconstpointer unused)
Packit b00eeb
{
Packit b00eeb
	GckMechanism mech = { CKM_MOCK_CAPITALIZE, NULL, 0 };
Packit b00eeb
	GError *error = NULL;
Packit b00eeb
	GAsyncResult *result = NULL;
Packit b00eeb
	GckObject *key;
Packit b00eeb
	guchar *output;
Packit b00eeb
	gsize n_output;
Packit b00eeb
Packit b00eeb
	/* Find the right key */
Packit b00eeb
	key = find_key (test->session, CKA_DECRYPT, CKM_MOCK_CAPITALIZE);
Packit b00eeb
	g_assert (key);
Packit b00eeb
Packit b00eeb
	/* Simple one */
Packit b00eeb
	output = gck_session_decrypt (test->session, key, CKM_MOCK_CAPITALIZE, (const guchar*)"FRY???", 7, &n_output, NULL, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (output);
Packit b00eeb
	g_assert (n_output == 7);
Packit b00eeb
	g_assert_cmpstr ((gchar*)output, ==, "fry???");
Packit b00eeb
	g_free (output);
Packit b00eeb
Packit b00eeb
	/* Asynchronous one */
Packit b00eeb
	gck_session_decrypt_async (test->session, key, &mech, (const guchar*)"FAT CHANCE", 11, NULL, fetch_async_result, &result);
Packit b00eeb
Packit b00eeb
	egg_test_wait_until (500);
Packit b00eeb
	g_assert (result != NULL);
Packit b00eeb
Packit b00eeb
	/* Get the result */
Packit b00eeb
	output = gck_session_decrypt_finish (test->session, result, &n_output, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (output);
Packit b00eeb
	g_assert (n_output == 11);
Packit b00eeb
	g_assert_cmpstr ((gchar*)output, ==, "fat chance");
Packit b00eeb
	g_free (output);
Packit b00eeb
Packit b00eeb
	g_object_unref (result);
Packit b00eeb
	g_object_unref (key);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
test_login_context_specific (Test *test, gconstpointer unused)
Packit b00eeb
{
Packit b00eeb
	/* The test module won't let us sign without doing a login, check that */
Packit b00eeb
Packit b00eeb
	GError *error = NULL;
Packit b00eeb
	GckObject *key;
Packit b00eeb
	guchar *output;
Packit b00eeb
	gsize n_output;
Packit b00eeb
Packit b00eeb
	/* Find the right key */
Packit b00eeb
	key = find_key (test->session, CKA_SIGN, CKM_MOCK_PREFIX);
Packit b00eeb
	g_assert (GCK_IS_OBJECT (key));
Packit b00eeb
	g_object_add_weak_pointer (G_OBJECT (key), (gpointer *)&key);
Packit b00eeb
Packit b00eeb
	/* Simple one */
Packit b00eeb
	output = gck_session_sign (test->session, key, CKM_MOCK_PREFIX, (const guchar*)"TV Monster", 11, &n_output, NULL, &error);
Packit b00eeb
	g_assert_error (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN);
Packit b00eeb
	g_assert (output == NULL);
Packit b00eeb
	g_error_free (error);
Packit b00eeb
Packit b00eeb
	g_object_unref (key);
Packit b00eeb
	g_assert (key == NULL);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
test_sign (Test *test, gconstpointer unused)
Packit b00eeb
{
Packit b00eeb
	GckMechanism mech = { CKM_MOCK_PREFIX, (guchar *)"my-prefix:", 10 };
Packit b00eeb
	GError *error = NULL;
Packit b00eeb
	GAsyncResult *result = NULL;
Packit b00eeb
	GckObject *key;
Packit b00eeb
	guchar *output;
Packit b00eeb
	gsize n_output;
Packit b00eeb
Packit b00eeb
	/* Enable auto-login on this test->session, see previous test */
Packit b00eeb
	g_signal_connect (test->module, "authenticate-object", G_CALLBACK (authenticate_object), NULL);
Packit b00eeb
Packit b00eeb
	/* Find the right key */
Packit b00eeb
	key = find_key (test->session_with_auth, CKA_SIGN, CKM_MOCK_PREFIX);
Packit b00eeb
	g_assert (key);
Packit b00eeb
Packit b00eeb
	/* Simple one */
Packit b00eeb
	output = gck_session_sign (test->session_with_auth, key, CKM_MOCK_PREFIX, (const guchar*)"Labarbara", 10, &n_output, NULL, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (output);
Packit b00eeb
	g_assert_cmpuint (n_output, ==, 24);
Packit b00eeb
	g_assert_cmpstr ((gchar*)output, ==, "signed-prefix:Labarbara");
Packit b00eeb
	g_free (output);
Packit b00eeb
Packit b00eeb
	/* Asynchronous one */
Packit b00eeb
	gck_session_sign_async (test->session_with_auth, key, &mech, (const guchar*)"Conrad", 7, NULL, fetch_async_result, &result);
Packit b00eeb
Packit b00eeb
	egg_test_wait_until (500);
Packit b00eeb
	g_assert (result != NULL);
Packit b00eeb
Packit b00eeb
	/* Get the result */
Packit b00eeb
	output = gck_session_sign_finish (test->session_with_auth, result, &n_output, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (output);
Packit b00eeb
	g_assert_cmpuint (n_output, ==, 17);
Packit b00eeb
	g_assert_cmpstr ((gchar*)output, ==, "my-prefix:Conrad");
Packit b00eeb
	g_free (output);
Packit b00eeb
Packit b00eeb
	g_object_unref (result);
Packit b00eeb
	g_object_unref (key);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
test_verify (Test *test, gconstpointer unused)
Packit b00eeb
{
Packit b00eeb
	GckMechanism mech = { CKM_MOCK_PREFIX, (guchar *)"my-prefix:", 10 };
Packit b00eeb
	GError *error = NULL;
Packit b00eeb
	GAsyncResult *result = NULL;
Packit b00eeb
	GckObject *key;
Packit b00eeb
	gboolean ret;
Packit b00eeb
Packit b00eeb
	/* Enable auto-login on this session, shouldn't be needed */
Packit b00eeb
	g_signal_connect (test->module, "authenticate-object", G_CALLBACK (authenticate_object), NULL);
Packit b00eeb
Packit b00eeb
	/* Find the right key */
Packit b00eeb
	key = find_key (test->session, CKA_VERIFY, CKM_MOCK_PREFIX);
Packit b00eeb
	g_assert (GCK_IS_OBJECT (key));
Packit b00eeb
	g_object_add_weak_pointer (G_OBJECT (key), (gpointer *)&key);
Packit b00eeb
Packit b00eeb
	/* Simple one */
Packit b00eeb
	ret = gck_session_verify (test->session, key, CKM_MOCK_PREFIX, (const guchar*)"Labarbara", 10,
Packit b00eeb
	                           (const guchar*)"signed-prefix:Labarbara", 24, NULL, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (ret);
Packit b00eeb
Packit b00eeb
	/* Failure one */
Packit b00eeb
	ret = gck_session_verify_full (test->session, key, &mech, (const guchar*)"Labarbara", 10,
Packit b00eeb
	                                (const guchar*)"my-prefix:Loborboro", 20, NULL, &error);
Packit b00eeb
	g_assert (error != NULL);
Packit b00eeb
	g_assert (!ret);
Packit b00eeb
	g_clear_error (&error);
Packit b00eeb
Packit b00eeb
	/* Asynchronous one */
Packit b00eeb
	gck_session_verify_async (test->session, key, &mech, (const guchar*)"Labarbara", 10,
Packit b00eeb
	                           (const guchar*)"my-prefix:Labarbara", 20, NULL, fetch_async_result, &result);
Packit b00eeb
	egg_test_wait_until (500);
Packit b00eeb
	g_assert (result != NULL);
Packit b00eeb
	ret = gck_session_verify_finish (test->session, result, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (ret);
Packit b00eeb
	g_object_unref (result);
Packit b00eeb
Packit b00eeb
	/* Asynchronous failure */
Packit b00eeb
	result = NULL;
Packit b00eeb
	gck_session_verify_async (test->session, key, &mech, (const guchar*)"Labarbara", 10,
Packit b00eeb
	                           (const guchar*)"my-prefix:Labarxoro", 20, NULL, fetch_async_result, &result);
Packit b00eeb
	egg_test_wait_until (500);
Packit b00eeb
	g_assert (result != NULL);
Packit b00eeb
	ret = gck_session_verify_finish (test->session, result, &error);
Packit b00eeb
	g_assert (error != NULL);
Packit b00eeb
	g_assert (!ret);
Packit b00eeb
	g_clear_error (&error);
Packit b00eeb
	g_object_unref (result);
Packit b00eeb
Packit b00eeb
	g_object_unref (key);
Packit b00eeb
	g_assert (key == NULL);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
test_generate_key_pair (Test *test, gconstpointer unused)
Packit b00eeb
{
Packit b00eeb
	GckMechanism mech = { CKM_MOCK_GENERATE, (guchar *)"generate", 9 };
Packit b00eeb
	GckBuilder builder = GCK_BUILDER_INIT;
Packit b00eeb
	GckAttributes *pub_attrs, *prv_attrs;
Packit b00eeb
	GError *error = NULL;
Packit b00eeb
	GAsyncResult *result = NULL;
Packit b00eeb
	GckObject *pub_key, *prv_key;
Packit b00eeb
	gboolean ret;
Packit b00eeb
Packit b00eeb
	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PUBLIC_KEY);
Packit b00eeb
	pub_attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
Packit b00eeb
	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PRIVATE_KEY);
Packit b00eeb
	prv_attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
Packit b00eeb
Packit b00eeb
	/* Full One*/
Packit b00eeb
	ret = gck_session_generate_key_pair_full (test->session, &mech, pub_attrs, prv_attrs,
Packit b00eeb
	                                           &pub_key, &prv_key, NULL, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (ret);
Packit b00eeb
	g_object_unref (pub_key);
Packit b00eeb
	g_object_unref (prv_key);
Packit b00eeb
Packit b00eeb
	/* Failure one */
Packit b00eeb
	mech.type = 0;
Packit b00eeb
	pub_key = prv_key = NULL;
Packit b00eeb
	ret = gck_session_generate_key_pair_full (test->session, &mech, pub_attrs, prv_attrs,
Packit b00eeb
	                                           &pub_key, &prv_key, NULL, &error);
Packit b00eeb
	g_assert (error != NULL);
Packit b00eeb
	g_assert (!ret);
Packit b00eeb
	g_clear_error (&error);
Packit b00eeb
	g_assert (pub_key == NULL);
Packit b00eeb
	g_assert (prv_key == NULL);
Packit b00eeb
Packit b00eeb
	/* Asynchronous one */
Packit b00eeb
	mech.type = CKM_MOCK_GENERATE;
Packit b00eeb
	gck_session_generate_key_pair_async (test->session, &mech, pub_attrs, prv_attrs, NULL, fetch_async_result, &result);
Packit b00eeb
	egg_test_wait_until (500);
Packit b00eeb
	g_assert (result != NULL);
Packit b00eeb
	ret = gck_session_generate_key_pair_finish (test->session, result, &pub_key, &prv_key, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (ret);
Packit b00eeb
	g_object_unref (result);
Packit b00eeb
	g_object_unref (pub_key);
Packit b00eeb
	g_object_unref (prv_key);
Packit b00eeb
Packit b00eeb
	/* Asynchronous failure */
Packit b00eeb
	result = NULL;
Packit b00eeb
	mech.type = 0;
Packit b00eeb
	pub_key = prv_key = NULL;
Packit b00eeb
	gck_session_generate_key_pair_async (test->session, &mech, pub_attrs, prv_attrs, NULL, fetch_async_result, &result);
Packit b00eeb
	egg_test_wait_until (500);
Packit b00eeb
	g_assert (result != NULL);
Packit b00eeb
	ret = gck_session_generate_key_pair_finish (test->session, result, &pub_key, &prv_key, &error);
Packit b00eeb
	g_assert (error != NULL);
Packit b00eeb
	g_assert (!ret);
Packit b00eeb
	g_clear_error (&error);
Packit b00eeb
	g_object_unref (result);
Packit b00eeb
	g_assert (pub_key == NULL);
Packit b00eeb
	g_assert (prv_key == NULL);
Packit b00eeb
Packit b00eeb
	gck_attributes_unref (pub_attrs);
Packit b00eeb
	gck_attributes_unref (prv_attrs);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
test_wrap_key (Test *test, gconstpointer unused)
Packit b00eeb
{
Packit b00eeb
	GckMechanism mech = { CKM_MOCK_WRAP, (guchar *)"wrap", 4 };
Packit b00eeb
	GError *error = NULL;
Packit b00eeb
	GAsyncResult *result = NULL;
Packit b00eeb
	GckObject *wrapper, *wrapped;
Packit b00eeb
	gpointer output;
Packit b00eeb
	gsize n_output;
Packit b00eeb
Packit b00eeb
	wrapper = find_key (test->session, CKA_WRAP, 0);
Packit b00eeb
	wrapped = find_key_with_value (test->session, "value");
Packit b00eeb
Packit b00eeb
	/* Simple One */
Packit b00eeb
	output = gck_session_wrap_key (test->session, wrapper, CKM_MOCK_WRAP, wrapped, &n_output, NULL, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (output);
Packit b00eeb
	egg_assert_cmpsize (n_output, ==, 5);
Packit b00eeb
	g_assert (memcmp (output, "value", 5) == 0);
Packit b00eeb
	g_free (output);
Packit b00eeb
Packit b00eeb
	/* Full One*/
Packit b00eeb
	output = gck_session_wrap_key_full (test->session, wrapper, &mech, wrapped, &n_output, NULL, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (output);
Packit b00eeb
	egg_assert_cmpsize (n_output, ==, 5);
Packit b00eeb
	g_assert (memcmp (output, "value", 5) == 0);
Packit b00eeb
	g_free (output);
Packit b00eeb
Packit b00eeb
	/* Failure one */
Packit b00eeb
	mech.type = 0;
Packit b00eeb
	n_output = 0;
Packit b00eeb
	output = gck_session_wrap_key_full (test->session, wrapper, &mech, wrapped, &n_output, NULL, &error);
Packit b00eeb
	g_assert (error != NULL);
Packit b00eeb
	g_assert (!output);
Packit b00eeb
	g_clear_error (&error);
Packit b00eeb
	egg_assert_cmpsize (n_output, ==, 0);
Packit b00eeb
Packit b00eeb
	/* Asynchronous one */
Packit b00eeb
	mech.type = CKM_MOCK_WRAP;
Packit b00eeb
	gck_session_wrap_key_async (test->session, wrapper, &mech, wrapped, NULL, fetch_async_result, &result);
Packit b00eeb
	egg_test_wait_until (500);
Packit b00eeb
	g_assert (result != NULL);
Packit b00eeb
	output = gck_session_wrap_key_finish (test->session, result, &n_output, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (output);
Packit b00eeb
	egg_assert_cmpsize (n_output, ==, 5);
Packit b00eeb
	g_assert (memcmp (output, "value", 5) == 0);
Packit b00eeb
	g_object_unref (result);
Packit b00eeb
	g_free (output);
Packit b00eeb
Packit b00eeb
	/* Asynchronous failure */
Packit b00eeb
	result = NULL;
Packit b00eeb
	mech.type = 0;
Packit b00eeb
	n_output = 0;
Packit b00eeb
	gck_session_wrap_key_async (test->session, wrapper, &mech, wrapped, NULL, fetch_async_result, &result);
Packit b00eeb
	egg_test_wait_until (500);
Packit b00eeb
	g_assert (result != NULL);
Packit b00eeb
	output = gck_session_wrap_key_finish (test->session, result, &n_output, &error);
Packit b00eeb
	g_assert (error != NULL);
Packit b00eeb
	g_assert (!output);
Packit b00eeb
	g_clear_error (&error);
Packit b00eeb
	egg_assert_cmpsize (n_output, ==, 0);
Packit b00eeb
	g_object_unref (result);
Packit b00eeb
Packit b00eeb
	g_object_unref (wrapper);
Packit b00eeb
	g_object_unref (wrapped);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
test_unwrap_key (Test *test, gconstpointer unused)
Packit b00eeb
{
Packit b00eeb
	GckMechanism mech = { CKM_MOCK_WRAP, (guchar *)"wrap", 4 };
Packit b00eeb
	GckBuilder builder = GCK_BUILDER_INIT;
Packit b00eeb
	GError *error = NULL;
Packit b00eeb
	GAsyncResult *result = NULL;
Packit b00eeb
	GckObject *wrapper, *unwrapped;
Packit b00eeb
	GckAttributes *attrs;
Packit b00eeb
Packit b00eeb
	wrapper = find_key (test->session, CKA_UNWRAP, 0);
Packit b00eeb
	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
Packit b00eeb
	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
Packit b00eeb
Packit b00eeb
	/* Full One*/
Packit b00eeb
	unwrapped = gck_session_unwrap_key_full (test->session, wrapper, &mech, (const guchar *)"special", 7, attrs, NULL, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (GCK_IS_OBJECT (unwrapped));
Packit b00eeb
	check_key_with_value (test->session, unwrapped, CKO_SECRET_KEY, "special");
Packit b00eeb
	g_object_unref (unwrapped);
Packit b00eeb
Packit b00eeb
	/* Failure one */
Packit b00eeb
	mech.type = 0;
Packit b00eeb
	unwrapped = gck_session_unwrap_key_full (test->session, wrapper, &mech, (const guchar *)"special", 7, attrs, NULL, &error);
Packit b00eeb
	g_assert (error != NULL);
Packit b00eeb
	g_assert (!unwrapped);
Packit b00eeb
	g_clear_error (&error);
Packit b00eeb
Packit b00eeb
	/* Asynchronous one */
Packit b00eeb
	mech.type = CKM_MOCK_WRAP;
Packit b00eeb
	gck_session_unwrap_key_async (test->session, wrapper, &mech, (const guchar *)"special", 7, attrs, NULL, fetch_async_result, &result);
Packit b00eeb
	egg_test_wait_until (500);
Packit b00eeb
	g_assert (result != NULL);
Packit b00eeb
	unwrapped = gck_session_unwrap_key_finish (test->session, result, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (GCK_IS_OBJECT (unwrapped));
Packit b00eeb
	check_key_with_value (test->session, unwrapped, CKO_SECRET_KEY, "special");
Packit b00eeb
	g_object_unref (unwrapped);
Packit b00eeb
	g_object_unref (result);
Packit b00eeb
Packit b00eeb
	/* Asynchronous failure */
Packit b00eeb
	result = NULL;
Packit b00eeb
	mech.type = 0;
Packit b00eeb
	gck_session_unwrap_key_async (test->session, wrapper, &mech, (const guchar *)"special", 6, attrs, NULL, fetch_async_result, &result);
Packit b00eeb
	egg_test_wait_until (500);
Packit b00eeb
	g_assert (result != NULL);
Packit b00eeb
	unwrapped = gck_session_unwrap_key_finish (test->session, result, &error);
Packit b00eeb
	g_assert (error != NULL);
Packit b00eeb
	g_assert (!unwrapped);
Packit b00eeb
	g_clear_error (&error);
Packit b00eeb
	g_object_unref (result);
Packit b00eeb
Packit b00eeb
	g_object_unref (wrapper);
Packit b00eeb
	gck_attributes_unref (attrs);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
test_derive_key (Test *test, gconstpointer unused)
Packit b00eeb
{
Packit b00eeb
	GckMechanism mech = { CKM_MOCK_DERIVE, (guchar *)"derive", 6 };
Packit b00eeb
	GckBuilder builder = GCK_BUILDER_INIT;
Packit b00eeb
	GError *error = NULL;
Packit b00eeb
	GAsyncResult *result = NULL;
Packit b00eeb
	GckObject *wrapper, *derived;
Packit b00eeb
	GckAttributes *attrs;
Packit b00eeb
Packit b00eeb
	wrapper = find_key (test->session, CKA_DERIVE, 0);
Packit b00eeb
	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
Packit b00eeb
	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
Packit b00eeb
Packit b00eeb
	/* Full One*/
Packit b00eeb
	derived = gck_session_derive_key_full (test->session, wrapper, &mech, attrs, NULL, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (GCK_IS_OBJECT (derived));
Packit b00eeb
	check_key_with_value (test->session, derived, CKO_SECRET_KEY, "derived");
Packit b00eeb
	g_object_unref (derived);
Packit b00eeb
Packit b00eeb
	/* Failure one */
Packit b00eeb
	mech.type = 0;
Packit b00eeb
	derived = gck_session_derive_key_full (test->session, wrapper, &mech, attrs, NULL, &error);
Packit b00eeb
	g_assert (error != NULL);
Packit b00eeb
	g_assert (!derived);
Packit b00eeb
	g_clear_error (&error);
Packit b00eeb
Packit b00eeb
	/* Asynchronous one */
Packit b00eeb
	mech.type = CKM_MOCK_DERIVE;
Packit b00eeb
	gck_session_derive_key_async (test->session, wrapper, &mech, attrs, NULL, fetch_async_result, &result);
Packit b00eeb
	egg_test_wait_until (500);
Packit b00eeb
	g_assert (result != NULL);
Packit b00eeb
	derived = gck_session_derive_key_finish (test->session, result, &error);
Packit b00eeb
	g_assert_no_error (error);
Packit b00eeb
	g_assert (GCK_IS_OBJECT (derived));
Packit b00eeb
	check_key_with_value (test->session, derived, CKO_SECRET_KEY, "derived");
Packit b00eeb
	g_object_unref (derived);
Packit b00eeb
	g_object_unref (result);
Packit b00eeb
Packit b00eeb
	/* Asynchronous failure */
Packit b00eeb
	result = NULL;
Packit b00eeb
	mech.type = 0;
Packit b00eeb
	gck_session_derive_key_async (test->session, wrapper, &mech, attrs, NULL, fetch_async_result, &result);
Packit b00eeb
	egg_test_wait_until (500);
Packit b00eeb
	g_assert (result != NULL);
Packit b00eeb
	derived = gck_session_derive_key_finish (test->session, result, &error);
Packit b00eeb
	g_assert (error != NULL);
Packit b00eeb
	g_assert (!derived);
Packit b00eeb
	g_clear_error (&error);
Packit b00eeb
	g_object_unref (result);
Packit b00eeb
Packit b00eeb
	g_object_unref (wrapper);
Packit b00eeb
	gck_attributes_unref (attrs);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
null_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
Packit b00eeb
                  const gchar *message, gpointer user_data)
Packit b00eeb
{
Packit b00eeb
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
int
Packit b00eeb
main (int argc, char **argv)
Packit b00eeb
{
Packit b00eeb
	g_test_init (&argc, &argv, NULL);
Packit b00eeb
Packit b00eeb
	g_set_prgname ("test-gck-crypto");
Packit b00eeb
Packit b00eeb
	/* Suppress these messages in tests */
Packit b00eeb
	g_log_set_handler (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG,
Packit b00eeb
	                   null_log_handler, NULL);
Packit b00eeb
Packit b00eeb
	g_test_add ("/gck/crypto/encrypt", Test, NULL, setup, test_encrypt, teardown);
Packit b00eeb
	g_test_add ("/gck/crypto/decrypt", Test, NULL, setup, test_decrypt, teardown);
Packit b00eeb
	g_test_add ("/gck/crypto/login_context_specific", Test, NULL, setup, test_login_context_specific, teardown);
Packit b00eeb
	g_test_add ("/gck/crypto/sign", Test, NULL, setup, test_sign, teardown);
Packit b00eeb
	g_test_add ("/gck/crypto/verify", Test, NULL, setup, test_verify, teardown);
Packit b00eeb
	g_test_add ("/gck/crypto/generate_key_pair", Test, NULL, setup, test_generate_key_pair, teardown);
Packit b00eeb
	g_test_add ("/gck/crypto/wrap_key", Test, NULL, setup, test_wrap_key, teardown);
Packit b00eeb
	g_test_add ("/gck/crypto/unwrap_key", Test, NULL, setup, test_unwrap_key, teardown);
Packit b00eeb
	g_test_add ("/gck/crypto/derive_key", Test, NULL, setup, test_derive_key, teardown);
Packit b00eeb
Packit b00eeb
	return egg_tests_run_with_loop ();
Packit b00eeb
}