[gcr] gck: Add floating references to GckAttributes



commit 411cc74ad88cfe1fee0ad58b05338b408fe8622b
Author: Stef Walter <stefw collabora co uk>
Date:   Wed Dec 7 17:52:31 2011 +0100

    gck: Add floating references to GckAttributes
    
     * Allows us more flexibility in our API in the future
     * Simplifies the common case of generating a set of attributes
       and directly passing it to a gck function

 gck/gck-attributes.c                   |   60 ++++++++++++++++++++++++++++++--
 gck/gck-enumerator.c                   |    2 +-
 gck/gck-mock.c                         |   33 ++++++++++-------
 gck/gck-mock.h                         |    2 +-
 gck/gck-modules.c                      |    2 +-
 gck/gck-object-attributes.c            |    5 +++
 gck/gck-object.c                       |   20 +++++++---
 gck/gck-session.c                      |   32 +++++++++++++----
 gck/gck-slot.c                         |    2 +-
 gck/gck-uri.c                          |    2 +-
 gck/gck.h                              |    2 +
 gck/gck.symbols                        |    1 +
 gck/tests/test-gck-crypto.c            |   18 +++------
 gck/tests/test-gck-enumerator.c        |   13 +++----
 gck/tests/test-gck-modules.c           |    5 +--
 gck/tests/test-gck-object.c            |   35 +++++-------------
 gck/tests/test-gck-session.c           |    2 +-
 gck/tests/test-gck-uri.c               |   10 +++---
 gcr/gcr-certificate-renderer.c         |    5 +--
 gcr/gcr-certificate-request-renderer.c |    9 +----
 gcr/gcr-gnupg-importer.c               |    5 +--
 gcr/gcr-gnupg-renderer.c               |    5 +--
 gcr/gcr-key-renderer.c                 |    5 +--
 gcr/gcr-openssh.c                      |    4 +-
 gcr/gcr-parser.c                       |    2 +-
 gcr/gcr-pkcs11-certificate.c           |    2 +-
 gcr/gcr-pkcs11-importer.c              |   23 ++++--------
 gcr/gcr-renderer.c                     |    2 +-
 gcr/gcr-subject-public-key.c           |   10 ++----
 gcr/gcr-trust.c                        |   15 ++++----
 gcr/tests/test-certificate-chain.c     |    6 ++--
 gcr/tests/test-fingerprint.c           |    2 +-
 gcr/tests/test-pkcs11-certificate.c    |    2 +-
 gcr/tests/test-subject-public-key.c    |   10 +++---
 gcr/tests/test-trust.c                 |    2 +-
 35 files changed, 197 insertions(+), 158 deletions(-)
---
diff --git a/gck/gck-attributes.c b/gck/gck-attributes.c
index a48e44f..d32e2cb 100644
--- a/gck/gck-attributes.c
+++ b/gck/gck-attributes.c
@@ -53,10 +53,14 @@
 
 G_STATIC_ASSERT (sizeof (GckAttribute) == sizeof (CK_ATTRIBUTE));
 
+#define STATE_LOCKED     1
+#define STATE_FLOATING   8
+
 struct _GckAttributes {
 	GckAttribute *data;
 	gulong count;
 	gint refs;
+	gint state;
 };
 
 typedef struct {
@@ -835,6 +839,18 @@ gck_builder_find_date (GckBuilder *builder,
 	                            real->array->len, attr_type, value);
 }
 
+/**
+ * gck_builder_steal:
+ * @builder: the builder
+ *
+ * Take the attributes that have been built in the #GckBuilder. The builder
+ * will no longer contain any attributes after this function call.
+ *
+ * The returned set of attributes is a full reference, not floating.
+ *
+ * Returns: (transfer full): the stolen attributes, which should be freed with
+ *          gck_attributes_unref()
+ */
 GckAttributes *
 gck_builder_steal (GckBuilder *builder)
 {
@@ -862,16 +878,35 @@ gck_builder_steal (GckBuilder *builder)
 	return attrs;
 }
 
+/**
+ * gck_builder_end:
+ * @builder: the builder
+ *
+ * Complete the #GckBuilder, and return the attributes contained in the builder.
+ * The #GckBuilder will be cleared after this function call, and it is no
+ * longer necessary to use gck_builder_clear() on it, although it is also
+ * permitted.
+ *
+ * The returned set of attributes is floating, and should either be passed to
+ * another gck library function which consumes this floating reference, or if
+ * you wish to keep these attributes around you should ref them with
+ * gck_attributes_ref_sink() and unref them later with gck_attributes_unref().
+ *
+ * Returns: (transfer none): a floating reference to the attributes created
+ *          in the builder
+ */
 GckAttributes *
 gck_builder_end (GckBuilder *builder)
 {
+	GckRealBuilder *real = (GckRealBuilder *)builder;
 	GckAttributes *attrs;
 
 	g_return_val_if_fail (builder != NULL, NULL);
 
 	attrs = gck_builder_steal (builder);
-	gck_builder_clear (builder);
+	attrs->state |= STATE_FLOATING;
 
+	g_assert (real->array == NULL);
 	return attrs;
 }
 
@@ -1589,8 +1624,12 @@ gck_attributes_get_boxed_type (void)
  *
  * Creates an GckAttributes array with no attributes.
  *
- * Returns: (transfer full): the new attributes array; when done with the array
- *          release it with gck_attributes_unref()
+ * The returned set of attributes is floating, and should either be passed to
+ * another gck library function which consumes this floating reference, or if
+ * you wish to keep these attributes around you should ref them with
+ * gck_attributes_ref_sink() and unref them later with gck_attributes_unref().
+ *
+ * Returns: (transfer none): a floating reference to an empty set of attributes
  **/
 GckAttributes *
 gck_attributes_new_empty (void)
@@ -1758,6 +1797,21 @@ gck_attributes_ref (GckAttributes *attrs)
 	return attrs;
 }
 
+GckAttributes *
+gck_attributes_ref_sink (GckAttributes *attrs)
+{
+	g_return_val_if_fail (attrs, NULL);
+	g_bit_lock (&attrs->state, STATE_LOCKED);
+
+	if (~attrs->state & STATE_FLOATING)
+		gck_attributes_ref (attrs);
+	else
+		attrs->state &= ~STATE_FLOATING;
+
+	g_bit_unlock (&attrs->state, STATE_LOCKED);
+	return attrs;
+}
+
 /**
  * gck_attributes_unref:
  * @attrs: An attribute array
diff --git a/gck/gck-enumerator.c b/gck/gck-enumerator.c
index f4573b5..0d37e7b 100644
--- a/gck/gck-enumerator.c
+++ b/gck/gck-enumerator.c
@@ -534,7 +534,7 @@ state_results (GckEnumeratorState *args,
 			rv = (args->funcs->C_GetAttributeValue) (session, result->handle, template, n_template);
 		}
 
-		attrs = gck_builder_end (&builder);
+		attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 		if (GCK_IS_GET_ATTRIBUTE_RV_OK (rv)) {
 			if (_gck_debugging) {
diff --git a/gck/gck-mock.c b/gck/gck-mock.c
index 4ee90d5..1f5325c 100644
--- a/gck/gck-mock.c
+++ b/gck/gck-mock.c
@@ -119,7 +119,7 @@ lookup_object (Session *session,
 }
 
 CK_OBJECT_HANDLE
-gck_mock_module_take_object (GckAttributes *attrs)
+gck_mock_module_add_object (GckAttributes *attrs)
 {
 	GckBuilder builder;
 	gboolean token;
@@ -127,17 +127,20 @@ gck_mock_module_take_object (GckAttributes *attrs)
 
 	g_return_val_if_fail (the_objects, 0);
 
+
 	handle = ++unique_identifier;
 	if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token)) {
 		g_return_val_if_fail (token == TRUE, 0);
+		gck_attributes_ref_sink (attrs);
 	} else {
 		gck_builder_init (&builder);
 		gck_builder_add_except (&builder, attrs, CKA_TOKEN, GCK_INVALID);
 		gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE);
 		gck_attributes_unref (attrs);
-		attrs = gck_builder_end (&builder);
+		attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 	}
 	g_hash_table_insert (the_objects, GUINT_TO_POINTER (handle), attrs);
+
 	return handle;
 }
 
@@ -243,7 +246,7 @@ replace_attributes (GckAttributes *atts,
 	gulong *types;
 
 	if (!n_attrs)
-		return gck_attributes_ref (atts);
+		return gck_attributes_ref_sink (atts);
 
 	gck_builder_init (&builder);
 	types = g_new0 (gulong, n_attrs);
@@ -254,7 +257,7 @@ replace_attributes (GckAttributes *atts,
 	}
 	gck_builder_add_exceptv (&builder, atts, types, n_attrs);
 	g_free (types);
-	return gck_builder_end (&builder);
+	return gck_attributes_ref_sink (gck_builder_end (&builder));
 }
 
 void
@@ -317,7 +320,8 @@ gck_mock_C_Initialize (CK_VOID_PTR pInitArgs)
 	gck_builder_init (&builder);
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_DATA);
 	gck_builder_add_string (&builder, CKA_LABEL, "TEST LABEL");
-	g_hash_table_insert (the_objects, GUINT_TO_POINTER (2), gck_builder_end (&builder));
+	g_hash_table_insert (the_objects, GUINT_TO_POINTER (2),
+	                     gck_attributes_ref_sink (gck_builder_end (&builder)));
 
 	/* Private capitalize key */
 	value = CKM_MOCK_CAPITALIZE;
