gnome-keyring r1619 - in trunk: . pkcs11 pkcs11/user-store
- From: nnielsen svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-keyring r1619 - in trunk: . pkcs11 pkcs11/user-store
- Date: Thu, 26 Feb 2009 05:40:44 +0000 (UTC)
Author: nnielsen
Date: Thu Feb 26 05:40:43 2009
New Revision: 1619
URL: http://svn.gnome.org/viewvc/gnome-keyring?rev=1619&view=rev
Log:
Hash objects when storing them in user-store and validate the hashes
when loading them.
Modified:
trunk/ChangeLog
trunk/pkcs11/pkcs11i.h
trunk/pkcs11/user-store/gck-user-storage.c
Modified: trunk/pkcs11/pkcs11i.h
==============================================================================
--- trunk/pkcs11/pkcs11i.h (original)
+++ trunk/pkcs11/pkcs11i.h Thu Feb 26 05:40:43 2009
@@ -66,4 +66,10 @@
#define CK_GNOME_MAX_APP (((CK_ULONG)-1) >> 10)
#define CK_GNOME_MAX_HANDLE (((CK_ULONG)-1) >> 10)
+/* -------------------------------------------------------------------
+ * OBJECT HASH
+ */
+
+#define CK_GNOME_INTERNAL_SHA1 (CKA_GNOME + 1000)
+
#endif /* PKCS11I_H */
Modified: trunk/pkcs11/user-store/gck-user-storage.c
==============================================================================
--- trunk/pkcs11/user-store/gck-user-storage.c (original)
+++ trunk/pkcs11/user-store/gck-user-storage.c Thu Feb 26 05:40:43 2009
@@ -35,6 +35,8 @@
#include "egg/egg-hex.h"
+#include "pkcs11/pkcs11i.h"
+
#include <glib/gstdio.h>
#include <libtasn1.h>
@@ -421,6 +423,56 @@
gck_manager_register_object (self->manager, object);
}
+static gboolean
+check_object_hash (GckUserStorage *self, const gchar *identifier, const guchar *data, gsize n_data)
+{
+ gconstpointer value;
+ GckDataResult res;
+ gboolean result;
+ gsize n_value;
+ gchar *digest;
+
+ g_assert (GCK_IS_USER_STORAGE (self));
+ g_assert (identifier);
+ g_assert (data);
+
+ digest = g_compute_checksum_for_data (G_CHECKSUM_SHA1, data, n_data);
+ g_return_val_if_fail (digest, FALSE);
+
+ res = gck_data_file_read_value (self->file, identifier, CK_GNOME_INTERNAL_SHA1, &value, &n_value);
+ g_return_val_if_fail (res == GCK_DATA_SUCCESS, FALSE);
+
+ result = (strlen (digest) == n_value && memcmp (digest, value, n_value) == 0);
+ g_free (digest);
+
+ return result;
+}
+
+static void
+store_object_hash (GckUserStorage *self, GckTransaction *transaction, const gchar *identifier,
+ const guchar *data, gsize n_data)
+{
+ GckDataResult res;
+ gchar *digest;
+
+ g_assert (GCK_IS_USER_STORAGE (self));
+ g_assert (GCK_IS_TRANSACTION (transaction));
+ g_assert (identifier);
+ g_assert (data);
+
+ digest = g_compute_checksum_for_data (G_CHECKSUM_SHA1, data, n_data);
+ if (digest == NULL) {
+ gck_transaction_fail (transaction, CKR_GENERAL_ERROR);
+ g_return_if_reached ();
+ }
+
+ res = gck_data_file_write_value (self->file, identifier, CK_GNOME_INTERNAL_SHA1, digest, strlen (digest));
+ g_free (digest);
+
+ if (res != GCK_DATA_SUCCESS)
+ gck_transaction_fail (transaction, CKR_GENERAL_ERROR);
+}
+
static void
data_file_entry_added (GckDataFile *store, const gchar *identifier, GckUserStorage *self)
{
@@ -460,6 +512,12 @@
return;
}
+ /* Make sure that the object wasn't tampered with */
+ if (!check_object_hash (self, identifier, data, n_data)) {
+ g_message ("file in user store doesn't match hash: %s", identifier);
+ return;
+ }
+
/* Create a new object for this identifier */
object = g_object_new (type, "unique", identifier, NULL);
g_return_if_fail (GCK_IS_SERIALIZABLE (object));
@@ -521,7 +579,7 @@
}
static void
-relock_object (GckTransaction *transaction, const gchar *path,
+relock_object (GckUserStorage *self, GckTransaction *transaction, const gchar *path,
const gchar *identifier, GckLogin *old_login, GckLogin *new_login)
{
GError *error = NULL;
@@ -532,6 +590,7 @@
GType type;
CK_RV rv;
+ g_assert (GCK_IS_USER_STORAGE (self));
g_assert (GCK_IS_TRANSACTION (transaction));
g_assert (identifier);
g_assert (path);
@@ -556,10 +615,18 @@
/* Read in the data for the object */
if (!g_file_get_contents (path, (gchar**)&data, &n_data, &error)) {
- g_message ("couldn't relock file in user store: %s: %s", identifier,
+ g_message ("couldn't load file in user store in order to relock: %s: %s", identifier,
error && error->message ? error->message : "");
g_clear_error (&error);
g_object_unref (object);
+ gck_transaction_fail (transaction, CKR_GENERAL_ERROR);
+ return;
+ }
+
+ /* Make sure the data matches the hash */
+ if (!check_object_hash (self, identifier, data, n_data)) {
+ g_message ("file in data store doesn't match hash: %s", identifier);
+ gck_transaction_fail (transaction, CKR_GENERAL_ERROR);
return;
}
@@ -619,7 +686,13 @@
/* And write it back out to the file */
gck_transaction_write_file (transaction, path, data, n_data);
+
+ /* Create and save the hash here */
+ if (!gck_transaction_get_failed (transaction))
+ store_object_hash (self, transaction, identifier, data, n_data);
+
g_free (data);
+
}
typedef struct _RelockArgs {
@@ -648,7 +721,7 @@
return;
path = g_build_filename (args->self->directory, identifier, NULL);
- relock_object (args->transaction, path, identifier, args->old_login, args->new_login);
+ relock_object (args->self, args->transaction, path, identifier, args->old_login, args->new_login);
g_free (path);
}
@@ -1063,6 +1136,10 @@
path = g_build_filename (self->directory, identifier, NULL);
gck_transaction_write_file (transaction, path, data, n_data);
+
+ /* Make sure we write in the object hash */
+ if (!gck_transaction_get_failed (transaction))
+ store_object_hash (self, transaction, identifier, data, n_data);
/* Now we decide to own the object */
if (!gck_transaction_get_failed (transaction))
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]