diff options
author | Stefan Walter <stefw@src.gnome.org> | 2008-12-30 02:18:02 +0000 |
---|---|---|
committer | Stefan Walter <stefw@src.gnome.org> | 2008-12-30 02:18:02 +0000 |
commit | e4bc09c74100a5d9165d35fa4db51c642d0091f7 (patch) | |
tree | 82ddf6e1963553b1cb9f2b0a86574a9b4dfd9ed4 | |
parent | 64ed69dced12b3f6cabb143a195334711486bea1 (diff) | |
download | gnome-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-- | ChangeLog | 16 | ||||
-rw-r--r-- | gp11/gp11-attributes.c | 425 | ||||
-rw-r--r-- | gp11/gp11-object.c | 423 | ||||
-rw-r--r-- | gp11/gp11-private.h | 19 | ||||
-rw-r--r-- | gp11/gp11-session.c | 62 | ||||
-rw-r--r-- | gp11/gp11.h | 42 | ||||
-rw-r--r-- | gp11/tests/Makefile.am | 8 | ||||
-rw-r--r-- | gp11/tests/unit-test-gp11-attributes.c | 106 | ||||
-rw-r--r-- | gp11/tests/unit-test-gp11-crypto.c | 10 | ||||
-rw-r--r-- | gp11/tests/unit-test-gp11-object.c | 98 | ||||
-rw-r--r-- | tool/gkr-tool-import.c | 23 |
11 files changed, 897 insertions, 335 deletions
@@ -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)); |