@@ -331,7 +335,8 @@ gck_mock_C_Initialize (CK_VOID_PTR pInitArgs)
 	gck_builder_add_boolean (&builder, CKA_DERIVE, CK_TRUE);
 	gck_builder_add_string (&builder, CKA_VALUE, "value");
 	gck_builder_add_string (&builder, CKA_GNOME_UNIQUE, "unique1");
-	g_hash_table_insert (the_objects, GUINT_TO_POINTER (PRIVATE_KEY_CAPITALIZE), gck_builder_end (&builder));
+	g_hash_table_insert (the_objects, GUINT_TO_POINTER (PRIVATE_KEY_CAPITALIZE),
+	                     gck_attributes_ref_sink (gck_builder_end (&builder)));
 
 	/* Public capitalize key */
 	value = CKM_MOCK_CAPITALIZE;
@@ -354,7 +359,8 @@ gck_mock_C_Initialize (CK_VOID_PTR pInitArgs)
 	gck_builder_add_boolean (&builder, CKA_ALWAYS_AUTHENTICATE, CK_TRUE);
 	gck_builder_add_string (&builder, CKA_VALUE, "value");
 	gck_builder_add_string (&builder, CKA_GNOME_UNIQUE, "unique3");
-	g_hash_table_insert (the_objects, GUINT_TO_POINTER (PRIVATE_KEY_PREFIX), gck_builder_end (&builder));
+	g_hash_table_insert (the_objects, GUINT_TO_POINTER (PRIVATE_KEY_PREFIX),
+	                     gck_attributes_ref_sink (gck_builder_end (&builder)));
 
 	/* Private prefix key */
 	value = CKM_MOCK_PREFIX;
@@ -365,7 +371,8 @@ gck_mock_C_Initialize (CK_VOID_PTR pInitArgs)
 	gck_builder_add_boolean (&builder, CKA_PRIVATE, CK_FALSE);
 	gck_builder_add_string (&builder, CKA_VALUE, "value");
 	gck_builder_add_string (&builder, CKA_GNOME_UNIQUE, "unique4");
-	g_hash_table_insert (the_objects, GUINT_TO_POINTER (PUBLIC_KEY_PREFIX), gck_builder_end (&builder));
+	g_hash_table_insert (the_objects, GUINT_TO_POINTER (PUBLIC_KEY_PREFIX),
+	                     gck_attributes_ref_sink (gck_builder_end (&builder)));
 
 	logged_in = FALSE;
 	initialized = TRUE;
@@ -861,7 +868,7 @@ gck_mock_C_CreateObject (CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate,
 	for (i = 0; i < ulCount; ++i)
 		gck_builder_add_data (&builder, pTemplate[i].type, pTemplate[i].pValue, pTemplate[i].ulValueLen);
 
-	attrs = gck_builder_end (&builder);
+	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 	if (gck_attributes_find_boolean (attrs, CKA_PRIVATE, &priv) && priv) {
 		if (!logged_in) {
 			gck_attributes_unref (attrs);
@@ -1587,7 +1594,7 @@ gck_mock_unsupported_C_GenerateKeyPair (CK_SESSION_HANDLE hSession, CK_MECHANISM
 		                         pPublicKeyTemplate[i].pValue,
 		                         pPublicKeyTemplate[i].ulValueLen);
 	*phPublicKey = ++unique_identifier;
-	attrs = gck_builder_end (&builder);
+	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 	if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token) && token)
 		g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phPublicKey), attrs);
 	else
@@ -1600,7 +1607,7 @@ gck_mock_unsupported_C_GenerateKeyPair (CK_SESSION_HANDLE hSession, CK_MECHANISM
 		                         pPrivateKeyTemplate[i].pValue,
 		                         pPrivateKeyTemplate[i].ulValueLen);
 	*phPrivateKey = ++unique_identifier;
-	attrs = gck_builder_end (&builder);
+	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 	if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token) && token)
 		g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phPrivateKey), attrs);
 	else
@@ -1702,7 +1709,7 @@ gck_mock_unsupported_C_UnwrapKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR p
 		                         pTemplate[i].pValue,
 		                         pTemplate[i].ulValueLen);
 	*phKey = ++unique_identifier;
-	attrs = gck_builder_end (&builder);
+	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 	if (gck_attributes_find_boolean (attrs, CKA_TOKEN, &token) && token)
 		g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phKey), attrs);
 	else
@@ -1750,7 +1757,7 @@ gck_mock_unsupported_C_DeriveKey (CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR p
 		                      pTemplate[i].ulValueLen);
 	gck_builder_add_all (&builder, attrs);
 	*phKey = ++unique_identifier;
-	copy = gck_builder_end (&builder);
+	copy = gck_attributes_ref_sink (gck_builder_end (&builder));
 	if (gck_attributes_find_boolean (copy, CKA_TOKEN, &token) && token)
 		g_hash_table_insert (the_objects, GUINT_TO_POINTER (*phKey), copy);
 	else
diff --git a/gck/gck-mock.h b/gck/gck-mock.h
index 99ad166..bd30b79 100644
--- a/gck/gck-mock.h
+++ b/gck/gck-mock.h
@@ -376,7 +376,7 @@ void                gck_mock_module_enumerate_objects              (CK_SESSION_H
                                                                     GckMockEnumerator func,
                                                                     gpointer user_data);
 
