summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Walter <stefw@src.gnome.org>2008-12-30 02:18:02 +0000
committerStefan Walter <stefw@src.gnome.org>2008-12-30 02:18:02 +0000
commite4bc09c74100a5d9165d35fa4db51c642d0091f7 (patch)
tree82ddf6e1963553b1cb9f2b0a86574a9b4dfd9ed4
parent64ed69dced12b3f6cabb143a195334711486bea1 (diff)
downloadgnome-keyring-e4bc09c74100a5d9165d35fa4db51c642d0091f7.tar.gz
Add support for specifying custom allocators on GP11Attributes, and fine
* gp11/gp11.h: * gp11/gp11-attributes.c: * gp11/gp11-object.c: * gp11/gp11-private.h: * gp11/gp11-session.c: * gp11/tests/Makefile.am: * gp11/tests/unit-test-gp11-attributes.c: * gp11/tests/unit-test-gp11-crypto.c: * gp11/tests/unit-test-gp11-object.c: * tool/gkr-tool-import.c: Add support for specifying custom allocators on GP11Attributes, and fine tune how gp11_object_get_* work. Add concept of locked attribute arrays with guarantees of application to not modify while we're processing them. svn path=/trunk/; revision=1414
-rw-r--r--ChangeLog16
-rw-r--r--gp11/gp11-attributes.c425
-rw-r--r--gp11/gp11-object.c423
-rw-r--r--gp11/gp11-private.h19
-rw-r--r--gp11/gp11-session.c62
-rw-r--r--gp11/gp11.h42
-rw-r--r--gp11/tests/Makefile.am8
-rw-r--r--gp11/tests/unit-test-gp11-attributes.c106
-rw-r--r--gp11/tests/unit-test-gp11-crypto.c10
-rw-r--r--gp11/tests/unit-test-gp11-object.c98
-rw-r--r--tool/gkr-tool-import.c23
11 files changed, 897 insertions, 335 deletions
diff --git a/ChangeLog b/ChangeLog
index fb031e00..dae9ef0f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2008-12-29 Stef Walter <stef@memberwebs.com>
+
+ * gp11/gp11.h:
+ * gp11/gp11-attributes.c:
+ * gp11/gp11-object.c:
+ * gp11/gp11-private.h:
+ * gp11/gp11-session.c:
+ * gp11/tests/Makefile.am:
+ * gp11/tests/unit-test-gp11-attributes.c:
+ * gp11/tests/unit-test-gp11-crypto.c:
+ * gp11/tests/unit-test-gp11-object.c:
+ * tool/gkr-tool-import.c: Add support for specifying custom allocators
+ on GP11Attributes, and fine tune how gp11_object_get_* work. Add
+ concept of locked attribute arrays with guarantees of application to
+ not modify while we're processing them.
+
2008-12-28 Stef Walter <stef@memberwebs.com>
* gp11/gp11.h:
diff --git a/gp11/gp11-attributes.c b/gp11/gp11-attributes.c
index af1636f9..aa8d71a8 100644
--- a/gp11/gp11-attributes.c
+++ b/gp11/gp11-attributes.c
@@ -29,6 +29,25 @@
#include <stdlib.h>
#include <string.h>
+
+static void
+attribute_init (GP11Attribute *attr, gulong attr_type,
+ gconstpointer value, gsize length,
+ GP11Allocator allocator)
+{
+ g_assert (sizeof (GP11Attribute) == sizeof (CK_ATTRIBUTE));
+ g_assert (allocator);
+
+ memset (attr, 0, sizeof (GP11Attribute));
+ attr->type = attr_type;
+ attr->length = length;
+ if (value && length) {
+ attr->value = (allocator) (NULL, length);
+ g_assert (attr->value);
+ memcpy (attr->value, value, length);
+ }
+}
+
/**
* gp11_attribute_init:
* @attr: An uninitialized attribute.
@@ -46,11 +65,8 @@ void
gp11_attribute_init (GP11Attribute *attr, gulong attr_type,
gconstpointer value, gsize length)
{
- g_assert (sizeof (GP11Attribute) == sizeof (CK_ATTRIBUTE));
- memset (attr, 0, sizeof (GP11Attribute));
- attr->type = attr_type;
- attr->length = length;
- attr->value = value && length ? g_memdup (value, length) : NULL;
+ g_return_if_fail (attr);
+ attribute_init (attr, attr_type, value, length, g_realloc);
}
/**
@@ -68,21 +84,41 @@ gp11_attribute_init (GP11Attribute *attr, gulong attr_type,
void
gp11_attribute_init_invalid (GP11Attribute *attr, gulong attr_type)
{
+ g_return_if_fail (attr);
g_assert (sizeof (GP11Attribute) == sizeof (CK_ATTRIBUTE));
memset (attr, 0, sizeof (GP11Attribute));
attr->type = attr_type;
attr->length = (gulong)-1;
}
+/**
+ * gp11_attribute_init_empty:
+ * @attr: An uninitialized attribute.
+ * @attr_type: The PKCS#11 attribute type to set on the attribute.
+ *
+ * Initialize a PKCS#11 attribute to an empty state. The attribute
+ * type will be set, but no data will be set.
+ *
+ * When done with the attribute you should use gp11_attribute_clear()
+ * to free the internal memory.
+ **/
void
-_gp11_attribute_init_take (GP11Attribute *attr, gulong attr_type,
- gpointer value, gsize length)
+gp11_attribute_init_empty (GP11Attribute *attr, gulong attr_type)
{
+ g_return_if_fail (attr);
g_assert (sizeof (GP11Attribute) == sizeof (CK_ATTRIBUTE));
memset (attr, 0, sizeof (GP11Attribute));
attr->type = attr_type;
- attr->length = length;
- attr->value = value && length ? value : NULL;
+ attr->length = 0;
+ attr->value = 0;
+}
+
+static void
+attribute_init_boolean (GP11Attribute *attr, gulong attr_type,
+ gboolean value, GP11Allocator allocator)
+{
+ CK_BBOOL bvalue = value ? CK_TRUE : CK_FALSE;
+ attribute_init (attr, attr_type, &bvalue, sizeof (bvalue), allocator);
}
/**
@@ -101,8 +137,25 @@ void
gp11_attribute_init_boolean (GP11Attribute *attr, gulong attr_type,
gboolean value)
{
- CK_BBOOL bvalue = value ? CK_TRUE : CK_FALSE;
- gp11_attribute_init (attr, attr_type, &bvalue, sizeof (bvalue));
+ g_return_if_fail (attr);
+ attribute_init_boolean (attr, attr_type, value, g_realloc);
+}
+
+static void
+attribute_init_date (GP11Attribute *attr, gulong attr_type,
+ const GDate *value, GP11Allocator allocator)
+{
+ gchar buffer[9];
+ CK_DATE date;
+ g_assert (value);
+ g_snprintf (buffer, sizeof (buffer), "%04d%02d%02d",
+ (int)g_date_get_year (value),
+ (int)g_date_get_month (value),
+ (int)g_date_get_day (value));
+ memcpy (&date.year, buffer + 0, 4);
+ memcpy (&date.month, buffer + 4, 2);
+ memcpy (&date.day, buffer + 6, 2);
+ attribute_init (attr, attr_type, &date, sizeof (CK_DATE), allocator);
}
/**
@@ -121,17 +174,17 @@ void
gp11_attribute_init_date (GP11Attribute *attr, gulong attr_type,
const GDate *value)
{
- gchar buffer[9];
- CK_DATE date;
+ g_return_if_fail (attr);
g_return_if_fail (value);
- g_snprintf (buffer, sizeof (buffer), "%04d%02d%02d",
- (int)g_date_get_year (value),
- (int)g_date_get_month (value),
- (int)g_date_get_day (value));
- memcpy (&date.year, buffer + 0, 4);
- memcpy (&date.month, buffer + 4, 2);
- memcpy (&date.day, buffer + 6, 2);
- gp11_attribute_init (attr, attr_type, &date, sizeof (CK_DATE));
+ attribute_init_date (attr, attr_type, value, g_realloc);
+}
+
+static void
+attribute_init_ulong (GP11Attribute *attr, gulong attr_type,
+ gulong value, GP11Allocator allocator)
+{
+ CK_ULONG uvalue = value;
+ attribute_init (attr, attr_type, &uvalue, sizeof (uvalue), allocator);
}
/**
@@ -150,8 +203,16 @@ void
gp11_attribute_init_ulong (GP11Attribute *attr, gulong attr_type,
gulong value)
{
- CK_ULONG uvalue = value;
- gp11_attribute_init (attr, attr_type, &uvalue, sizeof (uvalue));
+ g_return_if_fail (attr);
+ attribute_init_ulong (attr, attr_type, value, g_realloc);
+}
+
+static void
+attribute_init_string (GP11Attribute *attr, gulong attr_type,
+ const gchar *value, GP11Allocator allocator)
+{
+ gsize len = value ? strlen (value) : 0;
+ attribute_init (attr, attr_type, (gpointer)value, len, allocator);
}
/**
@@ -172,8 +233,8 @@ void
gp11_attribute_init_string (GP11Attribute *attr, gulong attr_type,
const gchar *value)
{
- gsize len = value ? strlen (value) : 0;
- gp11_attribute_init (attr, attr_type, (gpointer)value, len);
+ g_return_if_fail (attr);
+ attribute_init_string (attr, attr_type, value, g_realloc);
}
/**
@@ -192,7 +253,7 @@ GP11Attribute*
gp11_attribute_new (gulong attr_type, gpointer value, gsize length)
{
GP11Attribute *attr = g_slice_new0 (GP11Attribute);
- gp11_attribute_init (attr, attr_type, value, length);
+ attribute_init (attr, attr_type, value, length, g_realloc);
return attr;
}
@@ -216,6 +277,23 @@ gp11_attribute_new_invalid (gulong attr_type)
}
/**
+ * gp11_attribute_new_empty:
+ * @attr_type: The PKCS#11 attribute type to set on the attribute.
+ *
+ * Create a new PKCS#11 attribute with empty data.
+ *
+ * Return value: The new attribute. When done with the attribute use
+ * gp11_attribute_free() to free it.
+ */
+GP11Attribute*
+gp11_attribute_new_empty (gulong attr_type)
+{
+ GP11Attribute *attr = g_slice_new0 (GP11Attribute);
+ gp11_attribute_init_empty (attr, attr_type);
+ return attr;
+}
+
+/**
* gp11_attribute_new_boolean:
* @attr_type: The PKCS#11 attribute type to set on the attribute.
* @value: The boolean value of the attribute.
@@ -230,7 +308,7 @@ GP11Attribute*
gp11_attribute_new_boolean (gulong attr_type, gboolean value)
{
GP11Attribute *attr = g_slice_new0 (GP11Attribute);
- gp11_attribute_init_boolean (attr, attr_type, value);
+ attribute_init_boolean (attr, attr_type, value, g_realloc);
return attr;
}
@@ -249,7 +327,7 @@ GP11Attribute*
gp11_attribute_new_date (gulong attr_type, const GDate *value)
{
GP11Attribute *attr = g_slice_new0 (GP11Attribute);
- gp11_attribute_init_date (attr, attr_type, value);
+ attribute_init_date (attr, attr_type, value, g_realloc);
return attr;
}
@@ -268,7 +346,7 @@ GP11Attribute*
gp11_attribute_new_ulong (gulong attr_type, gulong value)
{
GP11Attribute *attr = g_slice_new0 (GP11Attribute);
- gp11_attribute_init_ulong (attr, attr_type, value);
+ attribute_init_ulong (attr, attr_type, value, g_realloc);
return attr;
}
@@ -289,7 +367,7 @@ GP11Attribute*
gp11_attribute_new_string (gulong attr_type, const gchar *value)
{
GP11Attribute *attr = g_slice_new0 (GP11Attribute);
- gp11_attribute_init_string (attr, attr_type, value);
+ attribute_init_string (attr, attr_type, value, g_realloc);
return attr;
}
@@ -449,6 +527,26 @@ gp11_attribute_dup (GP11Attribute *attr)
return copy;
}
+static void
+attribute_init_copy (GP11Attribute *dest, const GP11Attribute *src, GP11Allocator allocator)
+{
+ g_assert (dest);
+ g_assert (src);
+ g_assert (allocator);
+
+ /*
+ * TODO: Handle stupid, dumb, broken, special cases like
+ * CKA_WRAP_TEMPLATE and CKA_UNWRAP_TEMPLATE.
+ */
+
+ memcpy (dest, src, sizeof (GP11Attribute));
+ if (src->value && src->length) {
+ dest->value = (allocator) (NULL, src->length);
+ g_assert (dest->value);
+ memcpy (dest->value, src->value, src->length);
+ }
+}
+
/**
* gp11_attribute_init_copy:
* @dest: An uninitialized attribute.
@@ -461,18 +559,22 @@ gp11_attribute_dup (GP11Attribute *attr)
* gp11_attribute_clear() to free the internal memory.
**/
void
-gp11_attribute_init_copy (GP11Attribute *dest, GP11Attribute *src)
+gp11_attribute_init_copy (GP11Attribute *dest, const GP11Attribute *src)
{
g_return_if_fail (dest);
g_return_if_fail (src);
+ attribute_init_copy (dest, src, g_realloc);
+}
- /*
- * TODO: Handle stupid, dumb, broken, special cases like
- * CKA_WRAP_TEMPLATE and CKA_UNWRAP_TEMPLATE.
- */
-
- memcpy (dest, src, sizeof (GP11Attribute));
- dest->value = src->value && src->length ? g_memdup (src->value, src->length) : NULL;
+static void
+attribute_clear (GP11Attribute *attr, GP11Allocator allocator)
+{
+ g_assert (attr);
+ g_assert (allocator);
+ if (attr->value)
+ (allocator) (attr->value, 0);
+ attr->value = NULL;
+ attr->length = 0;
}
/**
@@ -482,13 +584,14 @@ gp11_attribute_init_copy (GP11Attribute *dest, GP11Attribute *src)
* Clear allocated memory held by a statically allocated attribute.
* These are usually initialized with gp11_attribute_init() or a
* similar function.
+ *
+ * The type of the attribute will remain set.
**/
void
gp11_attribute_clear (GP11Attribute *attr)
{
g_return_if_fail (attr);
- g_free (attr->value);
- memset (attr, 0, sizeof (GP11Attribute));
+ attribute_clear (attr, g_realloc);
}
/**
@@ -503,14 +606,15 @@ void
gp11_attribute_free (GP11Attribute *attr)
{
if (attr) {
- gp11_attribute_clear (attr);
+ attribute_clear (attr, g_realloc);
g_slice_free (GP11Attribute, attr);
}
}
struct _GP11Attributes {
GArray *array;
- gint immutable;
+ GP11Allocator allocator;
+ gboolean locked;
gint refs;
};
@@ -543,24 +647,73 @@ gp11_attributes_get_boxed_type (void)
GP11Attributes*
gp11_attributes_new (void)
{
+ return gp11_attributes_new_full (g_realloc);
+}
+
+/**
+ * gp11_attributes_new_full:
+ * @allocator: Memory allocator for attribute data, or NULL for default.
+ *
+ * Create a new GP11Attributes array.
+ *
+ * Return value: The new attributes array. When done with the array
+ * release it with gp11_attributes_unref().
+ **/
+GP11Attributes*
+gp11_attributes_new_full (GP11Allocator allocator)
+{
GP11Attributes *attrs;
+
+ if (!allocator)
+ allocator = g_realloc;
g_assert (sizeof (GP11Attribute) == sizeof (CK_ATTRIBUTE));
attrs = g_slice_new0 (GP11Attributes);
attrs->array = g_array_new (0, 1, sizeof (GP11Attribute));
+ attrs->allocator = allocator;
attrs->refs = 1;
- attrs->immutable = 0;
+ attrs->locked = FALSE;
+ return attrs;
+}
+
+/**
+ * gp11_attributes_new_empty:
+ * @attr_type: The first attribute type to add as empty.
+ *
+ * Creates an GP11Attributes array with empty attributes. The arguments
+ * should be values of attribute types, terminated with -1.
+ *
+ * Return value: The new attributes array. When done with the array
+ * release it with gp11_attributes_unref().
+ **/
+GP11Attributes*
+gp11_attributes_new_empty (gulong attr_type, ...)
+{
+ GP11Attributes *attrs = gp11_attributes_new_full (g_realloc);
+ va_list va;
+
+ va_start (va, attr_type);
+
+ while (attr_type != (gulong)-1) {
+ gp11_attributes_add_empty (attrs, attr_type);
+ attr_type = va_arg (va, gulong);
+ }
+
+ va_end (va);
+
return attrs;
}
static GP11Attributes*
-initialize_from_valist (gulong type, va_list va)
+initialize_from_valist (GP11Allocator allocator, gulong type, va_list va)
{
GP11Attributes *attrs;
gssize length;
gpointer value;
- attrs = gp11_attributes_new ();
+ g_assert (allocator);
+
+ attrs = gp11_attributes_new_full (allocator);
/* No attributes */
if (type == (gulong)-1)
@@ -639,7 +792,7 @@ gp11_attributes_newv (gulong first_type, ...)
va_list va;
va_start (va, first_type);
- attrs = initialize_from_valist (first_type, va);
+ attrs = initialize_from_valist (g_realloc, first_type, va);
va_end (va);
return attrs;
@@ -647,6 +800,7 @@ gp11_attributes_newv (gulong first_type, ...)
/**
* gp11_attributes_newv:
+ * @allocator: Memory allocator for attribute data, or NULL for default.
* @va: Variable argument containing attributes to add.
*
* Create a new GP11Attributes array.
@@ -676,10 +830,14 @@ gp11_attributes_newv (gulong first_type, ...)
* release it with gp11_attributes_unref().
**/
GP11Attributes*
-gp11_attributes_new_valist (va_list va)
+gp11_attributes_new_valist (GP11Allocator allocator, va_list va)
{
gulong type = va_arg (va, gulong);
- return initialize_from_valist (type, va);
+
+ if (!allocator)
+ allocator = g_realloc;
+
+ return initialize_from_valist (allocator, type, va);
}
/**
@@ -699,23 +857,15 @@ gp11_attributes_at (GP11Attributes *attrs, guint index)
{
g_return_val_if_fail (attrs && attrs->array, NULL);
g_return_val_if_fail (index < attrs->array->len, NULL);
- g_return_val_if_fail (g_atomic_int_get (&attrs->immutable) == 0, NULL);
+ g_return_val_if_fail (!attrs->locked, NULL);
return &g_array_index (attrs->array, GP11Attribute, index);
}
-CK_ATTRIBUTE_PTR
-_gp11_attributes_raw (GP11Attributes *attrs)
-{
- g_return_val_if_fail (attrs && attrs->array, NULL);
- return (CK_ATTRIBUTE_PTR)attrs->array->data;
-}
-
static GP11Attribute*
attributes_push (GP11Attributes *attrs)
{
GP11Attribute attr;
- g_assert (g_atomic_int_get (&attrs->immutable) == 0);
-
+ g_assert (!attrs->locked);
memset (&attr, 0, sizeof (attr));
g_array_append_val (attrs->array, attr);
return &g_array_index (attrs->array, GP11Attribute, attrs->array->len - 1);
@@ -735,21 +885,10 @@ gp11_attributes_add (GP11Attributes *attrs, GP11Attribute *attr)
{
GP11Attribute *added;
g_return_if_fail (attrs && attrs->array);
- g_return_if_fail (g_atomic_int_get (&attrs->immutable) == 0);
+ g_return_if_fail (!attrs->locked);
g_return_if_fail (attr);
added = attributes_push (attrs);
- gp11_attribute_init_copy (added, attr);
-}
-
-void
-_gp11_attributes_add_take (GP11Attributes *attrs, gulong attr_type,
- gpointer value, gsize length)
-{
- GP11Attribute *added;
- g_return_if_fail (attrs);
- g_return_if_fail (g_atomic_int_get (&attrs->immutable) == 0);
- added = attributes_push (attrs);
- _gp11_attribute_init_take (added, attr_type, (gpointer)value, length);
+ attribute_init_copy (added, attr, attrs->allocator);
}
/**
@@ -769,9 +908,9 @@ gp11_attributes_add_data (GP11Attributes *attrs, gulong attr_type,
{
GP11Attribute *added;
g_return_if_fail (attrs);
- g_return_if_fail (g_atomic_int_get (&attrs->immutable) == 0);
+ g_return_if_fail (!attrs->locked);
added = attributes_push (attrs);
- gp11_attribute_init (added, attr_type, value, length);
+ attribute_init (added, attr_type, value, length, attrs->allocator);
}
/**
@@ -786,12 +925,29 @@ gp11_attributes_add_invalid (GP11Attributes *attrs, gulong attr_type)
{
GP11Attribute *added;
g_return_if_fail (attrs);
- g_return_if_fail (g_atomic_int_get (&attrs->immutable) == 0);
+ g_return_if_fail (!attrs->locked);
added = attributes_push (attrs);
gp11_attribute_init_invalid (added, attr_type);
}
/**
+ * gp11_attributes_add_empty:
+ * @attrs: The attributes array to add.
+ * @attr_type: The type of attribute to add.
+ *
+ * Add an attribute with the specified type, with empty data.
+ **/
+void
+gp11_attributes_add_empty (GP11Attributes *attrs, gulong attr_type)
+{
+ GP11Attribute *added;
+ g_return_if_fail (attrs);
+ g_return_if_fail (!attrs->locked);
+ added = attributes_push (attrs);
+ gp11_attribute_init_empty (added, attr_type);
+}
+
+/**
* gp11_attributes_add_boolean:
* @attrs: The attributes array to add to.
* @attr_type: The type of attribute to add.
@@ -806,9 +962,9 @@ gp11_attributes_add_boolean (GP11Attributes *attrs, gulong attr_type, gboolean v
{
GP11Attribute *added;
g_return_if_fail (attrs);
- g_return_if_fail (g_atomic_int_get (&attrs->immutable) == 0);
+ g_return_if_fail (!attrs->locked);
added = attributes_push (attrs);
- gp11_attribute_init_boolean (added, attr_type, value);
+ attribute_init_boolean (added, attr_type, value, attrs->allocator);
}
/**
@@ -826,9 +982,9 @@ gp11_attributes_add_string (GP11Attributes *attrs, gulong attr_type, const gchar
{
GP11Attribute *added;
g_return_if_fail (attrs);
- g_return_if_fail (g_atomic_int_get (&attrs->immutable) == 0);
+ g_return_if_fail (!attrs->locked);
added = attributes_push (attrs);
- gp11_attribute_init_string (added, attr_type, value);
+ attribute_init_string (added, attr_type, value, attrs->allocator);
}
/**
@@ -846,9 +1002,9 @@ gp11_attributes_add_date (GP11Attributes *attrs, gulong attr_type, const GDate *
{
GP11Attribute *added;
g_return_if_fail (attrs);
- g_return_if_fail (g_atomic_int_get (&attrs->immutable) == 0);
+ g_return_if_fail (!attrs->locked);
added = attributes_push (attrs);
- gp11_attribute_init_date (added, attr_type, value);
+ attribute_init_date (added, attr_type, value, attrs->allocator);
}
/**
@@ -866,9 +1022,9 @@ gp11_attributes_add_ulong (GP11Attributes *attrs, gulong attr_type, gulong value
{
GP11Attribute *added;
g_return_if_fail (attrs);
- g_return_if_fail (g_atomic_int_get (&attrs->immutable) == 0);
+ g_return_if_fail (!attrs->locked);
added = attributes_push (attrs);
- gp11_attribute_init_ulong (added, attr_type, value);
+ attribute_init_ulong (added, attr_type, value, attrs->allocator);
}
/**
@@ -883,6 +1039,7 @@ gulong
gp11_attributes_count (GP11Attributes *attrs)
{
g_return_val_if_fail (attrs, 0);
+ g_return_val_if_fail (!attrs->locked, 0);
return attrs->array->len;
}
@@ -902,7 +1059,8 @@ gp11_attributes_find (GP11Attributes *attrs, gulong attr_type)
guint i;
g_return_val_if_fail (attrs && attrs->array, NULL);
-
+ g_return_val_if_fail (!attrs->locked, NULL);
+
for (i = 0; i < attrs->array->len; ++i) {
attr = gp11_attributes_at (attrs, i);
if (attr->type == attr_type)
@@ -930,7 +1088,9 @@ gboolean
gp11_attributes_find_boolean (GP11Attributes *attrs, gulong attr_type, gboolean *value)
{
GP11Attribute *attr;
+
g_return_val_if_fail (value, FALSE);
+ g_return_val_if_fail (!attrs->locked, FALSE);
attr = gp11_attributes_find (attrs, attr_type);
if (!attr || gp11_attribute_is_invalid (attr))
@@ -957,7 +1117,9 @@ gboolean
gp11_attributes_find_ulong (GP11Attributes *attrs, gulong attr_type, gulong *value)
{
GP11Attribute *attr;
+
g_return_val_if_fail (value, FALSE);
+ g_return_val_if_fail (!attrs->locked, FALSE);
attr = gp11_attributes_find (attrs, attr_type);
if (!attr || gp11_attribute_is_invalid (attr))
@@ -984,7 +1146,9 @@ gboolean
gp11_attributes_find_string (GP11Attributes *attrs, gulong attr_type, gchar **value)
{
GP11Attribute *attr;
+
g_return_val_if_fail (value, FALSE);
+ g_return_val_if_fail (!attrs->locked, FALSE);
attr = gp11_attributes_find (attrs, attr_type);
if (!attr || gp11_attribute_is_invalid (attr))
@@ -1011,7 +1175,9 @@ gboolean
gp11_attributes_find_date (GP11Attributes *attrs, gulong attr_type, GDate *value)
{
GP11Attribute *attr;
+
g_return_val_if_fail (value, FALSE);
+ g_return_val_if_fail (!attrs->locked, FALSE);
attr = gp11_attributes_find (attrs, attr_type);
if (!attr || gp11_attribute_is_invalid (attr))
@@ -1052,10 +1218,101 @@ gp11_attributes_unref (GP11Attributes *attrs)
if (g_atomic_int_dec_and_test (&attrs->refs)) {
g_return_if_fail (attrs->array);
+ g_return_if_fail (!attrs->locked);
for (i = 0; i < attrs->array->len; ++i)
- gp11_attribute_clear (gp11_attributes_at (attrs, i));
+ attribute_clear (gp11_attributes_at (attrs, i), attrs->allocator);
g_array_free (attrs->array, TRUE);
attrs->array = NULL;
g_slice_free (GP11Attributes, attrs);
}
}
+
+/* -------------------------------------------------------------------------------------------
+ * INTERNAL
+ *
+ * The idea is that while we're processing a GP11Attributes array (via PKCS#11
+ * C_GetAtributeValue for example) the calling application shouldn't access those
+ * attributes at all, except to ref or unref them.
+ *
+ * We try to help debug this with our 'locked' states. The various processing
+ * functions that accept GP11Attributes lock the attributes while handing
+ * them off to be processed (perhaps in a different thread). We check this locked
+ * flag in all public functions accessing GP11Attributes.
+ *
+ * The reason we don't use thread safe or atomic primitives here, is because:
+ * a) The attributes are 'locked' by the same thread that prepares the call.
+ * b) This is a debugging feature, and should not be relied on for correctness.
+ */
+
+void
+_gp11_attributes_lock (GP11Attributes *attrs)
+{
+ g_assert (attrs);
+ g_assert (!attrs->locked);
+ attrs->locked = TRUE;
+}
+
+void
+_gp11_attributes_unlock (GP11Attributes *attrs)
+{
+ g_assert (attrs);
+ g_assert (attrs->locked);
+ attrs->locked = FALSE;
+}
+
+CK_ATTRIBUTE_PTR
+_gp11_attributes_prepare_in (GP11Attributes *attrs, CK_ULONG_PTR n_attrs)
+{
+ GP11Attribute *attr;
+ guint i;
+
+ g_assert (attrs);
+ g_assert (n_attrs);
+ g_assert (attrs->locked);
+
+ /* Prepare the attributes to receive their length */
+
+ for (i = 0; i < attrs->array->len; ++i) {
+ attr = &g_array_index (attrs->array, GP11Attribute, i);
+ attribute_clear (attr, attrs->allocator);
+ }
+
+ *n_attrs = attrs->array->len;
+ return (CK_ATTRIBUTE_PTR)attrs->array->data;
+}
+
+CK_ATTRIBUTE_PTR
+_gp11_attributes_commit_in (GP11Attributes *attrs, CK_ULONG_PTR n_attrs)
+{
+ GP11Attribute *attr;
+ guint i;
+
+ g_assert (attrs);
+ g_assert (n_attrs);
+ g_assert (attrs->locked);
+
+ /* Allocate each attribute with the length that was set */
+
+ for (i = 0; i < attrs->array->len; ++i) {
+ attr = &g_array_index (attrs->array, GP11Attribute, i);
+ g_assert (!attr->value);
+ if (attr->length != 0 && attr->length != (gulong)-1) {
+ attr->value = (attrs->allocator) (NULL, attr->length);
+ g_assert (attr->value);
+ }
+ }
+
+ *n_attrs = attrs->array->len;
+ return (CK_ATTRIBUTE_PTR)attrs->array->data;
+}
+
+CK_ATTRIBUTE_PTR
+_gp11_attributes_commit_out (GP11Attributes *attrs, CK_ULONG_PTR n_attrs)
+{
+ g_assert (attrs);
+ g_assert (n_attrs);
+ g_assert (attrs->locked);
+
+ *n_attrs = attrs->array->len;
+ return (CK_ATTRIBUTE_PTR)attrs->array->data;
+}
diff --git a/gp11/gp11-object.c b/gp11/gp11-object.c
index 548783f0..2bf0770b 100644
--- a/gp11/gp11-object.c
+++ b/gp11/gp11-object.c
@@ -286,28 +286,26 @@ gp11_object_from_handle (GP11Slot *slot, CK_OBJECT_HANDLE handle)
/**
* gp11_objects_from_handle_array:
* @slot: The slot on which these objects are present.
- * @attr: The raw object handles, contained in an attribute.
+ * @handles: The raw object handles.
+ * @n_handles: The number of raw object handles.
*
- * Initialize a list of GP11Object from raw PKCS#11 handles contained inside
- * of an attribute. The attribute must contain contiguous CK_OBJECT_HANDLE
- * handles in an array.
+ * Initialize a list of GP11Object from raw PKCS#11 handles. The handles argument must contain
+ * contiguous CK_OBJECT_HANDLE handles in an array.
*
* Return value: The list of GP11Object. You should use gp11_list_unref_free() when done with
* this list.
**/
GList*
-gp11_objects_from_handle_array (GP11Slot *slot, const GP11Attribute *attr)
+gp11_objects_from_handle_array (GP11Slot *slot, CK_OBJECT_HANDLE_PTR handles, CK_ULONG n_handles)
{
GList *results = NULL;
- CK_OBJECT_HANDLE *array;
- guint i, n_array;
+ CK_ULONG i;
g_return_val_if_fail (GP11_IS_SLOT (slot), NULL);
+ g_return_val_if_fail (handles || !n_handles, NULL);
- array = (CK_OBJECT_HANDLE*)attr->value;
- n_array = attr->length / sizeof (CK_OBJECT_HANDLE);
- for (i = 0; i < n_array; ++i)
- results = g_list_prepend (results, gp11_object_from_handle (slot, array[i]));
+ for (i = 0; i < n_handles; ++i)
+ results = g_list_prepend (results, gp11_object_from_handle (slot, handles[i]));
return g_list_reverse (results);
}
@@ -428,7 +426,9 @@ gp11_object_set_session (GP11Object *self, GP11Session *session)
g_static_mutex_unlock (&pv->mutex);
}
-/* DESTROY */
+/* --------------------------------------------------------------------------------------
+ * DESTROY
+ */
typedef struct _Destroy {
GP11Arguments base;
@@ -438,6 +438,7 @@ typedef struct _Destroy {
static CK_RV
perform_destroy (Destroy *args)
{
+ g_assert (args);
return (args->base.pkcs11->C_DestroyObject) (args->base.handle, args->object);
}
@@ -454,6 +455,8 @@ perform_destroy (Destroy *args)
gboolean
gp11_object_destroy (GP11Object *self, GError **err)
{
+ g_return_val_if_fail (GP11_IS_OBJECT (self), FALSE);
+ g_return_val_if_fail (!err || !*err, FALSE);
return gp11_object_destroy_full (self, NULL, err);
}
@@ -478,6 +481,7 @@ gp11_object_destroy_full (GP11Object *self, GCancellable *cancellable, GError **
g_return_val_if_fail (GP11_IS_OBJECT (self), FALSE);
g_return_val_if_fail (GP11_IS_SLOT (data->slot), FALSE);
+ g_return_val_if_fail (!err || !*err, FALSE);
args.object = data->handle;
@@ -530,9 +534,15 @@ gp11_object_destroy_async (GP11Object *self, GCancellable *cancellable,
gboolean
gp11_object_destroy_finish (GP11Object *self, GAsyncResult *result, GError **err)
{
+ g_return_val_if_fail (GP11_IS_OBJECT (self), FALSE);
+ g_return_val_if_fail (GP11_IS_CALL (result), FALSE);
return _gp11_call_basic_finish (result, err);
}
+/* --------------------------------------------------------------------------------------
+ * SET ATTRIBUTES
+ */
+
typedef struct _SetAttributes {
GP11Arguments base;
GP11Attributes *attrs;
@@ -542,14 +552,20 @@ typedef struct _SetAttributes {
static CK_RV
perform_set_attributes (SetAttributes *args)
{
+ CK_ATTRIBUTE_PTR attrs;
+ CK_ULONG n_attrs;
+
+ g_assert (args);
+ attrs = _gp11_attributes_commit_out (args->attrs, &n_attrs);
+
return (args->base.pkcs11->C_SetAttributeValue) (args->base.handle, args->object,
- _gp11_attributes_raw (args->attrs),
- gp11_attributes_count (args->attrs));
+ attrs, n_attrs);
}
static void
free_set_attributes (SetAttributes *args)
{
+ g_assert (args);
gp11_attributes_unref (args->attrs);
g_free (args);
}
@@ -593,8 +609,11 @@ gp11_object_set (GP11Object *self, GError **err, ...)
va_list va;
CK_RV rv;
+ g_return_val_if_fail (GP11_IS_OBJECT (self), FALSE);
+ g_return_val_if_fail (!err || !*err, FALSE);
+
va_start (va, err);
- attrs = gp11_attributes_new_valist (va);
+ attrs = gp11_attributes_new_valist (g_realloc, va);
va_end (va);
rv = gp11_object_set_full (self, attrs, NULL, err);
@@ -624,6 +643,10 @@ gp11_object_set_full (GP11Object *self, GP11Attributes *attrs,
gboolean ret = FALSE;
g_return_val_if_fail (GP11_IS_OBJECT (self), FALSE);
+ g_return_val_if_fail (attrs, FALSE);
+ g_return_val_if_fail (!err || !*err, FALSE);
+
+ _gp11_attributes_lock (attrs);
memset (&args, 0, sizeof (args));
args.attrs = attrs;
@@ -632,6 +655,8 @@ gp11_object_set_full (GP11Object *self, GP11Attributes *attrs,
session = require_session_sync (self, CKF_RW_SESSION, err);
if (session)
ret = _gp11_call_sync (session, perform_set_attributes, NULL, &args, cancellable, err);
+
+ _gp11_attributes_unlock (attrs);
g_object_unref (session);
return ret;
}
@@ -656,9 +681,12 @@ gp11_object_set_async (GP11Object *self, GP11Attributes *attrs, GCancellable *ca
GP11Call *call;
g_return_if_fail (GP11_IS_OBJECT (self));
+ g_return_if_fail (attrs);
args = _gp11_call_async_prep (data->slot, self, perform_set_attributes,
NULL, sizeof (*args), free_set_attributes);
+
+ _gp11_attributes_lock (attrs);
args->attrs = gp11_attributes_ref (attrs);
args->object = data->handle;
@@ -680,15 +708,28 @@ gp11_object_set_async (GP11Object *self, GP11Attributes *attrs, GCancellable *ca
gboolean
gp11_object_set_finish (GP11Object *self, GAsyncResult *result, GError **err)
{
+ SetAttributes *args;
+
+ g_return_val_if_fail (GP11_IS_OBJECT (self), FALSE);
+ g_return_val_if_fail (GP11_IS_CALL (result), FALSE);
+ g_return_val_if_fail (!err || !*err, FALSE);
+
+ /* Unlock the attributes we were using */
+ args = _gp11_call_arguments (result, SetAttributes);
+ g_assert (args->attrs);
+ _gp11_attributes_unlock (args->attrs);
+
return _gp11_call_basic_finish (result, err);
}
+/* ------------------------------------------------------------------------------------
+ * GET ATTRIBUTES
+ */
+
typedef struct _GetAttributes {
GP11Arguments base;
- gulong *attr_types;
- gsize n_attr_types;
CK_OBJECT_HANDLE object;
- GP11Attributes *results;
+ GP11Attributes *attrs;
} GetAttributes;
/*
@@ -713,18 +754,14 @@ static CK_RV
perform_get_attributes (GetAttributes *args)
{
CK_ATTRIBUTE_PTR attrs;
- CK_ULONG i, n_attrs;
+ CK_ULONG n_attrs;
CK_RV rv;
- /* Allocate the CK_ATTRIBUTE's */
- n_attrs = args->n_attr_types;
- if (n_attrs) {
- attrs = g_new0 (CK_ATTRIBUTE, n_attrs);
- for (i = 0; i < n_attrs; ++i)
- attrs[i].type = args->attr_types[i];
- } else {
- attrs = NULL;
- }
+ g_assert (args);
+ g_assert (args->attrs);
+
+ /* Prepare all the attributes */
+ attrs = _gp11_attributes_prepare_in (args->attrs, &n_attrs);
/* Get the size of each value */
rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object,
@@ -735,31 +772,12 @@ perform_get_attributes (GetAttributes *args)
}
/* Allocate memory for each value */
- for (i = 0; i < n_attrs; ++i) {
- if (attrs[i].ulValueLen > 0 && attrs[i].ulValueLen != (CK_ULONG)-1)
- attrs[i].pValue = g_malloc0 (attrs[i].ulValueLen);
- }
+ attrs = _gp11_attributes_commit_in (args->attrs, &n_attrs);
/* Now get the actual values */
rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object,
attrs, n_attrs);
- /* Transfer over the memory to the results */
- if (is_ok_get_attributes_rv (rv)) {
- g_assert (!args->results);
- args->results = gp11_attributes_new ();
- for (i = 0; i < n_attrs; ++i) {
- _gp11_attributes_add_take (args->results, attrs[i].type,
- attrs[i].pValue, attrs[i].ulValueLen);
- memset (&attrs[i], 0, sizeof (attrs[0]));
- }
- }
-
- /* Free any memory we didn't use */
- for (i = 0; i < n_attrs; ++i)
- g_free (attrs[i].pValue);
- g_free (attrs);
-
if (is_ok_get_attributes_rv (rv))
rv = CKR_OK;
@@ -769,9 +787,10 @@ perform_get_attributes (GetAttributes *args)
static void
free_get_attributes (GetAttributes *args)
{
- g_free (args->attr_types);
- if (args->results)
- gp11_attributes_unref (args->results);
+ g_assert (args);
+ g_assert (args->attrs);
+ gp11_attributes_unref (args->attrs);
+ g_free (args);
}
@@ -784,107 +803,114 @@ free_get_attributes (GetAttributes *args)
* Get the specified attributes from the object. This call may
* block for an indefinite period.
*
- * Note that the returned attributes are not required to be
- * in the order they were requested.
- *
* Return value: The resulting PKCS#11 attributes, or NULL if an error occurred.
+ * The result must be unreffed when you're finished with it.
**/
GP11Attributes*
gp11_object_get (GP11Object *self, GError **err, ...)
{
- GP11Attributes *result;
- GArray *array;
+ GP11Attributes *attrs;
va_list va;
gulong type;
- array = g_array_new (0, 1, sizeof (gulong));
+ g_return_val_if_fail (GP11_IS_OBJECT (self), NULL);
+ g_return_val_if_fail (!err || !*err, NULL);
+
+ attrs = gp11_attributes_new ();
va_start (va, err);
for (;;) {
type = va_arg (va, gulong);
if (type == (gulong)-1)
break;
- g_array_append_val (array, type);
+ gp11_attributes_add_invalid (attrs, type);
}
va_end (va);
- result = gp11_object_get_full (self, (gulong*)array->data, array->len, NULL, err);
- g_array_free (array, TRUE);
- return result;
+ if (!gp11_object_get_full (self, attrs, NULL, err)) {
+ gp11_attributes_unref (attrs);
+ return NULL;
+ }
+
+ return attrs;
}
/**
* gp11_object_get:
* @self: The object to get attributes from.
- * @attr_types: The attributes to get.
- * @n_attr_types: The number of attributes to get.
+ * @attrs: The attributes to get, with the types filled in.
* @cancellable: Optional cancellation object, or NULL.
* @err: A location to store an error.
*
* Get the specified attributes from the object. This call may
* block for an indefinite period.
*
- * Note that the returned attributes are not required to be
- * in the order they were requested.
+ * No extra references are added to the returned attributes pointer.
+ * During this call you may not access the attributes in any way.
*
- * Return value: The resulting PKCS#11 attributes, or NULL if an error occurred.
+ * Return value: A pointer to the filled in attributes if successful,
+ * or NULL if not.
**/
GP11Attributes*
-gp11_object_get_full (GP11Object *self, const gulong *attr_types, gsize n_attr_types,
+gp11_object_get_full (GP11Object *self, GP11Attributes *attrs,
GCancellable *cancellable, GError **err)
{
GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
GetAttributes args;
GP11Session *session;
+ gboolean ret;
- g_return_val_if_fail (GP11_IS_OBJECT (self), FALSE);
+ g_return_val_if_fail (GP11_IS_OBJECT (self), NULL);
+ g_return_val_if_fail (attrs, NULL);
+ g_return_val_if_fail (!err || !*err, NULL);
session = require_session_sync (self, 0, err);
if (!session)
return NULL;
+ _gp11_attributes_lock (attrs);
+
memset (&args, 0, sizeof (args));
- args.attr_types = (gulong*)attr_types;
- args.n_attr_types = n_attr_types;
+ args.attrs = attrs;
args.object = data->handle;
- if (!_gp11_call_sync (session, perform_get_attributes, NULL, &args, cancellable, err)) {
- gp11_attributes_unref (args.results);
- g_object_unref (session);
- return NULL;
- }
-
+ ret = _gp11_call_sync (session, perform_get_attributes, NULL, &args, cancellable, err);
+ _gp11_attributes_unlock (attrs);
g_object_unref (session);
- return args.results;
+
+ return ret ? attrs : NULL;
}
/**
* gp11_object_get_async:
* @self: The object to get attributes from.
- * @attr_types: The attributes to get.
- * @n_attr_types: The number of attributes to get.
+ * @attrs: The attributes to get, initialized with their types.
* @cancellable: Optional cancellation object, or NULL.
* @callback: A callback which is called when the operation completes.
* @user_data: Data to be passed to the callback.
*
- * Get the specified attributes from the object. This call returns
- * immediately and completes asynchronously.
+ * Get the specified attributes from the object. The attributes will be cleared
+ * of their current values, and new attributes will be stored. The attributes
+ * should not be accessed in any way except for referencing and unreferencing
+ * them until gp11_object_get_finish() is called.
+ *
+ * This call returns immediately and completes asynchronously.
**/
void
-gp11_object_get_async (GP11Object *self, const gulong *attr_types, gsize n_attr_types,
- GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
+gp11_object_get_async (GP11Object *self, GP11Attributes *attrs, GCancellable *cancellable,
+ GAsyncReadyCallback callback, gpointer user_data)
{
GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
GetAttributes *args;
GP11Call *call;
g_return_if_fail (GP11_IS_OBJECT (self));
+ g_return_if_fail (attrs);
args = _gp11_call_async_prep (data->slot, self, perform_get_attributes,
NULL, sizeof (*args), free_get_attributes);
- args->n_attr_types = n_attr_types;
- if (n_attr_types)
- args->attr_types = g_memdup (attr_types, sizeof (gulong) * n_attr_types);
+ _gp11_attributes_lock (attrs);
+ args->attrs = gp11_attributes_ref (attrs);
args->object = data->handle;
call = _gp11_call_async_ready (args, cancellable, callback, user_data);
@@ -900,119 +926,228 @@ gp11_object_get_async (GP11Object *self, const gulong *attr_types, gsize n_attr_
* Get the result of a get operation and return specified attributes from
* the object.
*
- * Note that the returned attributes are not required to be
- * in the order they were requested.
+ * No extra references are added to the returned attributes pointer.
*
- * Return value: The resulting PKCS#11 attributes, or NULL if an error occurred.
+ * Return value: The filled in attributes structure if successful or
+ * NULL if not successful.
**/
GP11Attributes*
gp11_object_get_finish (GP11Object *self, GAsyncResult *result, GError **err)
{
- GP11Attributes *results;
GetAttributes *args;
+ g_return_val_if_fail (GP11_IS_OBJECT (self), NULL);
+ g_return_val_if_fail (GP11_IS_CALL (result), NULL);
+ g_return_val_if_fail (!err || !*err, NULL);
+
+ args = _gp11_call_arguments (result, GetAttributes);
+ _gp11_attributes_unlock (args->attrs);
+
if (!_gp11_call_basic_finish (result, err))
return NULL;
- args = _gp11_call_arguments (result, GetAttributes);
+ return args->attrs;
+}
+
+/* ---------------------------------------------------------------------------------
+ * GET ATTRIBUTE DATA
+ */
+
+typedef struct _GetAttributeData {
+ GP11Arguments base;
+ CK_OBJECT_HANDLE object;
+ CK_ATTRIBUTE_TYPE type;
+ GP11Allocator allocator;
+ guchar *result;
+ gsize n_result;
+} GetAttributeData;
+
+static CK_RV
+perform_get_attribute_data (GetAttributeData *args)
+{
+ CK_ATTRIBUTE attr;
+ CK_RV rv;
+
+ g_assert (args);
+ g_assert (args->allocator);
+
+ attr.type = args->type;
+ attr.ulValueLen = 0;
+ attr.pValue = 0;
+
+ /* Get the size of the value */
+ rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object,
+ &attr, 1);
+ if (rv != CKR_OK)
+ return rv;
+
+ /* Allocate memory for the value */
+ args->result = (args->allocator) (NULL, attr.ulValueLen);
+ g_assert (args->result);
+ attr.pValue = args->result;
- results = args->results;
- args->results = NULL;
+ /* Now get the actual value */
+ rv = (args->base.pkcs11->C_GetAttributeValue) (args->base.handle, args->object,
+ &attr, 1);
+
+ if (rv == CKR_OK)
+ args->n_result = attr.ulValueLen;
- return results;
+ return rv;
+}
+
+static void
+free_get_attribute_data (GetAttributeData *args)
+{
+ g_assert (args);
+ g_free (args->result);
+ g_free (args);
}
/**
- * gp11_object_get_one:
- * @self: The object to get an attribute from.
- * @attr_type: The attribute to get.
+ * gp11_object_get_data:
+ * @self: The object to get attribute data from.
+ * @attr_type: The attribute to get data for.
+ * @n_data: The length of the resulting data.
* @err: A location to store an error.
*
- * Get the specified attribute from the object. This call may
- * block for an indefinite period.
+ * Get the data for the specified attribute from the object. This call
+ * may block for an indefinite period.
*
- * Return value: The resulting PKCS#11 attribute, or NULL if an error occurred.
+ * Return value: The resulting PKCS#11 attribute data, or NULL if an error occurred.
**/
-GP11Attribute*
-gp11_object_get_one (GP11Object *self, gulong attr_type, GError **err)
+gpointer
+gp11_object_get_data (GP11Object *self, gulong attr_type, gsize *n_data, GError **err)
{
- return gp11_object_get_one_full (self, attr_type, NULL, err);
+ g_return_val_if_fail (GP11_IS_OBJECT (self), NULL);
+ g_return_val_if_fail (n_data, NULL);
+ g_return_val_if_fail (!err || !*err, NULL);
+
+ return gp11_object_get_data_full (self, attr_type, g_realloc, NULL, n_data, err);
}
/**
- * gp11_object_get_one_full:
- * @self: The object to get an attribute from.
- * @attr_type: The attribute to get.
+ * gp11_object_get_data_full:
+ * @self: The object to get attribute data from.
+ * @attr_type: The attribute to get data for.
+ * @allocator: An allocator with which to allocate memory for the data, or NULL for default.
* @cancellable: Optional cancellation object, or NULL.
+ * @n_data: The length of the resulting data.
* @err: A location to store an error.
*
- * Get the specified attribute from the object. This call may
- * block for an indefinite period.
+ * Get the data for the specified attribute from the object. This call
+ * may block for an indefinite period.
*
- * Return value: The resulting PKCS#11 attribute, or NULL if an error occurred.
+ * Return value: The resulting PKCS#11 attribute data, or NULL if an error occurred.
**/
-GP11Attribute*
-gp11_object_get_one_full (GP11Object *self, gulong attr_type,
- GCancellable *cancellable, GError **err)
+gpointer
+gp11_object_get_data_full (GP11Object *self, gulong attr_type, GP11Allocator allocator,
+ GCancellable *cancellable, gsize *n_data, GError **err)
{
- GP11Attributes *attrs;
- GP11Attribute *attr;
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
+ GetAttributeData args;
+ GP11Session *session;
+ gboolean ret;
+
+ g_return_val_if_fail (GP11_IS_OBJECT (self), NULL);
+ g_return_val_if_fail (n_data, NULL);
+ g_return_val_if_fail (!err || !*err, NULL);
+
+ if (!allocator)
+ allocator = g_realloc;
- attrs = gp11_object_get_full (self, &attr_type, 1, cancellable, err);
- if (!attrs || !gp11_attributes_count (attrs))
+ session = require_session_sync (self, 0, err);
+ if (!session)
return NULL;
- attr = gp11_attributes_at (attrs, 0);
- g_return_val_if_fail (attr, NULL);
- attr = gp11_attribute_dup (attr);
- gp11_attributes_unref (attrs);
- return attr;
+ memset (&args, 0, sizeof (args));
+ args.allocator = allocator;
+ args.object = data->handle;
+ args.type = attr_type;
+
+ ret = _gp11_call_sync (session, perform_get_attribute_data, NULL, &args, cancellable, err);
+ g_object_unref (session);
+
+ /* Free any value if failed */
+ if (!ret) {
+ if (args.result)
+ (allocator) (args.result, 0);
+ return NULL;
+ }
+
+ *n_data = args.n_result;
+ return args.result;
}
/**
- * gp11_object_get_one_async:
- * @self: The object to get an attribute from.
- * @attr_type: The attribute to get.
+ * gp11_object_get_data_async:
+ * @self: The object to get attribute data from.
+ * @attr_type: The attribute to get data for.
+ * @allocator: An allocator with which to allocate memory for the data, or NULL for default.
* @cancellable: Optional cancellation object, or NULL.
* @callback: Called when the operation completes.
* @user_data: Data to be passed to the callback.
*
- * Get the specified attribute from the object. This call will
+ * Get the data for the specified attribute from the object. This call will
* return immediately and complete asynchronously.
**/
void
-gp11_object_get_one_async (GP11Object *self, gulong attr_type, GCancellable *cancellable,
- GAsyncReadyCallback callback, gpointer user_data)
+gp11_object_get_data_async (GP11Object *self, gulong attr_type, GP11Allocator allocator,
+ GCancellable *cancellable, GAsyncReadyCallback callback,
+ gpointer user_data)
{
- gp11_object_get_async (self, &attr_type, 1, cancellable, callback, user_data);
+ GP11ObjectData *data = GP11_OBJECT_GET_DATA (self);
+ GetAttributeData *args;
+ GP11Call *call;
+
+ g_return_if_fail (GP11_IS_OBJECT (self));
+
+ if (!allocator)
+ allocator = g_realloc;
+
+ args = _gp11_call_async_prep (data->slot, self, perform_get_attribute_data,
+ NULL, sizeof (*args), free_get_attribute_data);
+
+ args->allocator = allocator;
+ args->object = data->handle;
+ args->type = attr_type;
+
+ call = _gp11_call_async_ready (args, cancellable, callback, user_data);
+ require_session_async (self, call, 0, cancellable);
}
/**
- * gp11_object_get_one_finish:
+ * gp11_object_get_data_finish:
* @self: The object to get an attribute from.
* @result: The result passed to the callback.
+ * @n_data: The length of the resulting data.
* @err: A location to store an error.
*
- * Get the result of an operation to get an attribute from
+ * Get the result of an operation to get attribute data from
* an object.
*
- * Return value: The PKCS#11 attribute or NULL if an error occurred.
+ * Return value: The PKCS#11 attribute data or NULL if an error occurred.
**/
-
-GP11Attribute*
-gp11_object_get_one_finish (GP11Object *self, GAsyncResult *result, GError **err)
+gpointer
+gp11_object_get_data_finish (GP11Object *self, GAsyncResult *result,
+ gsize *n_data, GError **err)
{
- GP11Attributes *attrs;
- GP11Attribute *attr;
+ GetAttributeData *args;
+ guchar *data;
- attrs = gp11_object_get_finish (self, result, err);
- if (!attrs)
+ g_return_val_if_fail (GP11_IS_OBJECT (self), NULL);
+ g_return_val_if_fail (GP11_IS_CALL (result), NULL);
+ g_return_val_if_fail (n_data, NULL);
+ g_return_val_if_fail (!err || !*err, NULL);
+
+ if (!_gp11_call_basic_finish (result, err))
return NULL;
+
+ args = _gp11_call_arguments (result, GetAttributeData);
+
+ *n_data = args->n_result;
+ data = args->result;
+ args->result = NULL;
- attr = gp11_attributes_at (attrs, 0);
- g_return_val_if_fail (attr, NULL);
- attr = gp11_attribute_dup (attr);
- gp11_attributes_unref (attrs);
- return attr;
+ return data;
}
-
diff --git a/gp11/gp11-private.h b/gp11/gp11-private.h
index 6e07d6ca..b251c9ea 100644
--- a/gp11/gp11-private.h
+++ b/gp11/gp11-private.h
@@ -36,17 +36,18 @@ G_BEGIN_DECLS
* ATTRIBUTE INTERNALS
*/
-void _gp11_attribute_init_take (GP11Attribute *attr,
- gulong attr_type,
- gpointer value,
- gsize length);
+void _gp11_attributes_lock (GP11Attributes *attrs);
-void _gp11_attributes_add_take (GP11Attributes *attr,
- gulong attr_type,
- gpointer value,
- gsize length);
+void _gp11_attributes_unlock (GP11Attributes *attrs);
-CK_ATTRIBUTE_PTR _gp11_attributes_raw (GP11Attributes *attrs);
+CK_ATTRIBUTE_PTR _gp11_attributes_prepare_in (GP11Attributes *attrs,
+ CK_ULONG_PTR n_attrs);
+
+CK_ATTRIBUTE_PTR _gp11_attributes_commit_in (GP11Attributes *attrs,
+ CK_ULONG_PTR n_attrs);
+
+CK_ATTRIBUTE_PTR _gp11_attributes_commit_out (GP11Attributes *attrs,
+ CK_ULONG_PTR n_attrs);
/* ----------------------------------------------------------------------------
* SLOT
diff --git a/gp11/gp11-session.c b/gp11/gp11-session.c
index f62d0722..feab0dab 100644
--- a/gp11/gp11-session.c
+++ b/gp11/gp11-session.c
@@ -618,9 +618,13 @@ free_create_object (CreateObject *args)
static CK_RV
perform_create_object (CreateObject *args)
{
- return (args->base.pkcs11->C_CreateObject) (args->base.handle,
- _gp11_attributes_raw (args->attrs),
- gp11_attributes_count (args->attrs),
+ CK_ATTRIBUTE_PTR attrs;
+ CK_ULONG n_attrs;
+
+ attrs = _gp11_attributes_commit_out (args->attrs, &n_attrs);
+
+ return (args->base.pkcs11->C_CreateObject) (args->base.handle,
+ attrs, n_attrs,
&args->object);
}
@@ -665,7 +669,7 @@ gp11_session_create_object (GP11Session *self, GError **err, ...)
va_list va;
va_start (va, err);
- attrs = gp11_attributes_new_valist (va);
+ attrs = gp11_attributes_new_valist (g_realloc, va);
va_end (va);
object = gp11_session_create_object_full (self, attrs, NULL, err);
@@ -691,8 +695,18 @@ gp11_session_create_object_full (GP11Session *self, GP11Attributes *attrs,
{
GP11SessionData *data = GP11_SESSION_GET_DATA (self);
CreateObject args = { GP11_ARGUMENTS_INIT, attrs, 0 };
- if (!_gp11_call_sync (self, perform_create_object, NULL, &args, cancellable, err))
+ gboolean ret;
+
+ g_return_val_if_fail (GP11_IS_SESSION (self), NULL);
+ g_return_val_if_fail (attrs, NULL);
+
+ _gp11_attributes_lock (attrs);
+ ret = _gp11_call_sync (self, perform_create_object, NULL, &args, cancellable, err);
+ _gp11_attributes_unlock (attrs);
+
+ if (!ret)
return NULL;
+
return gp11_object_from_handle (data->slot, args.object);
}
@@ -714,8 +728,12 @@ gp11_session_create_object_async (GP11Session *self, GP11Attributes *attrs,
{
CreateObject *args = _gp11_call_async_prep (self, self, perform_create_object,
NULL, sizeof (*args), free_create_object);
- args->attrs = attrs;
- gp11_attributes_ref (attrs);
+
+ g_return_if_fail (attrs);
+
+ args->attrs = gp11_attributes_ref (attrs);
+ _gp11_attributes_lock (attrs);
+
_gp11_call_async_ready_go (args, cancellable, callback, user_data);
}
@@ -734,10 +752,12 @@ gp11_session_create_object_finish (GP11Session *self, GAsyncResult *result, GErr
{
GP11SessionData *data = GP11_SESSION_GET_DATA (self);
CreateObject *args;
-
+
+ args = _gp11_call_arguments (result, CreateObject);
+ _gp11_attributes_unlock (args->attrs);
+
if (!_gp11_call_basic_finish (result, err))
return NULL;
- args = _gp11_call_arguments (result, CreateObject);
return gp11_object_from_handle (data->slot, args->object);
}
@@ -764,12 +784,15 @@ perform_find_objects (FindObjects *args)
{
CK_OBJECT_HANDLE_PTR batch;
CK_ULONG n_batch, n_found;
+ CK_ATTRIBUTE_PTR attrs;
+ CK_ULONG n_attrs;
GArray *array;
CK_RV rv;
+ attrs = _gp11_attributes_commit_out (args->attrs, &n_attrs);
+
rv = (args->base.pkcs11->C_FindObjectsInit) (args->base.handle,
- _gp11_attributes_raw (args->attrs),
- gp11_attributes_count (args->attrs));
+ attrs, n_attrs);
if (rv != CKR_OK)
return rv;
@@ -868,7 +891,7 @@ gp11_session_find_objects (GP11Session *self, GError **err, ...)
va_list va;
va_start (va, err);
- attrs = gp11_attributes_new_valist (va);
+ attrs = gp11_attributes_new_valist (g_realloc, va);
va_end (va);
results = gp11_session_find_objects_full (self, attrs, NULL, err);
@@ -895,9 +918,14 @@ gp11_session_find_objects_full (GP11Session *self, GP11Attributes *attrs,
FindObjects args = { GP11_ARGUMENTS_INIT, attrs, NULL, 0 };
GList *results = NULL;
+ g_return_val_if_fail (attrs, NULL);
+ _gp11_attributes_lock (attrs);
+
if (_gp11_call_sync (self, perform_find_objects, NULL, &args, cancellable, err))
results = objlist_from_handles (self, args.objects, args.n_objects);
+
g_free (args.objects);
+ _gp11_attributes_unlock (attrs);
return results;
}
@@ -919,8 +947,8 @@ gp11_session_find_objects_async (GP11Session *self, GP11Attributes *attrs,
{
FindObjects *args = _gp11_call_async_prep (self, self, perform_find_objects,
NULL, sizeof (*args), free_find_objects);
- args->attrs = attrs;
- gp11_attributes_ref (attrs);
+ args->attrs = gp11_attributes_ref (attrs);
+ _gp11_attributes_lock (attrs);
_gp11_call_async_ready_go (args, cancellable, callback, user_data);
}
@@ -938,10 +966,12 @@ GList*
gp11_session_find_objects_finish (GP11Session *self, GAsyncResult *result, GError **err)
{
FindObjects *args;
-
+
+ args = _gp11_call_arguments (result, FindObjects);
+ _gp11_attributes_unlock (args->attrs);
+
if (!_gp11_call_basic_finish (result, err))
return NULL;
- args = _gp11_call_arguments (result, FindObjects);
return objlist_from_handles (self, args->objects, args->n_objects);
}
diff --git a/gp11/gp11.h b/gp11/gp11.h
index 00227488..f3784cfb 100644
--- a/gp11/gp11.h
+++ b/gp11/gp11.h
@@ -47,6 +47,8 @@ const gchar* gp11_message_from_rv (CK_RV rv);
gchar* gp11_string_from_chars (const guchar *data, gsize max);
+typedef gpointer (*GP11Allocator) (gpointer data, gsize length);
+
typedef struct GP11Mechanism {
gulong type;
gpointer parameter;
@@ -80,6 +82,9 @@ void gp11_attribute_init (GP11Attribute *attr
void gp11_attribute_init_invalid (GP11Attribute *attr,
gulong attr_type);
+void gp11_attribute_init_empty (GP11Attribute *attr,
+ gulong attr_type);
+
void gp11_attribute_init_boolean (GP11Attribute *attr,
gulong attr_type,
gboolean value);
@@ -97,7 +102,7 @@ void gp11_attribute_init_string (GP11Attribute *attr
const gchar *value);
void gp11_attribute_init_copy (GP11Attribute *dest,
- GP11Attribute *src);
+ const GP11Attribute *src);
GP11Attribute* gp11_attribute_new (gulong attr_type,
gpointer value,
@@ -105,6 +110,8 @@ GP11Attribute* gp11_attribute_new (gulong attr_type,
GP11Attribute* gp11_attribute_new_invalid (gulong attr_type);
+GP11Attribute* gp11_attribute_new_empty (gulong attr_type);
+
GP11Attribute* gp11_attribute_new_boolean (gulong attr_type,
gboolean value);
@@ -143,13 +150,13 @@ GType gp11_attributes_get_boxed_type (void) G_GNUC_CONST;
GP11Attributes* gp11_attributes_new (void);
-GP11Attributes* gp11_attributes_newv (gulong attr_type, ...);
+GP11Attributes* gp11_attributes_new_empty (gulong attr_type, ...);
-GP11Attributes* gp11_attributes_new_valist (va_list va);
+GP11Attributes* gp11_attributes_new_full (GP11Allocator allocator);
-void gp11_attributes_set_immutable (GP11Attributes *attrs);
+GP11Attributes* gp11_attributes_newv (gulong attr_type, ...);
-gboolean gp11_attributes_is_immutable (GP11Attributes *attrs);
+GP11Attributes* gp11_attributes_new_valist (GP11Allocator allocator, va_list va);
GP11Attribute* gp11_attributes_at (GP11Attributes *attrs,
guint index);
@@ -165,6 +172,9 @@ void gp11_attributes_add_data (GP11Attributes *att
void gp11_attributes_add_invalid (GP11Attributes *attrs,
gulong attr_type);
+void gp11_attributes_add_empty (GP11Attributes *attrs,
+ gulong attr_type);
+
void gp11_attributes_add_boolean (GP11Attributes *attrs,
gulong attr_type,
gboolean value);
@@ -1201,7 +1211,8 @@ GP11Object* gp11_object_from_handle (GP11Slot *slot,
CK_OBJECT_HANDLE handle);
GList* gp11_objects_from_handle_array (GP11Slot *slot,
- const GP11Attribute *attr);
+ CK_OBJECT_HANDLE_PTR handles,
+ CK_ULONG n_handles);
GP11Module* gp11_object_get_module (GP11Object *self);
@@ -1295,14 +1306,12 @@ GP11Attributes* gp11_object_get (GP11Object *self,
...);
GP11Attributes* gp11_object_get_full (GP11Object *self,
- const gulong *attr_types,
- gsize n_attr_types,
+ GP11Attributes *attrs,
GCancellable *cancellable,
GError **err);
void gp11_object_get_async (GP11Object *self,
- const gulong *attr_types,
- gsize n_attr_types,
+ GP11Attributes *attrs,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
@@ -1311,23 +1320,28 @@ GP11Attributes* gp11_object_get_finish (GP11Object *self,
GAsyncResult *result,
GError **err);
-GP11Attribute* gp11_object_get_one (GP11Object *self,
+gpointer gp11_object_get_data (GP11Object *self,
gulong attr_type,
+ gsize *n_data,
GError **err);
-GP11Attribute* gp11_object_get_one_full (GP11Object *self,
+gpointer gp11_object_get_data_full (GP11Object *self,
gulong attr_type,
+ GP11Allocator allocator,
GCancellable *cancellable,
+ gsize *n_data,
GError **err);
-void gp11_object_get_one_async (GP11Object *self,
+void gp11_object_get_data_async (GP11Object *self,
gulong attr_type,
+ GP11Allocator allocator,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
-GP11Attribute* gp11_object_get_one_finish (GP11Object *self,
+gpointer gp11_object_get_data_finish (GP11Object *self,
GAsyncResult *result,
+ gsize *n_data,
GError **err);
diff --git a/gp11/tests/Makefile.am b/gp11/tests/Makefile.am
index f839962c..6cd06fb0 100644
--- a/gp11/tests/Makefile.am
+++ b/gp11/tests/Makefile.am
@@ -1,10 +1,12 @@
+
+# Keep these in the order they should be tested
UNIT_AUTO = \
unit-test-gp11-attributes.c \
- unit-test-gp11-crypto.c \
unit-test-gp11-module.c \
- unit-test-gp11-object.c \
+ unit-test-gp11-slot.c \
unit-test-gp11-session.c \
- unit-test-gp11-slot.c
+ unit-test-gp11-object.c \
+ unit-test-gp11-crypto.c
UNIT_FLAGS = \
-I$(top_srcdir)/gp11/ \
diff --git a/gp11/tests/unit-test-gp11-attributes.c b/gp11/tests/unit-test-gp11-attributes.c
index dfbcdd11..fa34fbf4 100644
--- a/gp11/tests/unit-test-gp11-attributes.c
+++ b/gp11/tests/unit-test-gp11-attributes.c
@@ -77,6 +77,31 @@ DEFINE_TEST(init_string)
gp11_attribute_clear (&attr);
}
+
+DEFINE_TEST(init_invalid)
+{
+ GP11Attribute attr;
+
+ gp11_attribute_init_invalid (&attr, ATTR_TYPE);
+ g_assert (attr.type == ATTR_TYPE);
+ g_assert (attr.length == (gulong)-1);
+ g_assert (attr.value == NULL);
+
+ g_assert (gp11_attribute_is_invalid (&attr));
+ gp11_attribute_clear (&attr);
+}
+
+DEFINE_TEST(init_empty)
+{
+ GP11Attribute attr;
+
+ gp11_attribute_init_empty (&attr, ATTR_TYPE);
+ g_assert (attr.type == ATTR_TYPE);
+ g_assert (attr.length == 0);
+ g_assert (attr.value == NULL);
+
+ gp11_attribute_clear (&attr);
+}
DEFINE_TEST(new_memory)
{
@@ -145,6 +170,32 @@ DEFINE_TEST(new_string)
gp11_attribute_free (attr);
}
+DEFINE_TEST(new_invalid)
+{
+ GP11Attribute *attr;
+
+ attr = gp11_attribute_new_invalid (ATTR_TYPE);
+ g_assert (attr->type == ATTR_TYPE);
+ g_assert (attr->length == (gulong)-1);
+ g_assert (attr->value == NULL);
+
+ g_assert (gp11_attribute_is_invalid (attr));
+
+ gp11_attribute_free (attr);
+}
+
+DEFINE_TEST(new_empty)
+{
+ GP11Attribute *attr;
+
+ attr = gp11_attribute_new_empty (ATTR_TYPE);
+ g_assert (attr->type == ATTR_TYPE);
+ g_assert (attr->length == 0);
+ g_assert (attr->value == NULL);
+
+ gp11_attribute_free (attr);
+}
+
DEFINE_TEST(get_boolean)
{
GP11Attribute *attr;
@@ -243,14 +294,16 @@ DEFINE_TEST(new_attributes)
}
static void
-test_attributes_contents (GP11Attributes *attrs)
+test_attributes_contents (GP11Attributes *attrs, gboolean extras)
{
GP11Attribute *attr;
gchar *value;
GDate date, *check;
+ guint count;
g_assert (attrs != NULL);
- g_assert (gp11_attributes_count (attrs) == 5);
+ count = extras ? 7 : 5;
+ g_assert_cmpuint (gp11_attributes_count (attrs), ==, count);
attr = gp11_attributes_at (attrs, 0);
g_assert (attr->type == 0);
@@ -277,6 +330,20 @@ test_attributes_contents (GP11Attributes *attrs)
g_assert (attr->type == 404);
g_assert (attr->length == N_ATTR_DATA);
g_assert (memcmp (attr->value, ATTR_DATA, N_ATTR_DATA) == 0);
+
+ if (!extras)
+ return;
+
+ attr = gp11_attributes_at (attrs, 5);
+ g_assert (attr->type == 505);
+ g_assert (attr->length == (gulong)-1);
+ g_assert (attr->value == NULL);
+ g_assert (gp11_attribute_is_invalid (attr));
+
+ attr = gp11_attributes_at (attrs, 6);
+ g_assert (attr->type == 606);
+ g_assert (attr->length == 0);
+ g_assert (attr->value == NULL);
}
DEFINE_TEST(newv_attributes)
@@ -291,7 +358,7 @@ DEFINE_TEST(newv_attributes)
-1);
g_date_free (date);
- test_attributes_contents (attrs);
+ test_attributes_contents (attrs, FALSE);
gp11_attributes_unref (attrs);
/* An empty one */
@@ -299,6 +366,21 @@ DEFINE_TEST(newv_attributes)
gp11_attributes_unref (attrs);
}
+DEFINE_TEST(new_empty_attributes)
+{
+ GP11Attributes *attrs = gp11_attributes_new_empty (101, 202, 303, 404, -1);
+ GP11Attribute *attr;
+ guint i;
+
+ g_assert_cmpuint (gp11_attributes_count (attrs), ==, 4);
+ for (i = 0; i < gp11_attributes_count (attrs); ++i) {
+ attr = gp11_attributes_at (attrs, i);
+ g_assert (attr->type == ((i + 1) * 100) + i + 1);
+ g_assert (attr->value == NULL);
+ g_assert (attr->length == 0);
+ }
+}
+
static GP11Attributes*
help_attributes_valist (int dummy, ...)
{
@@ -306,7 +388,7 @@ help_attributes_valist (int dummy, ...)
va_list va;
va_start (va, dummy);
- attrs = gp11_attributes_new_valist (va);
+ attrs = gp11_attributes_new_valist (NULL, va);
va_end (va);
return attrs;
@@ -326,7 +408,7 @@ DEFINE_TEST(new_valist_attributes)
-1);
g_date_free (date);
- test_attributes_contents (attrs);
+ test_attributes_contents (attrs, FALSE);
gp11_attributes_unref (attrs);
}
@@ -354,7 +436,9 @@ DEFINE_TEST(add_data_attributes)
gp11_attributes_add_date (attrs, 303, date);
g_date_free (date);
gp11_attributes_add_data (attrs, 404, ATTR_DATA, N_ATTR_DATA);
- test_attributes_contents (attrs);
+ gp11_attributes_add_invalid (attrs, 505);
+ gp11_attributes_add_empty (attrs, 606);
+ test_attributes_contents (attrs, TRUE);
gp11_attributes_unref (attrs);
}
@@ -387,7 +471,15 @@ DEFINE_TEST(add_attributes)
gp11_attributes_add (attrs, &attr);
gp11_attribute_clear (&attr);
- test_attributes_contents (attrs);
+ gp11_attribute_init_invalid (&attr, 505);
+ gp11_attributes_add (attrs, &attr);
+ gp11_attribute_clear (&attr);
+
+ gp11_attribute_init_empty (&attr, 606);
+ gp11_attributes_add (attrs, &attr);
+ gp11_attribute_clear (&attr);
+
+ test_attributes_contents (attrs, TRUE);
gp11_attributes_unref (attrs);
}
diff --git a/gp11/tests/unit-test-gp11-crypto.c b/gp11/tests/unit-test-gp11-crypto.c
index 752dd432..ff95ce17 100644
--- a/gp11/tests/unit-test-gp11-crypto.c
+++ b/gp11/tests/unit-test-gp11-crypto.c
@@ -51,18 +51,20 @@ find_key (GP11Session *session, CK_ATTRIBUTE_TYPE method, CK_MECHANISM_TYPE mech
{
GList *objects, *l;
GP11Object *object = NULL;
- GP11Attribute *attr;
+ CK_MECHANISM_TYPE_PTR mechs;
+ gsize n_mechs;
objects = gp11_session_find_objects (session, NULL, method, GP11_BOOLEAN, TRUE, GP11_INVALID);
g_assert (objects);
for (l = objects; l; l = g_list_next (l)) {
gp11_object_set_session (l->data, session);
- attr = gp11_object_get_one (l->data, CKA_ALLOWED_MECHANISMS, NULL);
- g_assert (attr);
+ mechs = gp11_object_get_data (l->data, CKA_ALLOWED_MECHANISMS, &n_mechs, NULL);
+ g_assert (mechs);
+ g_assert (n_mechs == sizeof (CK_MECHANISM_TYPE));
/* We know all of them only have one allowed mech */
- if (gp11_attribute_get_ulong (attr) == mech) {
+ if (*mechs == mech) {
object = l->data;
g_object_ref (object);
break;
diff --git a/gp11/tests/unit-test-gp11-object.c b/gp11/tests/unit-test-gp11-object.c
index 1ab73cb3..2345ddb4 100644
--- a/gp11/tests/unit-test-gp11-object.c
+++ b/gp11/tests/unit-test-gp11-object.c
@@ -185,11 +185,10 @@ DEFINE_TEST(destroy_object)
DEFINE_TEST(get_attributes)
{
GAsyncResult *result = NULL;
- GP11Attributes *attrs;
+ GP11Attributes *attrs, *attrs_ret;
GError *err = NULL;
gulong klass;
gchar *value = NULL;
- gulong types[2] = { CKA_CLASS, CKA_LABEL };
/* Simple */
attrs = gp11_object_get (object, &err, CKA_CLASS, CKA_LABEL, -1);
@@ -198,69 +197,78 @@ DEFINE_TEST(get_attributes)
g_assert (gp11_attributes_find_ulong (attrs, CKA_CLASS, &klass) && klass == CKO_DATA);
g_assert (gp11_attributes_find_string (attrs, CKA_LABEL, &value) && strcmp (value, "TEST LABEL") == 0);
g_free (value); value = NULL;
- gp11_attributes_unref (attrs);
}
+ gp11_attributes_unref (attrs);
/* Full */
- attrs = gp11_object_get_full (object, types, 2, NULL, &err);
- SUCCESS_RES (attrs, err);
- if (attrs != NULL) {
+ attrs = gp11_attributes_new_empty (CKA_CLASS, CKA_LABEL, -1);
+ attrs_ret = gp11_object_get_full (object, attrs, NULL, &err);
+ SUCCESS_RES (attrs_ret, err);
+ if (attrs_ret != NULL) {
+ g_assert (attrs_ret == attrs);
g_assert (gp11_attributes_find_ulong (attrs, CKA_CLASS, &klass) && klass == CKO_DATA);
g_assert (gp11_attributes_find_string (attrs, CKA_LABEL, &value) && strcmp (value, "TEST LABEL") == 0);
g_free (value); value = NULL;
- gp11_attributes_unref (attrs);
}
+ gp11_attributes_unref (attrs);
/* Async */
- gp11_object_get_async (object, types, 2, NULL, fetch_async_result, &result);
+ attrs = gp11_attributes_new_empty (CKA_CLASS, CKA_LABEL, -1);
+ gp11_object_get_async (object, attrs, NULL, fetch_async_result, &result);
WAIT_UNTIL (result);
g_assert (result != NULL);
- attrs = gp11_object_get_finish (object, result, &err);
+ attrs_ret = gp11_object_get_finish (object, result, &err);
g_object_unref (result);
SUCCESS_RES (attrs, err);
if (attrs != NULL) {
+ g_assert (attrs_ret == attrs);
g_assert (gp11_attributes_find_ulong (attrs, CKA_CLASS, &klass) && klass == CKO_DATA);
g_assert (gp11_attributes_find_string (attrs, CKA_LABEL, &value) && strcmp (value, "TEST LABEL") == 0);
g_free (value); value = NULL;
- gp11_attributes_unref (attrs);
}
+ gp11_attributes_unref (attrs);
}
-DEFINE_TEST(get_one_attribute)
+DEFINE_TEST(get_data_attribute)
{
GAsyncResult *result = NULL;
- GP11Attribute *attr;
+ CK_OBJECT_CLASS_PTR klass;
+ gsize n_data;
GError *err = NULL;
/* Simple */
- attr = gp11_object_get_one (object, CKA_CLASS, &err);
- SUCCESS_RES (attr, err);
- if (attr != NULL) {
- g_assert (attr->type == CKA_CLASS && gp11_attribute_get_ulong (attr) == CKO_DATA);
- gp11_attribute_free (attr);
+ klass = gp11_object_get_data (object, CKA_CLASS, &n_data, &err);
+ SUCCESS_RES (klass, err);
+ if (klass != NULL) {
+ g_assert (n_data == sizeof (CK_OBJECT_CLASS));
+ g_assert (*klass == CKO_DATA);
+ g_free (klass);
}
/* Full */
- attr = gp11_object_get_one_full (object, CKA_CLASS, NULL, &err);
- SUCCESS_RES (attr, err);
- if (attr != NULL) {
- g_assert (attr->type == CKA_CLASS && gp11_attribute_get_ulong (attr) == CKO_DATA);
- gp11_attribute_free (attr);
+ klass = gp11_object_get_data_full (object, CKA_CLASS, NULL, NULL, &n_data, &err);
+ SUCCESS_RES (klass, err);
+ if (klass != NULL) {
+ g_assert (n_data == sizeof (CK_OBJECT_CLASS));
+ g_assert (*klass == CKO_DATA);
+ g_free (klass);
}
/* Async */
- gp11_object_get_one_async (object, CKA_CLASS, NULL, fetch_async_result, &result);
+ gp11_object_get_data_async (object, CKA_CLASS, NULL, NULL, fetch_async_result, &result);
WAIT_UNTIL (result);
g_assert (result != NULL);
- attr = gp11_object_get_one_finish (object, result, &err);
+ klass = gp11_object_get_data_finish (object, result, &n_data, &err);
g_object_unref (result);
- SUCCESS_RES (attr, err);
- if (attr != NULL) {
- g_assert (attr->type == CKA_CLASS && gp11_attribute_get_ulong (attr) == CKO_DATA);
- gp11_attribute_free (attr);
+ SUCCESS_RES (klass, err);
+ if (klass != NULL) {
+ g_assert (n_data == sizeof (CK_OBJECT_CLASS));
+ g_assert (*klass == CKO_DATA);
+ g_free (klass);
}
+
}
DEFINE_TEST(set_attributes)
@@ -372,11 +380,9 @@ DEFINE_TEST(explicit_sessions)
{
GP11Session *sess;
GAsyncResult *result = NULL;
- GP11Attributes *attrs;
+ CK_OBJECT_CLASS_PTR klass;
GError *err = NULL;
- gulong klass;
- gchar *value = NULL;
- gulong types[2] = { CKA_CLASS, CKA_LABEL };
+ gsize n_data;
/* Set an explicit session */
gp11_object_set_session (object, session);
@@ -388,28 +394,26 @@ DEFINE_TEST(explicit_sessions)
g_object_unref (sess);
/* Simple */
- attrs = gp11_object_get (object, &err, CKA_CLASS, CKA_LABEL, -1);
- SUCCESS_RES (attrs, err);
- if (attrs != NULL) {
- g_assert (gp11_attributes_find_ulong (attrs, CKA_CLASS, &klass) && klass == CKO_DATA);
- g_assert (gp11_attributes_find_string (attrs, CKA_LABEL, &value) && strcmp (value, "TEST LABEL") == 0);
- g_free (value); value = NULL;
- gp11_attributes_unref (attrs);
+ klass = gp11_object_get_data (object, CKA_CLASS, &n_data, &err);
+ SUCCESS_RES (klass, err);
+ if (klass != NULL) {
+ g_assert (n_data == sizeof (CK_OBJECT_CLASS));
+ g_assert (*klass == CKO_DATA);
+ g_free (klass);
}
/* Async */
- gp11_object_get_async (object, types, 2, NULL, fetch_async_result, &result);
+ gp11_object_get_data_async (object, CKA_CLASS, NULL, NULL, fetch_async_result, &result);
WAIT_UNTIL (result);
g_assert (result != NULL);
- attrs = gp11_object_get_finish (object, result, &err);
+ klass = gp11_object_get_data_finish (object, result, &n_data, &err);
g_object_unref (result);
- SUCCESS_RES (attrs, err);
- if (attrs != NULL) {
- g_assert (gp11_attributes_find_ulong (attrs, CKA_CLASS, &klass) && klass == CKO_DATA);
- g_assert (gp11_attributes_find_string (attrs, CKA_LABEL, &value) && strcmp (value, "TEST LABEL") == 0);
- g_free (value); value = NULL;
- gp11_attributes_unref (attrs);
+ SUCCESS_RES (klass, err);
+ if (klass != NULL) {
+ g_assert (n_data == sizeof (CK_OBJECT_CLASS));
+ g_assert (*klass == CKO_DATA);
+ g_free (klass);
}
/* Set it to null and make sure taht works */
diff --git a/tool/gkr-tool-import.c b/tool/gkr-tool-import.c
index 1976767a..685b70a5 100644
--- a/tool/gkr-tool-import.c
+++ b/tool/gkr-tool-import.c
@@ -55,8 +55,8 @@ print_object_information (GP11Object *object)
GError *err = NULL;
gchar *label;
- attrs = gp11_object_get_full (object, ATTR_TYPES, G_N_ELEMENTS(ATTR_TYPES), NULL, &err);
- if(!attrs) {
+ attrs = gp11_attributes_new_empty (CKA_LABEL, CKA_CLASS, CKA_ID, -1);
+ if (!gp11_object_get_full (object, attrs, NULL, &err)) {
gkr_tool_handle_error (&err, "couldn't get imported object info");
return;
}
@@ -115,18 +115,27 @@ print_object_information (GP11Object *object)
static void
print_import_information (GP11Session *session, GP11Object *import)
{
- GP11Attribute *attr;
+ CK_OBJECT_HANDLE_PTR handles;
+ CK_ULONG n_handles;
+ gsize length;
GList *objects, *l;
+ GP11Slot *slot;
GError *err;
- attr = gp11_object_get_one (import, CKA_GNOME_IMPORT_OBJECTS, &err);
- if (!attr) {
+ handles = gp11_object_get_data (import, CKA_GNOME_IMPORT_OBJECTS, &length, &err);
+ if (!handles) {
gkr_tool_handle_error (&err, "couldn't find imported objects");
return;
}
+
+ n_handles = length / sizeof (CK_OBJECT_HANDLE);
+
+ slot = gp11_session_get_slot (session);
+ g_return_if_fail (slot);
- objects = gp11_objects_from_handle_array (session, attr);
- gp11_attribute_free (attr);
+ objects = gp11_objects_from_handle_array (slot, handles, n_handles);
+ g_free (handles);
+ g_object_unref (slot);
for (l = objects; l; l = g_list_next (l))
print_object_information (GP11_OBJECT (l->data));