-CK_OBJECT_HANDLE    gck_mock_module_take_object                    (GckAttributes *attrs);
+CK_OBJECT_HANDLE    gck_mock_module_add_object                     (GckAttributes *attrs);
 
 void                gck_mock_module_set_object                     (CK_OBJECT_HANDLE object,
                                                                     CK_ATTRIBUTE_PTR attrs,
diff --git a/gck/gck-modules.c b/gck/gck-modules.c
index 37518ac..2cc821b 100644
--- a/gck/gck-modules.c
+++ b/gck/gck-modules.c
@@ -216,7 +216,7 @@ gck_modules_enumerate_objects (GList *modules,
 	g_return_val_if_fail (attrs, NULL);
 
 	uri_data = gck_uri_data_new ();
-	uri_data->attributes = gck_attributes_ref (attrs);
+	uri_data->attributes = gck_attributes_ref_sink (attrs);
 
 	return _gck_enumerator_new_for_modules (modules, session_options, uri_data);
 }
diff --git a/gck/gck-object-attributes.c b/gck/gck-object-attributes.c
index fad6055..b8ee1bf 100644
--- a/gck/gck-object-attributes.c
+++ b/gck/gck-object-attributes.c
@@ -102,5 +102,10 @@ gck_object_attributes_set_attributes (GckObjectAttributes *object,
                                       GckAttributes *attributes)
 {
 	g_return_if_fail (GCK_IS_OBJECT_ATTRIBUTES (object));
+
+	gck_attributes_ref_sink (attributes);
+
 	g_object_set (object, "attributes", attributes, NULL);
+
+	gck_attributes_unref (attributes);
 }
diff --git a/gck/gck-object.c b/gck/gck-object.c
index 4b86984..0052393 100644
--- a/gck/gck-object.c
+++ b/gck/gck-object.c
@@ -524,8 +524,12 @@ gck_object_set (GckObject *self, GckAttributes *attrs,
 	args.attrs = attrs;
 	args.object = self->pv->handle;
 
+	gck_attributes_ref_sink (attrs);
+
 	ret = _gck_call_sync (self->pv->session, perform_set_attributes, NULL, &args, cancellable, error);
 
+	gck_attributes_unref (attrs);
+
 	return ret;
 }
 
@@ -552,7 +556,7 @@ gck_object_set_async (GckObject *self, GckAttributes *attrs, GCancellable *cance
 	args = _gck_call_async_prep (self->pv->session, self, perform_set_attributes,
 	                             NULL, sizeof (*args), free_set_attributes);
 
-	args->attrs = gck_attributes_ref (attrs);
+	args->attrs = gck_attributes_ref_sink (attrs);
 	args->object = self->pv->handle;
 
 	_gck_call_async_ready_go (args, cancellable, callback, user_data);
@@ -718,7 +722,7 @@ gck_object_get_full (GckObject *self,
 	ret = _gck_call_sync (self->pv->session, perform_get_attributes, NULL, &args, cancellable, error);
 
 	if (ret) {
-		return gck_builder_end (&args.builder);
+		return gck_attributes_ref_sink (gck_builder_end (&args.builder));
 	} else {
 		gck_builder_clear (&args.builder);
 		return NULL;
@@ -794,7 +798,7 @@ gck_object_get_finish (GckObject *self, GAsyncResult *result, GError **error)
 	if (!_gck_call_basic_finish (result, error))
 		return NULL;
 
-	return gck_builder_end (&args->builder);
+	return gck_attributes_ref_sink (gck_builder_end (&args->builder));
 }
 
 /* ---------------------------------------------------------------------------------
@@ -1073,8 +1077,12 @@ gck_object_set_template (GckObject *self, gulong attr_type, GckAttributes *attrs
 	args.type = attr_type;
 	args.object = self->pv->handle;
 
+	gck_attributes_ref_sink (attrs);
+
 	ret = _gck_call_sync (self->pv->session, perform_set_template, NULL, &args, cancellable, error);
 
+	gck_attributes_unref (attrs);
+
 	return ret;
 }
 
@@ -1105,7 +1113,7 @@ gck_object_set_template_async (GckObject *self, gulong attr_type, GckAttributes
 	args = _gck_call_async_prep (self->pv->session, self, perform_set_template,
 	                             NULL, sizeof (*args), free_set_template);
 
-	args->attrs = gck_attributes_ref (attrs);
+	args->attrs = gck_attributes_ref_sink (attrs);
 	args->type = attr_type;
 	args->object = self->pv->handle;
 
@@ -1234,7 +1242,7 @@ gck_object_get_template (GckObject *self, gulong attr_type,
 		return NULL;
 	}
 
-	return gck_builder_end (&args.builder);
+	return gck_attributes_ref_sink (gck_builder_end (&args.builder));
 }
 
 /**
@@ -1294,5 +1302,5 @@ gck_object_get_template_finish (GckObject *self, GAsyncResult *result,
 		return NULL;
 
 	args = _gck_call_arguments (result, get_template_args);
-	return gck_builder_end (&args->builder);
+	return gck_attributes_ref_sink (gck_builder_end (&args->builder));
 }
diff --git a/gck/gck-session.c b/gck/gck-session.c
index 6fc0266..055c193 100644
--- a/gck/gck-session.c
+++ b/gck/gck-session.c
@@ -1431,7 +1431,9 @@ gck_session_create_object (GckSession *self, GckAttributes *attrs,
 	g_return_val_if_fail (GCK_IS_SESSION (self), NULL);
 	g_return_val_if_fail (attrs != NULL, NULL);
 
+	gck_attributes_ref_sink (attrs);
 	ret = _gck_call_sync (self, perform_create_object, NULL, &args, cancellable, error);
+	gck_attributes_unref (attrs);
 
 	if (!ret)
 		return NULL;
@@ -1460,7 +1462,7 @@ gck_session_create_object_async (GckSession *self, GckAttributes *attrs,
 
 	g_return_if_fail (attrs);
 
-	args->attrs = gck_attributes_ref (attrs);
+	args->attrs = gck_attributes_ref_sink (attrs);
 
 	_gck_call_async_ready_go (args, cancellable, callback, user_data);
 }
@@ -1599,11 +1601,13 @@ gck_session_find_handles (GckSession *self,
 	g_return_val_if_fail (n_handles != NULL, NULL);
 	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
+	gck_attributes_ref_sink (match);
 	if (_gck_call_sync (self, perform_find_objects, NULL, &args, cancellable, error)) {
 		results = args.objects;
 		*n_handles = args.n_objects;
 		args.objects = NULL;
 	}
+	gck_attributes_unref (match);
 
 	g_free (args.objects);
 	return results;
@@ -1635,7 +1639,7 @@ gck_session_find_handles_async (GckSession *self,
 
 	args = _gck_call_async_prep (self, self, perform_find_objects,
 	                             NULL, sizeof (*args), free_find_objects);
-	args->attrs = gck_attributes_ref (match);
+	args->attrs = gck_attributes_ref_sink (match);
 	_gck_call_async_ready_go (args, cancellable, callback, user_data);
 }
 
@@ -1789,7 +1793,7 @@ gck_session_enumerate_objects (GckSession *session,
 	g_return_val_if_fail (match != NULL, NULL);
 
 	uri_data = gck_uri_data_new ();
-	uri_data->attributes = gck_attributes_ref (match);
+	uri_data->attributes = gck_attributes_ref_sink (match);
 
 	return _gck_enumerator_new_for_session (session, uri_data);
 }
@@ -1897,8 +1901,14 @@ gck_session_generate_key_pair_full (GckSession *self,
 	/* Shallow copy of the mechanism structure */
 	memcpy (&args.mechanism, mechanism, sizeof (args.mechanism));
 
+	gck_attributes_ref_sink (public_attrs);
+	gck_attributes_ref_sink (private_attrs);
+
 	ret = _gck_call_sync (self, perform_generate_key_pair, NULL, &args, cancellable, error);
 
+	gck_attributes_unref (private_attrs);
+	gck_attributes_unref (public_attrs);
+
 	if (!ret)
 		return FALSE;
 
@@ -1939,8 +1949,8 @@ gck_session_generate_key_pair_async (GckSession *self, GckMechanism *mechanism,
 	/* Shallow copy of the mechanism structure */
 	memcpy (&args->mechanism, mechanism, sizeof (args->mechanism));
 
-	args->public_attrs = gck_attributes_ref (public_attrs);
-	args->private_attrs = gck_attributes_ref (private_attrs);
+	args->public_attrs = gck_attributes_ref_sink (public_attrs);
+	args->private_attrs = gck_attributes_ref_sink (private_attrs);
 
 	_gck_call_async_ready_go (args, cancellable, callback, user_data);
 }
@@ -2278,8 +2288,12 @@ gck_session_unwrap_key_full (GckSession *self,
 	g_object_get (wrapper, "handle", &args.wrapper, NULL);
 	g_return_val_if_fail (args.wrapper != 0, NULL);
 
+	gck_attributes_ref_sink (attrs);
+
 	ret = _gck_call_sync (self, perform_unwrap_key, NULL, &args, cancellable, error);
 
+	gck_attributes_unref (attrs);
+
 	if (!ret)
 		return NULL;
 
@@ -2325,7 +2339,7 @@ gck_session_unwrap_key_async (GckSession *self,
 	/* Shallow copy of the mechanism structure */
 	memcpy (&args->mechanism, mechanism, sizeof (args->mechanism));
 
-	args->attrs = gck_attributes_ref (attrs);
+	args->attrs = gck_attributes_ref_sink (attrs);
 	args->input = input;
 	args->n_input = n_input;
 
@@ -2448,8 +2462,12 @@ gck_session_derive_key_full (GckSession *self, GckObject *base, GckMechanism *me
 	g_object_get (base, "handle", &args.key, NULL);
 	g_return_val_if_fail (args.key != 0, NULL);
 
+	gck_attributes_ref_sink (attrs);
+
 	ret = _gck_call_sync (self, perform_derive_key, NULL, &args, cancellable, error);
 
+	gck_attributes_unref (attrs);
+
 	if (!ret)
 		return NULL;
 
@@ -2487,7 +2505,7 @@ gck_session_derive_key_async (GckSession *self, GckObject *base, GckMechanism *m
 	/* Shallow copy of the mechanism structure */
 	memcpy (&args->mechanism, mechanism, sizeof (args->mechanism));
 
-	args->attrs = gck_attributes_ref (attrs);
+	args->attrs = gck_attributes_ref_sink (attrs);
 
 	_gck_call_async_ready_go (args, cancellable, callback, user_data);
 }
diff --git a/gck/gck-slot.c b/gck/gck-slot.c
index f55fb50..7ad1f5a 100644
--- a/gck/gck-slot.c
+++ b/gck/gck-slot.c
@@ -932,7 +932,7 @@ gck_slots_enumerate_objects (GList *slots,
 	g_return_val_if_fail (match != NULL, NULL);
 
 	uri_data = gck_uri_data_new ();
-	uri_data->attributes = gck_attributes_ref (match);
+	uri_data->attributes = gck_attributes_ref_sink (match);
 
 	return _gck_enumerator_new_for_slots (slots, options, uri_data);
 }
diff --git a/gck/gck-uri.c b/gck/gck-uri.c
index cf9707b..d8665fa 100644
--- a/gck/gck-uri.c
+++ b/gck/gck-uri.c
@@ -253,7 +253,7 @@ gck_uri_parse (const gchar *string, GckUriFlags flags, GError **error)
 		gck_builder_init (&builder);
 		for (i = 0; i < n_attrs; ++i)
 			gck_builder_add_data (&builder, attrs[i].type, attrs[i].pValue, attrs[i].ulValueLen);
-		uri_data->attributes = gck_builder_end (&builder);
+		uri_data->attributes = gck_attributes_ref_sink (gck_builder_end (&builder));
 	}
 	uri_data->any_unrecognized = p11_kit_uri_any_unrecognized (p11_uri);
 
diff --git a/gck/gck.h b/gck/gck.h
index cbea1c5..c4a5bbf 100644
--- a/gck/gck.h
+++ b/gck/gck.h
@@ -368,6 +368,8 @@ gulong               gck_attributes_count                   (GckAttributes *attr
 
 GckAttributes *      gck_attributes_ref                     (GckAttributes *attrs);
 
+GckAttributes *      gck_attributes_ref_sink                (GckAttributes *attrs);
+
 void                 gck_attributes_unref                   (gpointer attrs);
 
 gboolean             gck_attributes_contains                (GckAttributes *attrs,
diff --git a/gck/gck.symbols b/gck/gck.symbols
index 69b8ff0..9cd3f94 100644
--- a/gck/gck.symbols
+++ b/gck/gck.symbols
@@ -42,6 +42,7 @@ gck_attributes_get_boxed_type
 gck_attributes_get_type
 gck_attributes_new_empty
 gck_attributes_ref
+gck_attributes_ref_sink
 gck_attributes_to_string
 gck_attributes_unref
 gck_builder_add_all
diff --git a/gck/tests/test-gck-crypto.c b/gck/tests/test-gck-crypto.c
index 8a8914d..d26ccf9 100644
--- a/gck/tests/test-gck-crypto.c
+++ b/gck/tests/test-gck-crypto.c
@@ -104,16 +104,13 @@ find_key (GckSession *session, CK_ATTRIBUTE_TYPE method, CK_MECHANISM_TYPE mech)
 {
 	GckBuilder builder = GCK_BUILDER_INIT;
 	GList *objects, *l;
-	GckAttributes *attrs;
 	GckObject *object = NULL;
 	CK_MECHANISM_TYPE_PTR mechs;
 	gboolean match;
 	gsize n_mechs;
 
 	gck_builder_add_boolean (&builder, method, TRUE);
-	attrs = gck_builder_end (&builder);
-	objects = gck_session_find_objects (session, attrs, NULL, NULL);
-	gck_attributes_unref (attrs);
+	objects = gck_session_find_objects (session, gck_builder_end (&builder), NULL, NULL);
 	g_assert (objects);
 
 	for (l = objects; l; l = g_list_next (l)) {
@@ -144,13 +141,10 @@ find_key_with_value (GckSession *session, const gchar *value)
 {
 	GckBuilder builder = GCK_BUILDER_INIT;
 	GList *objects;
-	GckAttributes *attrs;
 	GckObject *object;
 
 	gck_builder_add_string (&builder, CKA_VALUE, value);
-	attrs = gck_builder_end (&builder);
-	objects = gck_session_find_objects (session, attrs, NULL, NULL);
-	gck_attributes_unref (attrs);
+	objects = gck_session_find_objects (session, gck_builder_end (&builder), NULL, NULL);
 	g_assert (objects);
 
 	object = g_object_ref (objects->data);
@@ -407,9 +401,9 @@ test_generate_key_pair (Test *test, gconstpointer unused)
 	gboolean ret;
 
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PUBLIC_KEY);
-	pub_attrs =  gck_builder_end (&builder);
+	pub_attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PRIVATE_KEY);
-	prv_attrs =  gck_builder_end (&builder);
+	prv_attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	/* Full One*/
 	ret = gck_session_generate_key_pair_full (test->session, &mech, pub_attrs, prv_attrs,
@@ -542,7 +536,7 @@ test_unwrap_key (Test *test, gconstpointer unused)
 
 	wrapper = find_key (test->session, CKA_UNWRAP, 0);
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
-	attrs = gck_builder_end (&builder);
+	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	/* Full One*/
 	unwrapped = gck_session_unwrap_key_full (test->session, wrapper, &mech, (const guchar *)"special", 7, attrs, NULL, &error);
@@ -598,7 +592,7 @@ test_derive_key (Test *test, gconstpointer unused)
 
 	wrapper = find_key (test->session, CKA_DERIVE, 0);
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
-	attrs = gck_builder_end (&builder);
+	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	/* Full One*/
 	derived = gck_session_derive_key_full (test->session, wrapper, &mech, attrs, NULL, &error);
diff --git a/gck/tests/test-gck-enumerator.c b/gck/tests/test-gck-enumerator.c
index 42e59b2..7c3a429 100644
--- a/gck/tests/test-gck-enumerator.c
+++ b/gck/tests/test-gck-enumerator.c
@@ -233,7 +233,6 @@ test_enumerate_session (Test *test,
 {
 	GckBuilder builder = GCK_BUILDER_INIT;
 	GckEnumerator *en;
-	GckAttributes *attrs;
 	GError *error = NULL;
 	GckSession *session;
 	GckObject *obj;
@@ -245,10 +244,8 @@ test_enumerate_session (Test *test,
 	session = gck_session_open (slots->data, 0, NULL, NULL, &error);
 	g_assert_no_error (error);
 
-	attrs = gck_builder_end (&builder);
-	en = gck_session_enumerate_objects (session, attrs);
+	en = gck_session_enumerate_objects (session, gck_builder_end (&builder));
 	g_assert (GCK_IS_ENUMERATOR (en));
-	gck_attributes_unref (attrs);
 
 	obj = gck_enumerator_next (en, NULL, &error);
 	g_assert (GCK_IS_OBJECT (obj));
@@ -270,7 +267,7 @@ test_attribute_match (Test *test, gconstpointer unused)
 
 	uri_data = gck_uri_data_new ();
 	gck_builder_add_string (&builder, CKA_LABEL, "Private Capitalize Key");
-	uri_data->attributes = gck_builder_end (&builder);
+	uri_data->attributes = gck_attributes_ref_sink (gck_builder_end (&builder));
 	en = _gck_enumerator_new_for_modules (test->modules, 0, uri_data);
 	g_assert (GCK_IS_ENUMERATOR (en));
 
@@ -560,18 +557,18 @@ test_chained (Test *test,
 
 	uri_data = gck_uri_data_new ();
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PUBLIC_KEY);
-	uri_data->attributes = gck_builder_end (&builder);
+	uri_data->attributes = gck_attributes_ref_sink (gck_builder_end (&builder));
 	one = _gck_enumerator_new_for_modules (test->modules, 0, uri_data);
 
 	uri_data = gck_uri_data_new ();
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PRIVATE_KEY);
-	uri_data->attributes = gck_builder_end (&builder);
+	uri_data->attributes = gck_attributes_ref_sink (gck_builder_end (&builder));
 	two = _gck_enumerator_new_for_modules (test->modules, 0, uri_data);
 	gck_enumerator_set_chained (one, two);
 
 	uri_data = gck_uri_data_new ();
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_DATA);
-	uri_data->attributes = gck_builder_end (&builder);
+	uri_data->attributes = gck_attributes_ref_sink (gck_builder_end (&builder));
 	three = _gck_enumerator_new_for_modules (test->modules, 0, uri_data);
 	gck_enumerator_set_chained (two, three);
 
diff --git a/gck/tests/test-gck-modules.c b/gck/tests/test-gck-modules.c
index 166abbc..e212d1c 100644
--- a/gck/tests/test-gck-modules.c
+++ b/gck/tests/test-gck-modules.c
@@ -66,16 +66,13 @@ static void
 test_enumerate_objects (Test *test, gconstpointer unused)
 {
 	GckBuilder builder = GCK_BUILDER_INIT;
-	GckAttributes *attrs;
 	GError *error = NULL;
 	GckEnumerator *en;
 	GList *objects;
 
 	gck_builder_add_string (&builder, CKA_LABEL, "Private Capitalize Key");
-	attrs = gck_builder_end (&builder);
-	en = gck_modules_enumerate_objects (test->modules, attrs, 0);
+	en = gck_modules_enumerate_objects (test->modules, gck_builder_end (&builder), 0);
 	g_assert (GCK_IS_ENUMERATOR (en));
-	gck_attributes_unref (attrs);
 
 	objects = gck_enumerator_next_n (en, -1, NULL, &error);
 	g_assert_no_error (error);
diff --git a/gck/tests/test-gck-object.c b/gck/tests/test-gck-object.c
index 14493d1..e0cdfd3 100644
--- a/gck/tests/test-gck-object.c
+++ b/gck/tests/test-gck-object.c
@@ -153,7 +153,7 @@ test_create_object (Test *test, gconstpointer unused)
 	gck_builder_add_string (&builder, CKA_LABEL, "TEST LABEL");
 	gck_builder_add_boolean (&builder, CKA_TOKEN, CK_FALSE);
 	gck_builder_add_data (&builder, CKA_VALUE, (const guchar *)"BLAH", 4);
-	attrs = gck_builder_end (&builder);
+	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	object = gck_session_create_object (test->session, attrs, NULL, &err);
 	g_assert (GCK_IS_OBJECT (object));
@@ -191,7 +191,7 @@ test_destroy_object (Test *test, gconstpointer unused)
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_DATA);
 	gck_builder_add_string (&builder, CKA_LABEL, "TEST OBJECT");
 	gck_builder_add_boolean (&builder, CKA_TOKEN, CK_TRUE);
-	attrs = gck_builder_end (&builder);
+	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	/* Using simple */
 	object = gck_session_create_object (test->session, attrs, NULL, &err);
@@ -313,7 +313,7 @@ test_set_attributes (Test *test, gconstpointer unused)
 {
 	GckBuilder builder = GCK_BUILDER_INIT;
 	GAsyncResult *result = NULL;
-	GckAttributes *attrs, *templ;
+	GckAttributes *attrs;
 	GError *err = NULL;
 	gulong klass;
 	gchar *value = NULL;
@@ -321,11 +321,9 @@ test_set_attributes (Test *test, gconstpointer unused)
 
 	gck_builder_add_ulong (&builder, CKA_CLASS, 6);
 	gck_builder_add_string (&builder, CKA_LABEL, "CHANGE TWO");
-	templ = gck_builder_end (&builder);
 
 	/* Full */
-	ret = gck_object_set (test->object, templ, NULL, &err);
-	gck_attributes_unref (templ);
+	ret = gck_object_set (test->object, gck_builder_end (&builder), NULL, &err);
 	g_assert_no_error (err);
 	g_assert (ret);
 	attrs = gck_object_get (test->object, NULL, &err, CKA_CLASS, CKA_LABEL, GCK_INVALID);
@@ -336,11 +334,9 @@ test_set_attributes (Test *test, gconstpointer unused)
 
 	gck_builder_add_ulong (&builder, CKA_CLASS, 7);
 	gck_builder_add_string (&builder, CKA_LABEL, "CHANGE THREE");
-	templ = gck_builder_end (&builder);
 
 	/* Async */
-	gck_object_set_async (test->object, templ, NULL, fetch_async_result, &result);
-	gck_attributes_unref (templ);
+	gck_object_set_async (test->object, gck_builder_end (&builder), NULL, fetch_async_result, &result);
 	egg_test_wait_until (500);
 	g_assert (result != NULL);
 
@@ -360,46 +356,36 @@ test_find_objects (Test *test, gconstpointer unused)
 {
 	GckBuilder builder = GCK_BUILDER_INIT;
 	GAsyncResult *result = NULL;
-	GckAttributes *templ, *attrs;
 	GList *objects;
 	GckObject *testobj;
 	GError *err = NULL;
 
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_DATA);
 	gck_builder_add_string (&builder, CKA_LABEL, "UNIQUE LABEL");
-	attrs = gck_builder_end (&builder);
-	testobj = gck_session_create_object (test->session, attrs, NULL, &err);
-	gck_attributes_unref (attrs);
+	testobj = gck_session_create_object (test->session, gck_builder_end (&builder), NULL, &err);
 	g_object_unref (testobj);
 
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_DATA);
 	gck_builder_add_string (&builder, CKA_LABEL, "OTHER LABEL");
-	attrs = gck_builder_end (&builder);
-	testobj = gck_session_create_object (test->session, attrs, NULL, &err);
-	gck_attributes_unref (attrs);
+	testobj = gck_session_create_object (test->session, gck_builder_end (&builder), NULL, &err);
 	g_object_unref (testobj);
 
 	/* Simple, "TEST LABEL" */
 	gck_builder_add_string (&builder, CKA_LABEL, "UNIQUE LABEL");
-	attrs = gck_builder_end (&builder);
-	objects = gck_session_find_objects (test->session, attrs, NULL, &err);
+	objects = gck_session_find_objects (test->session, gck_builder_end (&builder), NULL, &err);
 	g_assert_no_error (err);
 	g_assert (g_list_length (objects) == 1);
 	gck_list_unref_free (objects);
-	gck_attributes_unref (attrs);
 
 	/* Full, All */
-	templ = gck_builder_end (&builder);
-	objects = gck_session_find_objects (test->session, templ, NULL, &err);
+	objects = gck_session_find_objects (test->session, gck_builder_end (&builder), NULL, &err);
 	g_assert_no_error (err);
 	g_assert (g_list_length (objects) > 1);
 	gck_list_unref_free (objects);
-	gck_attributes_unref (templ);
 
 	/* Async, None */
 	gck_builder_add_string (&builder, CKA_LABEL, "blah blah");
-	templ = gck_builder_end (&builder);
-	gck_session_find_objects_async (test->session, templ, NULL, fetch_async_result, &result);
+	gck_session_find_objects_async (test->session, gck_builder_end (&builder), NULL, fetch_async_result, &result);
 	egg_test_wait_until (500);
 	g_assert (result != NULL);
 
@@ -407,7 +393,6 @@ test_find_objects (Test *test, gconstpointer unused)
 	g_object_unref (result);
 	g_assert (objects == NULL);
 	gck_list_unref_free (objects);
-	gck_attributes_unref (templ);
 }
 
 int
diff --git a/gck/tests/test-gck-session.c b/gck/tests/test-gck-session.c
index 4896063..438a361 100644
--- a/gck/tests/test-gck-session.c
+++ b/gck/tests/test-gck-session.c
@@ -439,7 +439,7 @@ test_auto_login (Test *test, gconstpointer unused)
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_DATA);
 	gck_builder_add_string (&builder, CKA_LABEL, "TEST OBJECT");
 	gck_builder_add_boolean (&builder, CKA_PRIVATE, CK_TRUE);
-	attrs = gck_builder_end (&builder);
+	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	/* Try to do something that requires a login */
 	object = gck_session_create_object (test->session, attrs, NULL, &err);
diff --git a/gck/tests/test-gck-uri.c b/gck/tests/test-gck-uri.c
index 773c665..8370133 100644
--- a/gck/tests/test-gck-uri.c
+++ b/gck/tests/test-gck-uri.c
@@ -327,7 +327,7 @@ test_build_with_attributes (void)
 	gck_builder_add_string (&builder, CKA_LABEL, "The Label");
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_DATA);
 	gck_builder_add_data (&builder, CKA_ID, (const guchar *)"TEST", 5);
-	uri_data.attributes = gck_builder_end (&builder);
+	uri_data.attributes = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	uri = gck_uri_build (&uri_data, GCK_URI_FOR_OBJECT);
 	g_assert (uri);
@@ -429,7 +429,7 @@ test_build_objecttype_cert (void)
 
 	uri_data = gck_uri_data_new ();
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_CERTIFICATE);
-	uri_data->attributes = gck_builder_end (&builder);
+	uri_data->attributes = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	uri = gck_uri_build (uri_data, GCK_URI_FOR_OBJECT);
 	g_assert (uri);
@@ -448,7 +448,7 @@ test_build_objecttype_private (void)
 
 	uri_data = gck_uri_data_new ();
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PRIVATE_KEY);
-	uri_data->attributes = gck_builder_end (&builder);
+	uri_data->attributes = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	uri = gck_uri_build (uri_data, GCK_URI_FOR_OBJECT);
 	g_assert (uri);
@@ -467,7 +467,7 @@ test_build_objecttype_public (void)
 
 	uri_data = gck_uri_data_new ();
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PUBLIC_KEY);
-	uri_data->attributes = gck_builder_end (&builder);
+	uri_data->attributes = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	uri = gck_uri_build (uri_data, GCK_URI_FOR_OBJECT);
 	g_assert (uri);
@@ -486,7 +486,7 @@ test_build_objecttype_secret (void)
 
 	uri_data = gck_uri_data_new ();
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
-	uri_data->attributes = gck_builder_end (&builder);
+	uri_data->attributes = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	uri = gck_uri_build (uri_data, GCK_URI_FOR_OBJECT);
 	g_assert (uri);
diff --git a/gcr/gcr-certificate-renderer.c b/gcr/gcr-certificate-renderer.c
index 79b42f0..fce96dc 100644
--- a/gcr/gcr-certificate-renderer.c
+++ b/gcr/gcr-certificate-renderer.c
@@ -418,7 +418,6 @@ gcr_certificate_renderer_class_init (GcrCertificateRendererClass *klass)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 	GckBuilder builder = GCK_BUILDER_INIT;
-	GckAttributes *registered;
 
 	_gcr_oids_init ();
 
@@ -462,9 +461,7 @@ gcr_certificate_renderer_class_init (GcrCertificateRendererClass *klass)
 
 	/* Register this as a renderer which can be loaded */
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_CERTIFICATE);
-	registered = gck_builder_end (&builder);
-	gcr_renderer_register (GCR_TYPE_CERTIFICATE_RENDERER, registered);
-	gck_attributes_unref (registered);
+	gcr_renderer_register (GCR_TYPE_CERTIFICATE_RENDERER, gck_builder_end (&builder));
 }
 
 static void
diff --git a/gcr/gcr-certificate-request-renderer.c b/gcr/gcr-certificate-request-renderer.c
index 591dd79..2e1b29d 100644
--- a/gcr/gcr-certificate-request-renderer.c
+++ b/gcr/gcr-certificate-request-renderer.c
@@ -169,7 +169,6 @@ _gcr_certificate_request_renderer_class_init (GcrCertificateRequestRendererClass
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 	GckBuilder builder = GCK_BUILDER_INIT;
-	GckAttributes *registered;
 
 	_gcr_oids_init ();
 
@@ -202,15 +201,11 @@ _gcr_certificate_request_renderer_class_init (GcrCertificateRequestRendererClass
 	/* Register this as a renderer which can be loaded */
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_GCR_CERTIFICATE_REQUEST);
 	gck_builder_add_ulong (&builder, CKA_GCR_CERTIFICATE_REQUEST_TYPE, CKQ_GCR_PKCS10);
-	registered = gck_builder_end (&builder);
-	gcr_renderer_register (GCR_TYPE_CERTIFICATE_REQUEST_RENDERER, registered);
-	gck_attributes_unref (registered);
+	gcr_renderer_register (GCR_TYPE_CERTIFICATE_REQUEST_RENDERER, gck_builder_end (&builder));
 
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_GCR_CERTIFICATE_REQUEST);
 	gck_builder_add_ulong (&builder, CKA_GCR_CERTIFICATE_REQUEST_TYPE, CKQ_GCR_SPKAC);
-	registered = gck_builder_end (&builder);
-	gcr_renderer_register (GCR_TYPE_CERTIFICATE_REQUEST_RENDERER, registered);
-	gck_attributes_unref (registered);
+	gcr_renderer_register (GCR_TYPE_CERTIFICATE_REQUEST_RENDERER, gck_builder_end (&builder));
 }
 
 static gboolean
diff --git a/gcr/gcr-gnupg-importer.c b/gcr/gcr-gnupg-importer.c
index 351ac46..9e78b2a 100644
--- a/gcr/gcr-gnupg-importer.c
+++ b/gcr/gcr-gnupg-importer.c
@@ -214,7 +214,6 @@ _gcr_gnupg_importer_class_init (GcrGnupgImporterClass *klass)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 	GckBuilder builder = GCK_BUILDER_INIT;
-	GckAttributes *registered;
 
 	gobject_class->dispose = _gcr_gnupg_importer_dispose;
 	gobject_class->finalize = _gcr_gnupg_importer_finalize;
@@ -238,9 +237,7 @@ _gcr_gnupg_importer_class_init (GcrGnupgImporterClass *klass)
 	                                NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_GCR_GNUPG_RECORDS);
-	registered = gck_builder_end (&builder);
-	gcr_importer_register (GCR_TYPE_GNUPG_IMPORTER, registered);
-	gck_attributes_unref (registered);
+	gcr_importer_register (GCR_TYPE_GNUPG_IMPORTER, gck_builder_end (&builder));
 
 	_gcr_initialize_library ();
 }
diff --git a/gcr/gcr-gnupg-renderer.c b/gcr/gcr-gnupg-renderer.c
index 9f31eb0..5180503 100644
--- a/gcr/gcr-gnupg-renderer.c
+++ b/gcr/gcr-gnupg-renderer.c
@@ -164,7 +164,6 @@ _gcr_gnupg_renderer_class_init (GcrGnupgRendererClass *klass)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 	GckBuilder builder = GCK_BUILDER_INIT;
-	GckAttributes *registered;
 
 	_gcr_gnupg_renderer_parent_class = g_type_class_peek_parent (klass);
 	g_type_class_add_private (klass, sizeof (GcrGnupgRendererPrivate));
@@ -187,9 +186,7 @@ _gcr_gnupg_renderer_class_init (GcrGnupgRendererClass *klass)
 
 	/* Register this as a renderer which can be loaded */
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_GCR_GNUPG_RECORDS);
-	registered = gck_builder_end (&builder);
-	gcr_renderer_register (GCR_TYPE_GNUPG_RENDERER, registered);
-	gck_attributes_unref (registered);
+	gcr_renderer_register (GCR_TYPE_GNUPG_RENDERER, gck_builder_end (&builder));
 }
 
 static const gchar *
diff --git a/gcr/gcr-key-renderer.c b/gcr/gcr-key-renderer.c
index 82089b3..333c719 100644
--- a/gcr/gcr-key-renderer.c
+++ b/gcr/gcr-key-renderer.c
@@ -213,7 +213,6 @@ gcr_key_renderer_class_init (GcrKeyRendererClass *klass)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 	GckBuilder builder = GCK_BUILDER_INIT;
-	GckAttributes *registered;
 
 	gcr_key_renderer_parent_class = g_type_class_peek_parent (klass);
 	g_type_class_add_private (klass, sizeof (GcrKeyRendererPrivate));
@@ -228,9 +227,7 @@ gcr_key_renderer_class_init (GcrKeyRendererClass *klass)
 
 	/* Register this as a view which can be loaded */
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PRIVATE_KEY);
-	registered = gck_builder_end (&builder);
-	gcr_renderer_register (GCR_TYPE_KEY_RENDERER, registered);
-	gck_attributes_unref (registered);
+	gcr_renderer_register (GCR_TYPE_KEY_RENDERER, gck_builder_end (&builder));
 }
 
 static void
diff --git a/gcr/gcr-openssh.c b/gcr/gcr-openssh.c
index c3970ab..c7471f7 100644
--- a/gcr/gcr-openssh.c
+++ b/gcr/gcr-openssh.c
@@ -226,7 +226,7 @@ parse_v1_public_line (const gchar *line,
 	if (word_options)
 		options = g_strndup (word_options, len_options);
 
-	attrs = gck_builder_end (&builder);
+	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	if (callback != NULL) {
 		bytes = egg_bytes_new_with_free_func (outer, n_outer,
@@ -442,7 +442,7 @@ parse_v2_public_line (const gchar *line,
 		gck_builder_add_string (&builder, CKA_LABEL, label);
 	}
 
-	attrs = gck_builder_end (&builder);
+	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	if (callback != NULL) {
 		bytes = egg_bytes_new_with_free_func (outer, n_outer,
diff --git a/gcr/gcr-parser.c b/gcr/gcr-parser.c
index 1022e41..bfa92e1 100644
--- a/gcr/gcr-parser.c
+++ b/gcr/gcr-parser.c
@@ -457,7 +457,7 @@ parsed_fire (GcrParser *self,
 	g_assert (parsed == self->pv->parsed);
 	g_assert (parsed->attrs == NULL);
 
-	parsed->attrs = gck_builder_end (&parsed->builder);
+	parsed->attrs = gck_attributes_ref_sink (gck_builder_end (&parsed->builder));
 
 	g_object_notify (G_OBJECT (self), "parsed-description");
 	g_object_notify (G_OBJECT (self), "parsed-attributes");
diff --git a/gcr/gcr-pkcs11-certificate.c b/gcr/gcr-pkcs11-certificate.c
index ced8135..f726ec9 100644
--- a/gcr/gcr-pkcs11-certificate.c
+++ b/gcr/gcr-pkcs11-certificate.c
@@ -103,7 +103,7 @@ prepare_lookup_certificate_issuer (GcrCertificate *cert)
 	gck_builder_add_data (&builder, CKA_SUBJECT, data, n_data);
 	g_free (data);
 
-	return gck_builder_end (&builder);
+	return gck_attributes_ref_sink (gck_builder_end (&builder));
 }
 
 static GcrCertificate*
diff --git a/gcr/gcr-pkcs11-importer.c b/gcr/gcr-pkcs11-importer.c
index e46ed2d..863a0d4 100644
--- a/gcr/gcr-pkcs11-importer.c
+++ b/gcr/gcr-pkcs11-importer.c
@@ -335,7 +335,7 @@ supplement_attributes (GcrPkcs11Importer *self,
 		}
 
 		gck_attributes_unref (attrs);
-		l->data = attrs = gck_builder_end (&builder);
+		l->data = attrs = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 		switch (klass) {
 		case CKO_CERTIFICATE:
@@ -369,14 +369,14 @@ supplement_attributes (GcrPkcs11Importer *self,
 			supplement_with_attributes (&builder, supplements);
 			supplement_id_for_data (&builder, nonce, sizeof (nonce),
 			                        fingerprint, strlen (fingerprint));
-			g_queue_push_tail (queue, gck_builder_end (&builder));
+			g_queue_push_tail (queue, gck_attributes_ref_sink (gck_builder_end (&builder)));
 			g_hash_table_insert (paired, pair->private_key, "present");
 
 			gck_builder_add_all (&builder, pair->certificate);
 			supplement_with_attributes (&builder, supplements);
 			supplement_id_for_data (&builder, nonce, sizeof (nonce),
 			                        fingerprint, strlen (fingerprint));
-			g_queue_push_tail (queue, gck_builder_end (&builder));
+			g_queue_push_tail (queue, gck_attributes_ref_sink (gck_builder_end (&builder)));
 			g_hash_table_insert (paired, pair->certificate, "present");
 
 			/* Used the suplements for the pairs, don't use for unpaired stuff */
@@ -400,7 +400,7 @@ supplement_attributes (GcrPkcs11Importer *self,
 			supplement_id_for_data (&builder, nonce, sizeof (nonce),
 			                        &attrs, sizeof (gpointer));
 
-			g_queue_push_tail (queue, gck_builder_end (&builder));
+			g_queue_push_tail (queue, gck_attributes_ref_sink (gck_builder_end (&builder)));
 		}
 	}
 
@@ -421,7 +421,7 @@ complete_supplement (GSimpleAsyncResult *res,
 	GckAttributes *attributes;
 
 	if (error == NULL) {
-		attributes = gck_builder_end (data->supplement);
+		attributes = gck_attributes_ref_sink (gck_builder_end (data->supplement));
 		supplement_attributes (data->importer, attributes);
 		gck_attributes_unref (attributes);
 
@@ -685,7 +685,6 @@ _gcr_pkcs11_importer_class_init (GcrPkcs11ImporterClass *klass)
 {
 	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 	GckBuilder builder = GCK_BUILDER_INIT;
-	GckAttributes *registered;
 
 	gobject_class->dispose = _gcr_pkcs11_importer_dispose;
 	gobject_class->finalize = _gcr_pkcs11_importer_finalize;
@@ -712,14 +711,10 @@ _gcr_pkcs11_importer_class_init (GcrPkcs11ImporterClass *klass)
 
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_CERTIFICATE);
 	gck_builder_add_ulong (&builder, CKA_CERTIFICATE_TYPE, CKC_X_509);
-	registered = gck_builder_end (&builder);
-	gcr_importer_register (GCR_TYPE_PKCS11_IMPORTER, registered);
-	gck_attributes_unref (registered);
+	gcr_importer_register (GCR_TYPE_PKCS11_IMPORTER, gck_builder_end (&builder));
 
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PRIVATE_KEY);
-	registered = gck_builder_end (&builder);
-	gcr_importer_register (GCR_TYPE_PKCS11_IMPORTER, registered);
-	gck_attributes_unref (registered);
+	gcr_importer_register (GCR_TYPE_PKCS11_IMPORTER, gck_builder_end (&builder));
 
 	_gcr_initialize_library ();
 }
@@ -926,9 +921,7 @@ _gcr_pkcs11_importer_queue (GcrPkcs11Importer *self,
 		gck_builder_add_all (&builder, attrs);
 		gck_builder_add_string (&builder, CKA_LABEL, label);
 		attrs = gck_builder_end (&builder);
-	} else {
-		attrs = gck_attributes_ref (attrs);
 	}
 
-	g_queue_push_tail (self->queue, attrs);
+	g_queue_push_tail (self->queue, gck_attributes_ref_sink (attrs));
 }
diff --git a/gcr/gcr-renderer.c b/gcr/gcr-renderer.c
index 3ef5c1a..71c84c0 100644
--- a/gcr/gcr-renderer.c
+++ b/gcr/gcr-renderer.c
@@ -275,7 +275,7 @@ gcr_renderer_register (GType renderer_type, GckAttributes *attrs)
 		registered_renderers = g_array_new (FALSE, FALSE, sizeof (GcrRegistered));
 
 	registered.renderer_type = renderer_type;
-	registered.attrs = gck_attributes_ref (attrs);
+	registered.attrs = gck_attributes_ref_sink (attrs);
 	g_array_append_val (registered_renderers, registered);
 	registered_sorted = FALSE;
 }
diff --git a/gcr/gcr-subject-public-key.c b/gcr/gcr-subject-public-key.c
index dbef1af..a3293f1 100644
--- a/gcr/gcr-subject-public-key.c
+++ b/gcr/gcr-subject-public-key.c
@@ -176,7 +176,6 @@ lookup_public_key (GckObject *object,
                    GError **lerror)
 {
 	GckBuilder builder = GCK_BUILDER_INIT;
-	GckAttributes *match;
 	GError *error = NULL;
 	GckSession *session;
 	GckObject *result;
@@ -192,14 +191,11 @@ lookup_public_key (GckObject *object,
 	}
 
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_PUBLIC_KEY);
-	gck_builder_add_data (&builder, CKA_ID, id, n_id);
-	match = gck_builder_end (&builder);
+	gck_builder_take_data (&builder, CKA_ID, id, n_id);
 	session = gck_object_get_session (object);
-	g_free (id);
 
-	objects = gck_session_find_objects (session, match, cancellable, &error);
+	objects = gck_session_find_objects (session, gck_builder_end (&builder), cancellable, &error);
 
-	gck_attributes_unref (match);
 	g_object_unref (session);
 
 	if (error != NULL) {
@@ -498,7 +494,7 @@ _gcr_subject_public_key_load_finish (GAsyncResult *result,
 		return NULL;
 
 	closure = g_simple_async_result_get_op_res_gpointer (res);
-	attributes = gck_builder_end (&closure->builder);
+	attributes = gck_attributes_ref_sink (gck_builder_end (&closure->builder));
 	asn = _gcr_subject_public_key_for_attributes (attributes);
 	if (asn == NULL) {
 		g_set_error_literal (error, GCK_ERROR, CKR_TEMPLATE_INCONSISTENT,
diff --git a/gcr/gcr-trust.c b/gcr/gcr-trust.c
index 34b86c5..e8e55e0 100644
--- a/gcr/gcr-trust.c
+++ b/gcr/gcr-trust.c
@@ -144,7 +144,7 @@ prepare_is_certificate_pinned (GcrCertificate *certificate, const gchar *purpose
 	gck_builder_add_string (&builder, CKA_X_PURPOSE, purpose);
 	gck_builder_add_string (&builder, CKA_X_PEER, peer);
 
-	return gck_builder_end (&builder);
+	return gck_attributes_ref_sink (gck_builder_end (&builder));
 }
 
 static gboolean
@@ -316,7 +316,7 @@ prepare_add_pinned_certificate (GcrCertificate *certificate, const gchar *purpos
 	gck_builder_add_string (&builder, CKA_X_PEER, peer);
 	gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE);
 
-	return gck_builder_end (&builder);
+	return gck_attributes_ref_sink (gck_builder_end (&builder));
 }
 
 static gboolean
@@ -325,7 +325,6 @@ perform_add_pinned_certificate (GckAttributes *search,
                                 GError **error)
 {
 	GckBuilder builder = GCK_BUILDER_INIT;
-	GckAttributes *attrs;
 	gboolean ret = FALSE;
 	GError *lerr = NULL;
 	GckObject *object;
@@ -358,7 +357,6 @@ perform_add_pinned_certificate (GckAttributes *search,
 	}
 
 	gck_builder_add_all (&builder, search);
-	attrs = gck_builder_end (&builder);
 
 	/* TODO: Add relevant label */
 
@@ -374,7 +372,8 @@ perform_add_pinned_certificate (GckAttributes *search,
 	} else {
 		session = gck_slot_open_session (slot, CKF_RW_SESSION, NULL, error);
 		if (session != NULL) {
-			object = gck_session_create_object (session, attrs, cancellable, error);
+			object = gck_session_create_object (session, gck_builder_end (&builder),
+			                                    cancellable, error);
 			if (object != NULL) {
 				g_object_unref (object);
 				ret = TRUE;
@@ -386,7 +385,7 @@ perform_add_pinned_certificate (GckAttributes *search,
 		g_object_unref (slot);
 	}
 
-	gck_attributes_unref (attrs);
+	gck_builder_clear (&builder);
 
 	/* Our own local error pointer */
 	g_clear_error (&lerr);
@@ -533,7 +532,7 @@ prepare_remove_pinned_certificate (GcrCertificate *certificate, const gchar *pur
 	gck_builder_add_string (&builder, CKA_X_PURPOSE, purpose);
 	gck_builder_add_string (&builder, CKA_X_PEER, peer);
 
-	return gck_builder_end (&builder);
+	return gck_attributes_ref_sink (gck_builder_end (&builder));
 }
 
 static gboolean
@@ -714,7 +713,7 @@ prepare_is_certificate_anchored (GcrCertificate *certificate, const gchar *purpo
 	prepare_trust_attrs (certificate, CKT_X_ANCHORED_CERTIFICATE, &builder);
 	gck_builder_add_string (&builder, CKA_X_PURPOSE, purpose);
 
-	return gck_builder_end (&builder);
+	return gck_attributes_ref_sink (gck_builder_end (&builder));
 }
 
 static gboolean
diff --git a/gcr/tests/test-certificate-chain.c b/gcr/tests/test-certificate-chain.c
index 87488d0..784f17b 100644
--- a/gcr/tests/test-certificate-chain.c
+++ b/gcr/tests/test-certificate-chain.c
@@ -194,7 +194,7 @@ add_certificate_to_module (GcrCertificate *certificate)
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_CERTIFICATE);
 	gck_builder_add_ulong (&builder, CKA_CERTIFICATE_TYPE, CKC_X_509);
 	gck_builder_add_data (&builder, CKA_SUBJECT, subject, n_subject);
-	gck_mock_module_take_object (gck_builder_end (&builder));
+	gck_mock_module_add_object (gck_builder_end (&builder));
 
 	g_free (subject);
 }
@@ -214,7 +214,7 @@ add_anchor_to_module (GcrCertificate *certificate, const gchar *purpose)
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_X_TRUST_ASSERTION);
 	gck_builder_add_ulong (&builder, CKA_X_ASSERTION_TYPE, CKT_X_ANCHORED_CERTIFICATE);
 	gck_builder_add_string (&builder, CKA_X_PURPOSE, purpose);
-	gck_mock_module_take_object (gck_builder_end (&builder));
+	gck_mock_module_add_object (gck_builder_end (&builder));
 }
 
 static void
@@ -233,7 +233,7 @@ add_pinned_to_module (GcrCertificate *certificate, const gchar *purpose, const g
 	gck_builder_add_ulong (&builder, CKA_X_ASSERTION_TYPE, CKT_X_PINNED_CERTIFICATE);
 	gck_builder_add_string (&builder, CKA_X_PURPOSE, purpose);
 	gck_builder_add_string (&builder, CKA_X_PEER, host);
-	gck_mock_module_take_object (gck_builder_end (&builder));
+	gck_mock_module_add_object (gck_builder_end (&builder));
 }
 
 static void
diff --git a/gcr/tests/test-fingerprint.c b/gcr/tests/test-fingerprint.c
index fd90bb1..7b4acf5 100644
--- a/gcr/tests/test-fingerprint.c
+++ b/gcr/tests/test-fingerprint.c
@@ -117,7 +117,7 @@ build_attributes_for_cert (EggBytes *data)
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_CERTIFICATE);
 	gck_builder_add_ulong (&builder, CKA_CERTIFICATE_TYPE, CKC_X_509);
 
-	return gck_builder_end (&builder);
+	return gck_attributes_ref_sink (gck_builder_end (&builder));
 }
 
 static EggBytes *
diff --git a/gcr/tests/test-pkcs11-certificate.c b/gcr/tests/test-pkcs11-certificate.c
index 29c1b29..3c263f1 100644
--- a/gcr/tests/test-pkcs11-certificate.c
+++ b/gcr/tests/test-pkcs11-certificate.c
@@ -95,7 +95,7 @@ setup (Test *test, gconstpointer unused)
 	gck_builder_add_data (&builder, CKA_SUBJECT,
 	                      egg_bytes_get_data (subject),
 	                      egg_bytes_get_size (subject));
-	gck_mock_module_take_object (gck_builder_end (&builder));
+	gck_mock_module_add_object (gck_builder_end (&builder));
 
 	egg_bytes_unref (bytes);
 	egg_bytes_unref (subject);
diff --git a/gcr/tests/test-subject-public-key.c b/gcr/tests/test-subject-public-key.c
index 8397262..eaee3c7 100644
--- a/gcr/tests/test-subject-public-key.c
+++ b/gcr/tests/test-subject-public-key.c
@@ -281,17 +281,17 @@ setup_loading (TestLoading *test,
 
 	gck_builder_add_all (&builder, test->at.crt_attrs);
 	gck_builder_add_string (&builder, CKA_ID, id);
-	handle = gck_mock_module_take_object (gck_builder_end (&builder));
+	handle = gck_mock_module_add_object (gck_builder_end (&builder));
 	test->crt_object = gck_object_from_handle (test->mo.session, handle);
 
 	gck_builder_add_all (&builder, test->at.pub_attrs);
 	gck_builder_add_string (&builder, CKA_ID, id);
-	handle = gck_mock_module_take_object (gck_builder_end (&builder));
+	handle = gck_mock_module_add_object (gck_builder_end (&builder));
 	test->pub_object = gck_object_from_handle (test->mo.session, handle);
 
 	gck_builder_add_all (&builder, test->at.prv_attrs);
 	gck_builder_add_string (&builder, CKA_ID, id);
-	handle = gck_mock_module_take_object (gck_builder_end (&builder));
+	handle = gck_mock_module_add_object (gck_builder_end (&builder));
 	test->prv_object = gck_object_from_handle (test->mo.session, handle);
 }
 
@@ -541,7 +541,7 @@ perform_load_partial (TestLoading *test,
 
 	for (i = 0; i < gck_attributes_count (attributes); i += 2)
 		gck_builder_add_owned (&builder, gck_attributes_at (attributes, i));
-	partial = gck_builder_end (&builder);
+	partial = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	object = g_object_new (mock_object_get_type (),
 	                       "module", test->mo.module,
@@ -622,7 +622,7 @@ test_load_failure_build (TestModule *test,
 	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_CERTIFICATE);
 	gck_builder_add_ulong (&builder, CKA_CERTIFICATE_TYPE, CKC_X_509);
 	gck_builder_add_string (&builder, CKA_VALUE, "invalid value");
-	attributes = gck_builder_end (&builder);
+	attributes = gck_attributes_ref_sink (gck_builder_end (&builder));
 
 	object = g_object_new (mock_object_get_type (),
 	                       "module", test->module,
diff --git a/gcr/tests/test-trust.c b/gcr/tests/test-trust.c
index 905024d..220e0ca 100644
--- a/gcr/tests/test-trust.c
+++ b/gcr/tests/test-trust.c
@@ -281,7 +281,7 @@ test_is_certificate_anchored_yes (Test *test, gconstpointer unused)
 	gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE);
 	gck_builder_add_string (&builder, CKA_X_PURPOSE, GCR_PURPOSE_CLIENT_AUTH);
 	gck_builder_add_ulong (&builder, CKA_X_ASSERTION_TYPE, CKT_X_ANCHORED_CERTIFICATE);
-	gck_mock_module_take_object (gck_builder_end (&builder));
+	gck_mock_module_add_object (gck_builder_end (&builder));
 
 	ret = gcr_trust_is_certificate_anchored (test->certificate, GCR_PURPOSE_CLIENT_AUTH, NULL, &error);
 	g_assert (ret == TRUE);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]