seahorse r2323 - in trunk: . gkr libseahorse pgp pkcs11 src ssh



Author: nnielsen
Date: Sun Aug  3 20:48:08 2008
New Revision: 2323
URL: http://svn.gnome.org/viewvc/seahorse?rev=2323&view=rev

Log:
	* libseahorse/libseahorse-c.vapi:
	* libseahorse/seahorse-context.c:
	* libseahorse/seahorse-object.vala:
	* libseahorse/seahorse-util.c:
	* libseahorse/seahorse-util.h:
	* pkcs11/p11.vapi:
	* pkcs11/gp11.vapi:
	* pkcs11/Makefile.am:
	* pkcs11/seahorse-pkcs11.c:
	* pkcs11/seahorse-pkcs11-certificate.vala: (added)
	* pkcs11/seahorse-pkcs11-source.vala: (added)
	* pkcs11/seahorse-pkcs11-module.c: 
	* src/Makefile.am:
	* src/main.c:
	* ssh/seahorse-ssh-source.c: 
	* configure.in: Add initial proof of concept for loading of 
	objects from PKCS#11. 

Added:
   trunk/pkcs11/seahorse-pkcs11-certificate.c
   trunk/pkcs11/seahorse-pkcs11-certificate.h
   trunk/pkcs11/seahorse-pkcs11-certificate.vala
   trunk/pkcs11/seahorse-pkcs11-source.c
   trunk/pkcs11/seahorse-pkcs11-source.h
   trunk/pkcs11/seahorse-pkcs11-source.vala
Modified:
   trunk/ChangeLog
   trunk/configure.in
   trunk/gkr/vala-build.stamp
   trunk/libseahorse/libseahorse-c.vapi
   trunk/libseahorse/seahorse-context.c
   trunk/libseahorse/seahorse-object.c
   trunk/libseahorse/seahorse-object.vala
   trunk/libseahorse/seahorse-util.c
   trunk/libseahorse/seahorse-util.h
   trunk/libseahorse/vala-build.stamp
   trunk/pgp/vala-build.stamp
   trunk/pkcs11/Makefile.am
   trunk/pkcs11/gp11.vapi
   trunk/pkcs11/p11.vapi
   trunk/pkcs11/seahorse-pkcs11-module.c
   trunk/pkcs11/seahorse-pkcs11.c
   trunk/pkcs11/vala-build.stamp
   trunk/src/Makefile.am
   trunk/src/main.c
   trunk/src/vala-build.stamp
   trunk/ssh/seahorse-ssh-source.c
   trunk/ssh/vala-build.stamp

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Sun Aug  3 20:48:08 2008
@@ -454,7 +454,7 @@
 	echo "disabling pkcs11 support"
 	enable_pkcs11="no"
 else
-	PKG_CHECK_MODULES(GP11, gp11-0, enable_pkcs11="yes", enable_pkcs11="no")
+	PKG_CHECK_MODULES(GP11, gp11-0 >= 2.23.6, enable_pkcs11="yes", enable_pkcs11="no")
 	if test "$enable_pkcs11" == "yes"; then
 		AC_DEFINE(WITH_PKCS11, 1, [gp11 library available])
 		SEAHORSE_CFLAGS="$SEAHORSE_CFLAGS $GP11_CFLAGS"

Modified: trunk/gkr/vala-build.stamp
==============================================================================
--- trunk/gkr/vala-build.stamp	(original)
+++ trunk/gkr/vala-build.stamp	Sun Aug  3 20:48:08 2008
@@ -1 +1 @@
-1217171775
+1217782016

Modified: trunk/libseahorse/libseahorse-c.vapi
==============================================================================
--- trunk/libseahorse/libseahorse-c.vapi	(original)
+++ trunk/libseahorse/libseahorse-c.vapi	Sun Aug  3 20:48:08 2008
@@ -22,6 +22,9 @@
 [CCode (cprefix = "Seahorse", lower_case_cprefix = "seahorse_")]
 namespace Seahorse {
 
+	[CCode (cname = "SEAHORSE_ERROR", cheader_filename = "seahorse-util.h")]
+	public GLib.Quark ERROR_DOMAIN;
+
         [CCode (cheader_filename = "seahorse-source.h")]
         public class Source : GLib.Object {
 		public GLib.Quark ktype { get; }
@@ -67,12 +70,19 @@
 
 	[CCode (cheader_filename = "seahorse-operation.h")]
 	public class Operation : GLib.Object {
-		public Operation.complete();
+		public Operation.complete(GLib.Error* error);
 		public bool is_successful ();
 		public bool is_running ();
 		public void display_error (string heading, Gtk.Widget? parent);
 		public void* get_result ();
 		public void watch (DoneFunc? done, ProgressFunc? progress);
+		
+		public virtual void cancel ();
+		
+		protected void mark_start ();
+		[CCode (cname = "seahorse_operation_mark_progress_full")]
+		protected void mark_progress(string? text, int at, int total);
+		protected void mark_done (bool cancelled, GLib.Error?# error);
 	}
 
 	[CCode (cheader_filename = "seahorse-operation.h")]
@@ -86,6 +96,10 @@
 		public uint count { get; }
 		public weak Source find_source (GLib.Quark ktype, Location location);
 		public void add_source (Source sksrc);
+		public void add_object (Object object);
+		public weak Object? get_object (Source src, GLib.Quark id);
+		public GLib.List<weak Object> get_objects (Source src);
+		public void remove_object(Object object);
 		public weak Object? find_object (GLib.Quark ktype, Location loc);
 		public GLib.List<weak Object> find_objects (GLib.Quark ktype, Usage usage, Location loc);
 		public Operation transfer_objects (GLib.List<Object> objects, Source? to);
@@ -121,6 +135,17 @@
 		public void status_set_operation (Widget widget, Operation op);
 	}
 	
+       	[CCode (cprefix = "SEAHORSE_VALIDITY_")]
+       	public static enum Validity {
+		REVOKED,
+		DISABLED,
+		UNKNOWN,
+		NEVER,
+		MARGINAL,
+		FULL,
+		ULTIMATE
+	}
+
 	[CCode (cheader_filename = "seahorse-util.h")]
 	namespace Util {
 		public uint memory_output_length (GLib.MemoryOutputStream output);
@@ -139,7 +164,16 @@
 		
 		public weak string uri_get_last (string uri);
 		public GLib.Quark detect_file_type (string uri);
-		public GLib.Quark detect_data_type (string text, long len);	
+		public GLib.Quark detect_data_type (string text, long len);
+		
+		[CCode (cname = "seahorse_validity_get_string", cheader_filename = "seahorse-validity.h")]
+		public weak string validity_to_string(Validity validity);	
+		
+		public string hex_encode(void* data, ulong len);
+		public string get_date_string(ulong date);
+		
+		[CCode (array_length_type = "guint")]
+		public uchar[] read_to_memory(GLib.InputStream input);
 	}
 
 	[CCode (cheader_filename = "seahorse-gconf.h", cprefix = "SeahorseGConf", lower_case_cprefix = "seahorse_gconf_")]

Modified: trunk/libseahorse/seahorse-context.c
==============================================================================
--- trunk/libseahorse/seahorse-context.c	(original)
+++ trunk/libseahorse/seahorse-context.c	Sun Aug  3 20:48:08 2008
@@ -315,7 +315,7 @@
     
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
 
     for (l = sctx->pv->sources; l; l = g_slist_next (l)) {
         ks = SEAHORSE_SOURCE (l->data);
@@ -351,7 +351,7 @@
     
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
 
     for (l = sctx->pv->sources; l; l = g_slist_next (l)) {
         ks = SEAHORSE_SOURCE (l->data);
@@ -382,7 +382,7 @@
 
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
 
     for (l = sctx->pv->sources; l; l = g_slist_next (l)) {
         ks = SEAHORSE_SOURCE (l->data);
@@ -543,7 +543,7 @@
 {
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), 0);
     return g_hash_table_size (sctx->pv->objects_by_source);
 }
 
@@ -555,7 +555,7 @@
     
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
     g_return_val_if_fail (SEAHORSE_IS_SOURCE (sksrc), NULL);
     
     k = hashkey_by_source (sksrc, id);
@@ -592,7 +592,7 @@
 
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
     g_return_val_if_fail (sksrc == NULL || SEAHORSE_IS_SOURCE (sksrc), NULL);
 
     memset (&kp, 0, sizeof (kp));
@@ -613,7 +613,7 @@
 
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
 
     sobj = (SeahorseObject*)g_hash_table_lookup (sctx->pv->objects_by_type, GUINT_TO_POINTER (id));
     while (sobj) {
@@ -641,7 +641,7 @@
 
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
     
     pred.tag = ktype;
     pred.usage = usage;
@@ -657,7 +657,7 @@
 
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
 
     memset (&km, 0, sizeof (km));
     
@@ -720,7 +720,7 @@
     
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
 
     /* TODO: All of this needs to take multiple key types into account */
     
@@ -750,7 +750,7 @@
 {
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
     g_return_val_if_fail (sctx->pv->discovery != NULL, NULL);
     
     return sctx->pv->discovery;
@@ -766,7 +766,7 @@
     
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
 
     for (l = sctx->pv->sources; l; l = g_slist_next (l)) {
         ks = SEAHORSE_SOURCE (l->data);
@@ -815,7 +815,7 @@
     
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
     
     /* Get a list of all selected key servers */
     names = seahorse_gconf_get_string_list (LASTSERVERS_KEY);
@@ -938,7 +938,7 @@
 
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
 
     objects = g_list_copy (objects);
     
@@ -1020,7 +1020,7 @@
     
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
 
     if (!to) {
         to = seahorse_context_find_source (sctx, ktype, SEAHORSE_LOCATION_LOCAL);
@@ -1074,7 +1074,7 @@
 
     if (!sctx)
         sctx = seahorse_context_for_app ();
-    g_return_if_fail (SEAHORSE_IS_CONTEXT (sctx));
+    g_return_val_if_fail (SEAHORSE_IS_CONTEXT (sctx), NULL);
 
     /* Check all the ids */
     for (l = rawids; l; l = g_slist_next (l)) {

Modified: trunk/libseahorse/seahorse-object.c
==============================================================================
--- trunk/libseahorse/seahorse-object.c	(original)
+++ trunk/libseahorse/seahorse-object.c	Sun Aug  3 20:48:08 2008
@@ -121,6 +121,9 @@
 
 void seahorse_object_set_source (SeahorseObject* self, SeahorseSource* value) {
 	g_return_if_fail (SEAHORSE_IS_OBJECT (self));
+	if (value == self->priv->_source) {
+		return;
+	}
 	if (self->priv->_source != NULL) {
 		g_object_remove_weak_pointer (G_OBJECT (self->priv->_source), &self->priv->_source);
 	}

Modified: trunk/libseahorse/seahorse-object.vala
==============================================================================
--- trunk/libseahorse/seahorse-object.vala	(original)
+++ trunk/libseahorse/seahorse-object.vala	Sun Aug  3 20:48:08 2008
@@ -84,6 +84,8 @@
 		public Source source {
 			get { return _source; }
 			set { 	
+				if (value == _source)
+					return;
 				if (_source != null)
 					_source.remove_weak_pointer (&_source);
 				_source = value;

Modified: trunk/libseahorse/seahorse-util.c
==============================================================================
--- trunk/libseahorse/seahorse-util.c	(original)
+++ trunk/libseahorse/seahorse-util.c	Sun Aug  3 20:48:08 2008
@@ -231,7 +231,7 @@
 }
 
 /**
- * seahorse_util_read_to_text:
+ * seahorse_util_read_to_memory:
  * @data: Data to write
  * @len: Length of the data
  *
@@ -239,8 +239,8 @@
  *
  * Returns: The string read from data
  **/
-gchar*
-seahorse_util_read_to_text (GInputStream *input, guint *len)
+guchar*
+seahorse_util_read_to_memory (GInputStream *input, guint *len)
 {
 	gint size = 128;
 	gchar *buffer, *text;
@@ -266,7 +266,7 @@
 	g_string_free (string, FALSE);
 	g_free (buffer);
 	
-	return text;
+	return (guchar*)text;
 }
 
 /** 
@@ -1241,6 +1241,23 @@
     g_memmove (text, b, (e + 1) - b);
 }
 
+gchar*
+seahorse_util_hex_encode (gconstpointer value, gsize length)
+{
+	GString *result;
+	gsize i;
+	
+	result = g_string_sized_new ((length * 2) + 1);
+
+	for (i = 0; i < length; i++) {
+		char hex[3];
+		snprintf (hex, sizeof (hex), "%02x", (int)(((guchar*)value)[i]));
+		g_string_append (result, hex);
+	}
+
+	return g_string_free (result, FALSE);
+}
+
 /* Callback to determine where a popup menu should be placed */
 void
 seahorse_util_determine_popup_menu_position (GtkMenu *menu, int *x, int *y,

Modified: trunk/libseahorse/seahorse-util.h
==============================================================================
--- trunk/libseahorse/seahorse-util.h	(original)
+++ trunk/libseahorse/seahorse-util.h	Sun Aug  3 20:48:08 2008
@@ -68,7 +68,7 @@
 gboolean    seahorse_util_prompt_delete         (const gchar *text,
                                                  GtkWidget *parent);
 
-gchar*      seahorse_util_read_to_text          (GInputStream *     input,
+guchar*     seahorse_util_read_to_memory        (GInputStream *     input,
                                                  guint              *len);
 
 guint       seahorse_util_read_data_block       (GString            *buf, 
@@ -165,6 +165,8 @@
 
 void        seahorse_util_string_trim_whitespace (gchar *text);
 
+gchar*      seahorse_util_hex_encode (gconstpointer value, gsize length);
+
 void        seahorse_util_determine_popup_menu_position  (GtkMenu *menu,
                                                            int *x,
                                                            int *y,

Modified: trunk/libseahorse/vala-build.stamp
==============================================================================
--- trunk/libseahorse/vala-build.stamp	(original)
+++ trunk/libseahorse/vala-build.stamp	Sun Aug  3 20:48:08 2008
@@ -1 +1 @@
-1217099898
+1217712531

Modified: trunk/pgp/vala-build.stamp
==============================================================================
--- trunk/pgp/vala-build.stamp	(original)
+++ trunk/pgp/vala-build.stamp	Sun Aug  3 20:48:08 2008
@@ -1 +1 @@
-1217173660
+1217782666

Modified: trunk/pkcs11/Makefile.am
==============================================================================
--- trunk/pkcs11/Makefile.am	(original)
+++ trunk/pkcs11/Makefile.am	Sun Aug  3 20:48:08 2008
@@ -16,7 +16,9 @@
 	-DGETTEXT_PACKAGE=\""seahorse\""
 
 VALA_SRCS = \
-	seahorse-pkcs11.vala
+	seahorse-pkcs11.vala \
+	seahorse-pkcs11-certificate.vala \
+	seahorse-pkcs11-source.vala
 	
 VALA_VAPIS = \
 	p11.vapi \

Modified: trunk/pkcs11/gp11.vapi
==============================================================================
--- trunk/pkcs11/gp11.vapi	(original)
+++ trunk/pkcs11/gp11.vapi	Sun Aug  3 20:48:08 2008
@@ -7,6 +7,7 @@
 
 	public weak string message_from_rv (uint rv);
 	
+	[Compact]
 	[CCode (dup_function = "gp11_attribute_dup", free_function = "gp11_attribute_free")]
 	public class Attribute {
 		public ulong type;
@@ -171,6 +172,8 @@
 
 	public class Object : GLib.Object {
 		public static Object from_handle(Session session, uint handle);
+		[CCode (cname = "gp11_objects_from_handle_array")]
+		public static GLib.List<Object> from_handle_array(Session session, GP11.Attribute attr);
 		
 		public weak Module module { get; }
 		public weak Session session { get; }

Modified: trunk/pkcs11/p11.vapi
==============================================================================
--- trunk/pkcs11/p11.vapi	(original)
+++ trunk/pkcs11/p11.vapi	Sun Aug  3 20:48:08 2008
@@ -1,11 +1,27 @@
 
-[CCode (cheader_filename = "pkcs11.h", cprefix = "", lower_case_cprefix = "")] 
+[CCode (cheader_filename = "pkcs11.h,pkcs11g.h", cprefix = "", lower_case_cprefix = "")] 
 namespace P11 {
 	const uint CKA_CLASS;
+	const uint CKA_END_DATE;
+	const uint CKA_GNOME_IMPORT_OBJECTS;
+	const uint CKA_GNOME_IMPORT_TOKEN;
+	const uint CKA_GNOME_USER_TRUST;
 	const uint CKA_ID;
+	const uint CKA_LABEL;
+	const uint CKA_START_DATE;
+	const uint CKA_TOKEN;
+	const uint CKA_VALUE;
 	
 	const ulong CKO_DATA;
 	const ulong CKO_CERTIFICATE;
 	const ulong CKO_PRIVATE_KEY;
 	const ulong CKO_PUBLIC_KEY;
+	
+	const uint CKF_RW_SESSION;
+	
+	const ulong CKR_OBJECT_HANDLE_INVALID;
+	const ulong CKR_FUNCTION_CANCELED;
+	
+	const ulong CKT_GNOME_TRUSTED;
+	const ulong CKT_GNOME_UNTRUSTED;
 }

Added: trunk/pkcs11/seahorse-pkcs11-certificate.c
==============================================================================
--- (empty file)
+++ trunk/pkcs11/seahorse-pkcs11-certificate.c	Sun Aug  3 20:48:08 2008
@@ -0,0 +1,370 @@
+
+#include "seahorse-pkcs11-certificate.h"
+#include <seahorse-types.h>
+#include <seahorse-key.h>
+#include <pkcs11.h>
+#include <pkcs11g.h>
+#include <glib/gi18n-lib.h>
+#include <seahorse-util.h>
+#include <seahorse-validity.h>
+#include <time.h>
+#include "seahorse-pkcs11.h"
+
+
+
+
+struct _SeahorsePkcs11CertificatePrivate {
+	GP11Object* _pkcs11_object;
+	GP11Attributes* _pkcs11_attributes;
+};
+
+#define SEAHORSE_PKCS11_CERTIFICATE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAHORSE_PKCS11_TYPE_CERTIFICATE, SeahorsePkcs11CertificatePrivate))
+enum  {
+	SEAHORSE_PKCS11_CERTIFICATE_DUMMY_PROPERTY,
+	SEAHORSE_PKCS11_CERTIFICATE_PKCS11_OBJECT,
+	SEAHORSE_PKCS11_CERTIFICATE_PKCS11_ATTRIBUTES,
+	SEAHORSE_PKCS11_CERTIFICATE_DISPLAY_NAME,
+	SEAHORSE_PKCS11_CERTIFICATE_DISPLAY_ID,
+	SEAHORSE_PKCS11_CERTIFICATE_MARKUP,
+	SEAHORSE_PKCS11_CERTIFICATE_SIMPLE_NAME,
+	SEAHORSE_PKCS11_CERTIFICATE_FINGERPRINT,
+	SEAHORSE_PKCS11_CERTIFICATE_VALIDITY,
+	SEAHORSE_PKCS11_CERTIFICATE_VALIDITY_STR,
+	SEAHORSE_PKCS11_CERTIFICATE_TRUST,
+	SEAHORSE_PKCS11_CERTIFICATE_TRUST_STR,
+	SEAHORSE_PKCS11_CERTIFICATE_EXPIRES,
+	SEAHORSE_PKCS11_CERTIFICATE_EXPIRES_STR,
+	SEAHORSE_PKCS11_CERTIFICATE_STOCK_ID
+};
+static void seahorse_pkcs11_certificate_rebuild (SeahorsePkcs11Certificate* self);
+static gpointer seahorse_pkcs11_certificate_parent_class = NULL;
+static void seahorse_pkcs11_certificate_dispose (GObject * obj);
+
+
+
+SeahorsePkcs11Certificate* seahorse_pkcs11_certificate_new (GP11Object* object, GP11Attributes* attributes) {
+	SeahorsePkcs11Certificate * self;
+	g_return_val_if_fail (GP11_IS_OBJECT (object), NULL);
+	g_return_val_if_fail (attributes != NULL, NULL);
+	self = g_object_newv (SEAHORSE_PKCS11_TYPE_CERTIFICATE, 0, NULL);
+	seahorse_pkcs11_certificate_set_pkcs11_object (self, object);
+	seahorse_pkcs11_certificate_set_pkcs11_attributes (self, attributes);
+	return self;
+}
+
+
+static void seahorse_pkcs11_certificate_rebuild (SeahorsePkcs11Certificate* self) {
+	g_return_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self));
+	SEAHORSE_OBJECT (self)->_id = ((GQuark) (0));
+	SEAHORSE_OBJECT (self)->_tag = SEAHORSE_PKCS11_TYPE;
+	if (self->priv->_pkcs11_attributes == NULL) {
+		SEAHORSE_OBJECT (self)->_location = SEAHORSE_LOCATION_INVALID;
+		SEAHORSE_OBJECT (self)->_usage = SEAHORSE_USAGE_NONE;
+		SEAHORSE_OBJECT (self)->_flags = ((guint) (SKEY_FLAG_DISABLED));
+	} else {
+		SEAHORSE_OBJECT (self)->_id = seahorse_pkcs11_id_from_attributes (self->priv->_pkcs11_attributes);
+		SEAHORSE_OBJECT (self)->_location = SEAHORSE_LOCATION_LOCAL;
+		SEAHORSE_OBJECT (self)->_usage = SEAHORSE_USAGE_PUBLIC_KEY;
+		SEAHORSE_OBJECT (self)->_flags = ((guint) (0));
+		/* TODO: Expiry, revoked, disabled etc... */
+		if (seahorse_pkcs11_certificate_get_trust (self) >= ((gint) (SEAHORSE_VALIDITY_MARGINAL))) {
+			SEAHORSE_OBJECT (self)->_flags = SEAHORSE_OBJECT (self)->_flags | (SKEY_FLAG_TRUSTED);
+		}
+	}
+	seahorse_object_fire_changed (SEAHORSE_OBJECT (self), SEAHORSE_OBJECT_CHANGE_ALL);
+}
+
+
+GP11Object* seahorse_pkcs11_certificate_get_pkcs11_object (SeahorsePkcs11Certificate* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self), NULL);
+	return self->priv->_pkcs11_object;
+}
+
+
+void seahorse_pkcs11_certificate_set_pkcs11_object (SeahorsePkcs11Certificate* self, GP11Object* value) {
+	GP11Object* _tmp2;
+	GP11Object* _tmp1;
+	g_return_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self));
+	_tmp2 = NULL;
+	_tmp1 = NULL;
+	self->priv->_pkcs11_object = (_tmp2 = (_tmp1 = value, (_tmp1 == NULL ? NULL : g_object_ref (_tmp1))), (self->priv->_pkcs11_object == NULL ? NULL : (self->priv->_pkcs11_object = (g_object_unref (self->priv->_pkcs11_object), NULL))), _tmp2);
+	g_object_notify (((GObject *) (self)), "pkcs11-object");
+}
+
+
+GP11Attributes* seahorse_pkcs11_certificate_get_pkcs11_attributes (SeahorsePkcs11Certificate* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self), NULL);
+	return self->priv->_pkcs11_attributes;
+}
+
+
+void seahorse_pkcs11_certificate_set_pkcs11_attributes (SeahorsePkcs11Certificate* self, GP11Attributes* value) {
+	GP11Attributes* _tmp2;
+	GP11Attributes* _tmp1;
+	g_return_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self));
+	_tmp2 = NULL;
+	_tmp1 = NULL;
+	self->priv->_pkcs11_attributes = (_tmp2 = (_tmp1 = value, (_tmp1 == NULL ? NULL : gp11_attributes_ref (_tmp1))), (self->priv->_pkcs11_attributes == NULL ? NULL : (self->priv->_pkcs11_attributes = (gp11_attributes_unref (self->priv->_pkcs11_attributes), NULL))), _tmp2);
+	seahorse_pkcs11_certificate_rebuild (self);
+	g_object_notify (((GObject *) (self)), "pkcs11-attributes");
+}
+
+
+static char* seahorse_pkcs11_certificate_real_get_display_name (SeahorsePkcs11Certificate* self) {
+	const char* _tmp4;
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self), NULL);
+	if (self->priv->_pkcs11_attributes != NULL) {
+		char* label;
+		char* _tmp2;
+		gboolean _tmp1;
+		char* _tmp0;
+		label = NULL;
+		_tmp2 = NULL;
+		_tmp0 = NULL;
+		if ((_tmp1 = gp11_attributes_find_string (self->priv->_pkcs11_attributes, CKA_LABEL, &_tmp0), label = (_tmp2 = _tmp0, (label = (g_free (label), NULL)), _tmp2), _tmp1)) {
+			return label;
+		}
+		label = (g_free (label), NULL);
+	}
+	/* TODO: Calculate something from the subject? */
+	_tmp4 = NULL;
+	return (_tmp4 = _ ("Certificate"), (_tmp4 == NULL ? NULL : g_strdup (_tmp4)));
+}
+
+
+char* seahorse_pkcs11_certificate_get_display_id (SeahorsePkcs11Certificate* self) {
+	const char* _tmp0;
+	char* id;
+	char* _tmp2;
+	char* _tmp3;
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self), NULL);
+	_tmp0 = NULL;
+	id = (_tmp0 = seahorse_pkcs11_certificate_get_fingerprint (self), (_tmp0 == NULL ? NULL : g_strdup (_tmp0)));
+	if (g_utf8_strlen (id, -1) <= 8) {
+		return id;
+	}
+	_tmp2 = NULL;
+	_tmp3 = NULL;
+	return (_tmp3 = (_tmp2 = g_utf8_offset_to_pointer (id, g_utf8_strlen (id, -1) - 8), g_strndup (_tmp2, g_utf8_offset_to_pointer (_tmp2, ((glong) (8))) - _tmp2)), (id = (g_free (id), NULL)), _tmp3);
+}
+
+
+static char* seahorse_pkcs11_certificate_real_get_markup (SeahorsePkcs11Certificate* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self), NULL);
+	return g_markup_escape_text (seahorse_object_get_display_name (SEAHORSE_OBJECT (self)), -1);
+}
+
+
+const char* seahorse_pkcs11_certificate_get_simple_name (SeahorsePkcs11Certificate* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self), NULL);
+	return seahorse_object_get_display_name (SEAHORSE_OBJECT (self));
+}
+
+
+char* seahorse_pkcs11_certificate_get_fingerprint (SeahorsePkcs11Certificate* self) {
+	GP11Attribute* attr;
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self), NULL);
+	/* TODO: We should be using the fingerprint off the key */
+	if (self->priv->_pkcs11_attributes == NULL) {
+		return g_strdup ("");
+	}
+	attr = gp11_attributes_find (self->priv->_pkcs11_attributes, CKA_ID);
+	if (attr == NULL) {
+		return g_strdup ("");
+	}
+	return seahorse_util_hex_encode (attr->value, attr->length);
+}
+
+
+gint seahorse_pkcs11_certificate_get_validity (SeahorsePkcs11Certificate* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self), 0);
+	/* TODO: We need to implement proper validity checking */
+	;
+	return ((gint) (SEAHORSE_VALIDITY_UNKNOWN));
+}
+
+
+char* seahorse_pkcs11_certificate_get_validity_str (SeahorsePkcs11Certificate* self) {
+	const char* _tmp0;
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self), NULL);
+	_tmp0 = NULL;
+	return (_tmp0 = seahorse_validity_get_string (((SeahorseValidity) (seahorse_pkcs11_certificate_get_validity (self)))), (_tmp0 == NULL ? NULL : g_strdup (_tmp0)));
+}
+
+
+gint seahorse_pkcs11_certificate_get_trust (SeahorsePkcs11Certificate* self) {
+	gulong trust;
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self), 0);
+	trust = 0UL;
+	if (self->priv->_pkcs11_attributes == NULL || !gp11_attributes_find_ulong (self->priv->_pkcs11_attributes, CKA_GNOME_USER_TRUST, &trust)) {
+		return ((gint) (SEAHORSE_VALIDITY_UNKNOWN));
+	}
+	if (trust == CKT_GNOME_TRUSTED) {
+		return ((gint) (SEAHORSE_VALIDITY_FULL));
+	} else {
+		if (trust == CKT_GNOME_UNTRUSTED) {
+			return ((gint) (SEAHORSE_VALIDITY_NEVER));
+		}
+	}
+	return ((gint) (SEAHORSE_VALIDITY_UNKNOWN));
+}
+
+
+char* seahorse_pkcs11_certificate_get_trust_str (SeahorsePkcs11Certificate* self) {
+	const char* _tmp0;
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self), NULL);
+	_tmp0 = NULL;
+	return (_tmp0 = seahorse_validity_get_string (((SeahorseValidity) (seahorse_pkcs11_certificate_get_trust (self)))), (_tmp0 == NULL ? NULL : g_strdup (_tmp0)));
+}
+
+
+gulong seahorse_pkcs11_certificate_get_expires (SeahorsePkcs11Certificate* self) {
+	GDate date = {0};
+	struct tm time = {0};
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self), 0UL);
+	if (self->priv->_pkcs11_attributes == NULL || !gp11_attributes_find_date (self->priv->_pkcs11_attributes, CKA_END_DATE, &date)) {
+		return ((gulong) (0));
+	}
+	g_date_to_struct_tm (&date, &time);
+	return ((gulong) (mktime (&time)));
+}
+
+
+char* seahorse_pkcs11_certificate_get_expires_str (SeahorsePkcs11Certificate* self) {
+	gulong expiry;
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self), NULL);
+	/* TODO: When expired return Expired */
+	expiry = seahorse_pkcs11_certificate_get_expires (self);
+	if (expiry == 0) {
+		return g_strdup ("");
+	}
+	return seahorse_util_get_date_string (expiry);
+}
+
+
+static char* seahorse_pkcs11_certificate_real_get_stock_id (SeahorsePkcs11Certificate* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (self), NULL);
+	/* TODO: A certificate icon */
+	return g_strdup ("");
+}
+
+
+static void seahorse_pkcs11_certificate_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
+	SeahorsePkcs11Certificate * self;
+	self = SEAHORSE_PKCS11_CERTIFICATE (object);
+	switch (property_id) {
+		case SEAHORSE_PKCS11_CERTIFICATE_PKCS11_OBJECT:
+		g_value_set_object (value, seahorse_pkcs11_certificate_get_pkcs11_object (self));
+		break;
+		case SEAHORSE_PKCS11_CERTIFICATE_PKCS11_ATTRIBUTES:
+		g_value_set_pointer (value, seahorse_pkcs11_certificate_get_pkcs11_attributes (self));
+		break;
+		case SEAHORSE_PKCS11_CERTIFICATE_DISPLAY_NAME:
+		g_value_set_string (value, seahorse_pkcs11_certificate_real_get_display_name (self));
+		break;
+		case SEAHORSE_PKCS11_CERTIFICATE_DISPLAY_ID:
+		g_value_set_string (value, seahorse_pkcs11_certificate_get_display_id (self));
+		break;
+		case SEAHORSE_PKCS11_CERTIFICATE_MARKUP:
+		g_value_set_string (value, seahorse_pkcs11_certificate_real_get_markup (self));
+		break;
+		case SEAHORSE_PKCS11_CERTIFICATE_SIMPLE_NAME:
+		g_value_set_string (value, seahorse_pkcs11_certificate_get_simple_name (self));
+		break;
+		case SEAHORSE_PKCS11_CERTIFICATE_FINGERPRINT:
+		g_value_set_string (value, seahorse_pkcs11_certificate_get_fingerprint (self));
+		break;
+		case SEAHORSE_PKCS11_CERTIFICATE_VALIDITY:
+		g_value_set_int (value, seahorse_pkcs11_certificate_get_validity (self));
+		break;
+		case SEAHORSE_PKCS11_CERTIFICATE_VALIDITY_STR:
+		g_value_set_string (value, seahorse_pkcs11_certificate_get_validity_str (self));
+		break;
+		case SEAHORSE_PKCS11_CERTIFICATE_TRUST:
+		g_value_set_int (value, seahorse_pkcs11_certificate_get_trust (self));
+		break;
+		case SEAHORSE_PKCS11_CERTIFICATE_TRUST_STR:
+		g_value_set_string (value, seahorse_pkcs11_certificate_get_trust_str (self));
+		break;
+		case SEAHORSE_PKCS11_CERTIFICATE_EXPIRES:
+		g_value_set_ulong (value, seahorse_pkcs11_certificate_get_expires (self));
+		break;
+		case SEAHORSE_PKCS11_CERTIFICATE_EXPIRES_STR:
+		g_value_set_string (value, seahorse_pkcs11_certificate_get_expires_str (self));
+		break;
+		case SEAHORSE_PKCS11_CERTIFICATE_STOCK_ID:
+		g_value_set_string (value, seahorse_pkcs11_certificate_real_get_stock_id (self));
+		break;
+		default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+
+static void seahorse_pkcs11_certificate_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
+	SeahorsePkcs11Certificate * self;
+	self = SEAHORSE_PKCS11_CERTIFICATE (object);
+	switch (property_id) {
+		case SEAHORSE_PKCS11_CERTIFICATE_PKCS11_OBJECT:
+		seahorse_pkcs11_certificate_set_pkcs11_object (self, g_value_get_object (value));
+		break;
+		case SEAHORSE_PKCS11_CERTIFICATE_PKCS11_ATTRIBUTES:
+		seahorse_pkcs11_certificate_set_pkcs11_attributes (self, g_value_get_pointer (value));
+		break;
+		default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+
+static void seahorse_pkcs11_certificate_class_init (SeahorsePkcs11CertificateClass * klass) {
+	seahorse_pkcs11_certificate_parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (SeahorsePkcs11CertificatePrivate));
+	G_OBJECT_CLASS (klass)->get_property = seahorse_pkcs11_certificate_get_property;
+	G_OBJECT_CLASS (klass)->set_property = seahorse_pkcs11_certificate_set_property;
+	G_OBJECT_CLASS (klass)->dispose = seahorse_pkcs11_certificate_dispose;
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_CERTIFICATE_PKCS11_OBJECT, g_param_spec_object ("pkcs11-object", "pkcs11-object", "pkcs11-object", GP11_TYPE_OBJECT, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_CERTIFICATE_PKCS11_ATTRIBUTES, g_param_spec_pointer ("pkcs11-attributes", "pkcs11-attributes", "pkcs11-attributes", G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE));
+	g_object_class_override_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_CERTIFICATE_DISPLAY_NAME, "display-name");
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_CERTIFICATE_DISPLAY_ID, g_param_spec_string ("display-id", "display-id", "display-id", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+	g_object_class_override_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_CERTIFICATE_MARKUP, "markup");
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_CERTIFICATE_SIMPLE_NAME, g_param_spec_string ("simple-name", "simple-name", "simple-name", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_CERTIFICATE_FINGERPRINT, g_param_spec_string ("fingerprint", "fingerprint", "fingerprint", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_CERTIFICATE_VALIDITY, g_param_spec_int ("validity", "validity", "validity", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_CERTIFICATE_VALIDITY_STR, g_param_spec_string ("validity-str", "validity-str", "validity-str", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_CERTIFICATE_TRUST, g_param_spec_int ("trust", "trust", "trust", G_MININT, G_MAXINT, 0, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_CERTIFICATE_TRUST_STR, g_param_spec_string ("trust-str", "trust-str", "trust-str", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_CERTIFICATE_EXPIRES, g_param_spec_ulong ("expires", "expires", "expires", 0, G_MAXULONG, 0UL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_CERTIFICATE_EXPIRES_STR, g_param_spec_string ("expires-str", "expires-str", "expires-str", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+	g_object_class_override_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_CERTIFICATE_STOCK_ID, "stock-id");
+}
+
+
+static void seahorse_pkcs11_certificate_instance_init (SeahorsePkcs11Certificate * self) {
+	self->priv = SEAHORSE_PKCS11_CERTIFICATE_GET_PRIVATE (self);
+}
+
+
+static void seahorse_pkcs11_certificate_dispose (GObject * obj) {
+	SeahorsePkcs11Certificate * self;
+	self = SEAHORSE_PKCS11_CERTIFICATE (obj);
+	(self->priv->_pkcs11_object == NULL ? NULL : (self->priv->_pkcs11_object = (g_object_unref (self->priv->_pkcs11_object), NULL)));
+	(self->priv->_pkcs11_attributes == NULL ? NULL : (self->priv->_pkcs11_attributes = (gp11_attributes_unref (self->priv->_pkcs11_attributes), NULL)));
+	G_OBJECT_CLASS (seahorse_pkcs11_certificate_parent_class)->dispose (obj);
+}
+
+
+GType seahorse_pkcs11_certificate_get_type (void) {
+	static GType seahorse_pkcs11_certificate_type_id = 0;
+	if (G_UNLIKELY (seahorse_pkcs11_certificate_type_id == 0)) {
+		static const GTypeInfo g_define_type_info = { sizeof (SeahorsePkcs11CertificateClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) seahorse_pkcs11_certificate_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SeahorsePkcs11Certificate), 0, (GInstanceInitFunc) seahorse_pkcs11_certificate_instance_init };
+		seahorse_pkcs11_certificate_type_id = g_type_register_static (SEAHORSE_TYPE_OBJECT, "SeahorsePkcs11Certificate", &g_define_type_info, 0);
+	}
+	return seahorse_pkcs11_certificate_type_id;
+}
+
+
+
+

Added: trunk/pkcs11/seahorse-pkcs11-certificate.h
==============================================================================
--- (empty file)
+++ trunk/pkcs11/seahorse-pkcs11-certificate.h	Sun Aug  3 20:48:08 2008
@@ -0,0 +1,55 @@
+
+#ifndef __SEAHORSE_PKCS11_CERTIFICATE_H__
+#define __SEAHORSE_PKCS11_CERTIFICATE_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <seahorse-object.h>
+#include <gp11.h>
+#include <stdlib.h>
+#include <string.h>
+
+G_BEGIN_DECLS
+
+
+#define SEAHORSE_PKCS11_TYPE_CERTIFICATE (seahorse_pkcs11_certificate_get_type ())
+#define SEAHORSE_PKCS11_CERTIFICATE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_PKCS11_TYPE_CERTIFICATE, SeahorsePkcs11Certificate))
+#define SEAHORSE_PKCS11_CERTIFICATE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_PKCS11_TYPE_CERTIFICATE, SeahorsePkcs11CertificateClass))
+#define SEAHORSE_PKCS11_IS_CERTIFICATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_PKCS11_TYPE_CERTIFICATE))
+#define SEAHORSE_PKCS11_IS_CERTIFICATE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_PKCS11_TYPE_CERTIFICATE))
+#define SEAHORSE_PKCS11_CERTIFICATE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_PKCS11_TYPE_CERTIFICATE, SeahorsePkcs11CertificateClass))
+
+typedef struct _SeahorsePkcs11Certificate SeahorsePkcs11Certificate;
+typedef struct _SeahorsePkcs11CertificateClass SeahorsePkcs11CertificateClass;
+typedef struct _SeahorsePkcs11CertificatePrivate SeahorsePkcs11CertificatePrivate;
+
+struct _SeahorsePkcs11Certificate {
+	SeahorseObject parent_instance;
+	SeahorsePkcs11CertificatePrivate * priv;
+};
+
+struct _SeahorsePkcs11CertificateClass {
+	SeahorseObjectClass parent_class;
+};
+
+
+SeahorsePkcs11Certificate* seahorse_pkcs11_certificate_new (GP11Object* object, GP11Attributes* attributes);
+GP11Object* seahorse_pkcs11_certificate_get_pkcs11_object (SeahorsePkcs11Certificate* self);
+void seahorse_pkcs11_certificate_set_pkcs11_object (SeahorsePkcs11Certificate* self, GP11Object* value);
+GP11Attributes* seahorse_pkcs11_certificate_get_pkcs11_attributes (SeahorsePkcs11Certificate* self);
+void seahorse_pkcs11_certificate_set_pkcs11_attributes (SeahorsePkcs11Certificate* self, GP11Attributes* value);
+char* seahorse_pkcs11_certificate_get_display_id (SeahorsePkcs11Certificate* self);
+const char* seahorse_pkcs11_certificate_get_simple_name (SeahorsePkcs11Certificate* self);
+char* seahorse_pkcs11_certificate_get_fingerprint (SeahorsePkcs11Certificate* self);
+gint seahorse_pkcs11_certificate_get_validity (SeahorsePkcs11Certificate* self);
+char* seahorse_pkcs11_certificate_get_validity_str (SeahorsePkcs11Certificate* self);
+gint seahorse_pkcs11_certificate_get_trust (SeahorsePkcs11Certificate* self);
+char* seahorse_pkcs11_certificate_get_trust_str (SeahorsePkcs11Certificate* self);
+gulong seahorse_pkcs11_certificate_get_expires (SeahorsePkcs11Certificate* self);
+char* seahorse_pkcs11_certificate_get_expires_str (SeahorsePkcs11Certificate* self);
+GType seahorse_pkcs11_certificate_get_type (void);
+
+
+G_END_DECLS
+
+#endif

Added: trunk/pkcs11/seahorse-pkcs11-certificate.vala
==============================================================================
--- (empty file)
+++ trunk/pkcs11/seahorse-pkcs11-certificate.vala	Sun Aug  3 20:48:08 2008
@@ -0,0 +1,145 @@
+
+namespace Seahorse.Pkcs11 {
+	public class Certificate : Seahorse.Object {
+
+		private GP11.Object? _pkcs11_object;
+		public GP11.Object pkcs11_object {
+			get { return _pkcs11_object; }
+			set { _pkcs11_object = value; }
+		}
+		
+		private GP11.Attributes? _pkcs11_attributes;
+		public GP11.Attributes pkcs11_attributes {
+			get { return _pkcs11_attributes; }
+			set { _pkcs11_attributes = value; rebuild(); }
+		}
+		
+		public override string# display_name {
+			get { 
+				if (_pkcs11_attributes != null) {
+					string label;
+					if (_pkcs11_attributes.find_string(P11.CKA_LABEL, out label))
+						return label;
+				}
+				
+				/* TODO: Calculate something from the subject? */
+				return _("Certificate");
+			}
+		}
+		
+		public string# display_id {
+			get { 
+				string id = fingerprint;
+				if(id.len() <= 8)
+					return id;
+				return id.substring(id.len() - 8, 8);
+			}
+		}
+
+		public override string# markup {
+			get { return GLib.Markup.escape_text(display_name); }
+		}
+		
+		public string simple_name {
+			get { return display_name; }
+		}
+		
+		public string# fingerprint {
+			get {
+				/* TODO: We should be using the fingerprint off the key */
+				if (_pkcs11_attributes == null)
+					return "";
+				weak GP11.Attribute? attr = _pkcs11_attributes.find(P11.CKA_ID);
+				if (attr == null)
+					return "";
+				return Util.hex_encode(attr.value, attr.length);
+			}
+		}
+		
+		public int validity { 
+			get { 
+				/* TODO: We need to implement proper validity checking */; 
+				return Validity.UNKNOWN;
+			}
+		}
+		
+		public string# validity_str {
+			get { return Util.validity_to_string((Seahorse.Validity)validity); }
+		}
+
+		public int trust {
+			get { 
+				ulong trust;
+				if (_pkcs11_attributes == null ||
+				    !_pkcs11_attributes.find_ulong(P11.CKA_GNOME_USER_TRUST, out trust))
+					return Validity.UNKNOWN;
+				if (trust == P11.CKT_GNOME_TRUSTED)
+					return Validity.FULL;
+				else if (trust == P11.CKT_GNOME_UNTRUSTED)
+					return Validity.NEVER;
+				return Validity.UNKNOWN;
+			}
+		}
+		
+		public string# trust_str {
+			get { return Util.validity_to_string((Seahorse.Validity)trust); }
+		}
+
+		public ulong expires {
+			get { 
+				GLib.Date date;
+				if (_pkcs11_attributes == null ||
+				    !_pkcs11_attributes.find_date(P11.CKA_END_DATE, out date))
+					return 0;
+				Time time;
+				date.to_time(out time);
+				return (ulong)time.mktime();
+			}
+		}
+		
+		public string# expires_str {
+			get { 	
+				/* TODO: When expired return Expired */
+				ulong expiry = expires;
+				if (expiry == 0)
+					return "";
+				return Util.get_date_string(expiry);
+			}
+		}
+
+		public override weak string# stock_id {
+			get {
+				/* TODO: A certificate icon */
+				return ""; 
+			}
+		}
+		
+		public Certificate(GP11.Object object, GP11.Attributes attributes) {
+			this.pkcs11_object = object;
+			this.pkcs11_attributes = attributes;
+		}
+		
+		private void rebuild() {
+			_id = 0;
+			_tag = Pkcs11.TYPE;
+			
+			if (_pkcs11_attributes == null) {
+				_location = Location.INVALID;
+				_usage = Usage.NONE;
+				_flags = Key.Flag.DISABLED;
+			} else {
+				_id = id_from_attributes(_pkcs11_attributes);
+				_location = Location.LOCAL;
+				_usage = Usage.PUBLIC_KEY;
+				_flags = 0;
+				
+				/* TODO: Expiry, revoked, disabled etc... */
+				
+				if (trust >= (int)Validity.MARGINAL)
+					_flags |= Key.Flag.TRUSTED;
+			}
+			
+			fire_changed(Change.ALL);
+		}
+	}
+}

Modified: trunk/pkcs11/seahorse-pkcs11-module.c
==============================================================================
--- trunk/pkcs11/seahorse-pkcs11-module.c	(original)
+++ trunk/pkcs11/seahorse-pkcs11-module.c	Sun Aug  3 20:48:08 2008
@@ -22,9 +22,47 @@
 #include "config.h"
 
 #include "seahorse-pkcs11-module.h"
+#include "seahorse-pkcs11-source.h"
 
+#include "seahorse-gconf.h"
+#include "seahorse-util.h"
+
+#include "gp11/gp11.h"
 void
 seahorse_pkcs11_module_init (void)
 {
+	SeahorseSource *source;
+	GP11Module *module;
+	GSList *l, *module_paths;
+	GList *slots, *s;
+	GError *err = NULL;
 	
+	/* Load each module in turn, and each slot for each module */
+	module_paths = seahorse_gconf_get_string_list ("/system/pkcs11/modules");
+	for (l = module_paths; l; l = g_slist_next (l)) {
+		
+		module = gp11_module_initialize (l->data, NULL, &err);
+		if (!module) {
+			g_warning ("couldn't initialize %s pkcs11 module: %s", 
+			           (gchar*)l->data, err ? err->message : NULL);
+			g_clear_error (&err);
+			continue;
+		}
+		
+		slots = gp11_module_get_slots (module, FALSE);
+		for (s = slots; s; s = g_list_next (s)) {
+			
+			source = SEAHORSE_SOURCE (seahorse_pkcs11_source_new (s->data));
+			seahorse_context_take_source (NULL, source);
+		}
+
+		/* These will have been refed by the source above */
+		gp11_list_unref_free (slots);
+		g_object_unref (module);
+	}
+
+	seahorse_util_string_slist_free (module_paths);
+
+	/* Let these register themselves */
+	g_type_class_unref (g_type_class_ref (SEAHORSE_PKCS11_TYPE_SOURCE));
 }

Added: trunk/pkcs11/seahorse-pkcs11-source.c
==============================================================================
--- (empty file)
+++ trunk/pkcs11/seahorse-pkcs11-source.c	Sun Aug  3 20:48:08 2008
@@ -0,0 +1,1560 @@
+
+#include "seahorse-pkcs11-source.h"
+#include <pkcs11.h>
+#include <pkcs11g.h>
+#include <seahorse-util.h>
+#include <glib/gi18n-lib.h>
+#include <seahorse-context.h>
+#include "seahorse-pkcs11.h"
+#include "seahorse-pkcs11-certificate.h"
+
+
+#define SEAHORSE_PKCS11_SOURCE_TYPE_UPDATER (seahorse_pkcs11_source_updater_get_type ())
+#define SEAHORSE_PKCS11_SOURCE_UPDATER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_UPDATER, SeahorsePkcs11SourceUpdater))
+#define SEAHORSE_PKCS11_SOURCE_UPDATER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_PKCS11_SOURCE_TYPE_UPDATER, SeahorsePkcs11SourceUpdaterClass))
+#define SEAHORSE_PKCS11_SOURCE_IS_UPDATER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_UPDATER))
+#define SEAHORSE_PKCS11_SOURCE_IS_UPDATER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_PKCS11_SOURCE_TYPE_UPDATER))
+#define SEAHORSE_PKCS11_SOURCE_UPDATER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_UPDATER, SeahorsePkcs11SourceUpdaterClass))
+
+typedef struct _SeahorsePkcs11SourceUpdater SeahorsePkcs11SourceUpdater;
+typedef struct _SeahorsePkcs11SourceUpdaterClass SeahorsePkcs11SourceUpdaterClass;
+typedef struct _SeahorsePkcs11SourceUpdaterPrivate SeahorsePkcs11SourceUpdaterPrivate;
+
+#define SEAHORSE_PKCS11_SOURCE_TYPE_REFRESHER (seahorse_pkcs11_source_refresher_get_type ())
+#define SEAHORSE_PKCS11_SOURCE_REFRESHER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_REFRESHER, SeahorsePkcs11SourceRefresher))
+#define SEAHORSE_PKCS11_SOURCE_REFRESHER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_PKCS11_SOURCE_TYPE_REFRESHER, SeahorsePkcs11SourceRefresherClass))
+#define SEAHORSE_PKCS11_SOURCE_IS_REFRESHER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_REFRESHER))
+#define SEAHORSE_PKCS11_SOURCE_IS_REFRESHER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_PKCS11_SOURCE_TYPE_REFRESHER))
+#define SEAHORSE_PKCS11_SOURCE_REFRESHER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_REFRESHER, SeahorsePkcs11SourceRefresherClass))
+
+typedef struct _SeahorsePkcs11SourceRefresher SeahorsePkcs11SourceRefresher;
+typedef struct _SeahorsePkcs11SourceRefresherClass SeahorsePkcs11SourceRefresherClass;
+typedef struct _SeahorsePkcs11SourceRefresherPrivate SeahorsePkcs11SourceRefresherPrivate;
+
+#define SEAHORSE_PKCS11_SOURCE_TYPE_LOADER (seahorse_pkcs11_source_loader_get_type ())
+#define SEAHORSE_PKCS11_SOURCE_LOADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_LOADER, SeahorsePkcs11SourceLoader))
+#define SEAHORSE_PKCS11_SOURCE_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_PKCS11_SOURCE_TYPE_LOADER, SeahorsePkcs11SourceLoaderClass))
+#define SEAHORSE_PKCS11_SOURCE_IS_LOADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_LOADER))
+#define SEAHORSE_PKCS11_SOURCE_IS_LOADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_PKCS11_SOURCE_TYPE_LOADER))
+#define SEAHORSE_PKCS11_SOURCE_LOADER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_LOADER, SeahorsePkcs11SourceLoaderClass))
+
+typedef struct _SeahorsePkcs11SourceLoader SeahorsePkcs11SourceLoader;
+typedef struct _SeahorsePkcs11SourceLoaderClass SeahorsePkcs11SourceLoaderClass;
+typedef struct _SeahorsePkcs11SourceLoaderPrivate SeahorsePkcs11SourceLoaderPrivate;
+
+#define SEAHORSE_PKCS11_SOURCE_TYPE_IMPORTER (seahorse_pkcs11_source_importer_get_type ())
+#define SEAHORSE_PKCS11_SOURCE_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_IMPORTER, SeahorsePkcs11SourceImporter))
+#define SEAHORSE_PKCS11_SOURCE_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_PKCS11_SOURCE_TYPE_IMPORTER, SeahorsePkcs11SourceImporterClass))
+#define SEAHORSE_PKCS11_SOURCE_IS_IMPORTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_IMPORTER))
+#define SEAHORSE_PKCS11_SOURCE_IS_IMPORTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_PKCS11_SOURCE_TYPE_IMPORTER))
+#define SEAHORSE_PKCS11_SOURCE_IMPORTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_IMPORTER, SeahorsePkcs11SourceImporterClass))
+
+typedef struct _SeahorsePkcs11SourceImporter SeahorsePkcs11SourceImporter;
+typedef struct _SeahorsePkcs11SourceImporterClass SeahorsePkcs11SourceImporterClass;
+typedef struct _SeahorsePkcs11SourceImporterPrivate SeahorsePkcs11SourceImporterPrivate;
+
+#define SEAHORSE_PKCS11_SOURCE_TYPE_REMOVER (seahorse_pkcs11_source_remover_get_type ())
+#define SEAHORSE_PKCS11_SOURCE_REMOVER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_REMOVER, SeahorsePkcs11SourceRemover))
+#define SEAHORSE_PKCS11_SOURCE_REMOVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_PKCS11_SOURCE_TYPE_REMOVER, SeahorsePkcs11SourceRemoverClass))
+#define SEAHORSE_PKCS11_SOURCE_IS_REMOVER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_REMOVER))
+#define SEAHORSE_PKCS11_SOURCE_IS_REMOVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_PKCS11_SOURCE_TYPE_REMOVER))
+#define SEAHORSE_PKCS11_SOURCE_REMOVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_PKCS11_SOURCE_TYPE_REMOVER, SeahorsePkcs11SourceRemoverClass))
+
+typedef struct _SeahorsePkcs11SourceRemover SeahorsePkcs11SourceRemover;
+typedef struct _SeahorsePkcs11SourceRemoverClass SeahorsePkcs11SourceRemoverClass;
+typedef struct _SeahorsePkcs11SourceRemoverPrivate SeahorsePkcs11SourceRemoverPrivate;
+
+/* ------------------------------------------------------------------------------
+ * Base class for several operations that all load objects (refresh, load, import)
+ */
+struct _SeahorsePkcs11SourceUpdater {
+	SeahorseOperation parent_instance;
+	SeahorsePkcs11SourceUpdaterPrivate * priv;
+	SeahorsePkcs11Source* _source;
+	GP11Session* _session;
+};
+
+struct _SeahorsePkcs11SourceUpdaterClass {
+	SeahorseOperationClass parent_class;
+	void (*load_objects) (SeahorsePkcs11SourceUpdater* self);
+};
+
+/* ------------------------------------------------------------------------------- 
+ * REFRESH OPREATION
+ */
+struct _SeahorsePkcs11SourceRefresher {
+	SeahorsePkcs11SourceUpdater parent_instance;
+	SeahorsePkcs11SourceRefresherPrivate * priv;
+};
+
+struct _SeahorsePkcs11SourceRefresherClass {
+	SeahorsePkcs11SourceUpdaterClass parent_class;
+};
+
+/* ------------------------------------------------------------------------------- 
+ * LOAD OPREATION
+ */
+struct _SeahorsePkcs11SourceLoader {
+	SeahorsePkcs11SourceUpdater parent_instance;
+	SeahorsePkcs11SourceLoaderPrivate * priv;
+};
+
+struct _SeahorsePkcs11SourceLoaderClass {
+	SeahorsePkcs11SourceUpdaterClass parent_class;
+};
+
+/* ------------------------------------------------------------------------------- 
+ * IMPORT OPREATION
+ */
+struct _SeahorsePkcs11SourceImporter {
+	SeahorsePkcs11SourceUpdater parent_instance;
+	SeahorsePkcs11SourceImporterPrivate * priv;
+};
+
+struct _SeahorsePkcs11SourceImporterClass {
+	SeahorsePkcs11SourceUpdaterClass parent_class;
+};
+
+/* ------------------------------------------------------------------------------- 
+ * REMOVE OPREATION
+ */
+struct _SeahorsePkcs11SourceRemover {
+	SeahorseOperation parent_instance;
+	SeahorsePkcs11SourceRemoverPrivate * priv;
+};
+
+struct _SeahorsePkcs11SourceRemoverClass {
+	SeahorseOperationClass parent_class;
+};
+
+
+
+struct _SeahorsePkcs11SourcePrivate {
+	GP11Slot* _slot;
+};
+
+#define SEAHORSE_PKCS11_SOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAHORSE_PKCS11_TYPE_SOURCE, SeahorsePkcs11SourcePrivate))
+enum  {
+	SEAHORSE_PKCS11_SOURCE_DUMMY_PROPERTY,
+	SEAHORSE_PKCS11_SOURCE_SLOT,
+	SEAHORSE_PKCS11_SOURCE_LOCATION,
+	SEAHORSE_PKCS11_SOURCE_KEY_TYPE,
+	SEAHORSE_PKCS11_SOURCE_KEY_DESC
+};
+static SeahorseOperation* seahorse_pkcs11_source_real_load (SeahorseSource* base, GQuark id);
+static SeahorseOperation* seahorse_pkcs11_source_real_import (SeahorsePkcs11Source* self, GInputStream* input);
+static SeahorseOperation* seahorse_pkcs11_source_real_export (SeahorsePkcs11Source* self, GList* objects, GOutputStream* output);
+static SeahorseOperation* seahorse_pkcs11_source_real_remove (SeahorsePkcs11Source* self, SeahorseObject* object);
+static void seahorse_pkcs11_source_receive_object (SeahorsePkcs11Source* self, GP11Object* object, GP11Attributes* attrs);
+static void seahorse_pkcs11_source_set_slot (SeahorsePkcs11Source* self, GP11Slot* value);
+struct _SeahorsePkcs11SourceUpdaterPrivate {
+	GCancellable* _cancellable;
+	GList* _objects;
+	gint _total;
+};
+
+#define SEAHORSE_PKCS11_SOURCE_UPDATER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAHORSE_PKCS11_SOURCE_TYPE_UPDATER, SeahorsePkcs11SourceUpdaterPrivate))
+enum  {
+	SEAHORSE_PKCS11_SOURCE_UPDATER_DUMMY_PROPERTY,
+	SEAHORSE_PKCS11_SOURCE_UPDATER_CANCELLABLE,
+	SEAHORSE_PKCS11_SOURCE_UPDATER_SOURCE
+};
+static void _g_list_free_g_object_unref (GList* self);
+static void seahorse_pkcs11_source_updater_complete (SeahorsePkcs11SourceUpdater* self, GError* err);
+static void seahorse_pkcs11_source_updater_on_open_session (SeahorsePkcs11SourceUpdater* self, GObject* obj, GAsyncResult* result);
+static void seahorse_pkcs11_source_updater_real_load_objects (SeahorsePkcs11SourceUpdater* self);
+static void seahorse_pkcs11_source_updater_load_objects (SeahorsePkcs11SourceUpdater* self);
+static void seahorse_pkcs11_source_updater_loaded_objects (SeahorsePkcs11SourceUpdater* self, GList* objects);
+static void _seahorse_pkcs11_source_updater_on_get_attributes_gasync_ready_callback (GObject* source_object, GAsyncResult* res, gpointer self);
+static void seahorse_pkcs11_source_updater_do_get_attributes (SeahorsePkcs11SourceUpdater* self);
+static void seahorse_pkcs11_source_updater_on_get_attributes (SeahorsePkcs11SourceUpdater* self, GObject* obj, GAsyncResult* result);
+static void seahorse_pkcs11_source_updater_real_cancel (SeahorseOperation* base);
+static GCancellable* seahorse_pkcs11_source_updater_get_cancellable (SeahorsePkcs11SourceUpdater* self);
+static SeahorsePkcs11Source* seahorse_pkcs11_source_updater_get_source (SeahorsePkcs11SourceUpdater* self);
+static void seahorse_pkcs11_source_updater_set_source (SeahorsePkcs11SourceUpdater* self, SeahorsePkcs11Source* value);
+static void _seahorse_pkcs11_source_updater_on_open_session_gasync_ready_callback (GObject* source_object, GAsyncResult* res, gpointer self);
+static GObject * seahorse_pkcs11_source_updater_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties);
+static gpointer seahorse_pkcs11_source_updater_parent_class = NULL;
+static void seahorse_pkcs11_source_updater_dispose (GObject * obj);
+static GType seahorse_pkcs11_source_updater_get_type (void);
+struct _SeahorsePkcs11SourceRefresherPrivate {
+	GHashTable* _checks;
+};
+
+#define SEAHORSE_PKCS11_SOURCE_REFRESHER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAHORSE_PKCS11_SOURCE_TYPE_REFRESHER, SeahorsePkcs11SourceRefresherPrivate))
+enum  {
+	SEAHORSE_PKCS11_SOURCE_REFRESHER_DUMMY_PROPERTY
+};
+static SeahorsePkcs11SourceRefresher* seahorse_pkcs11_source_refresher_new (SeahorsePkcs11Source* source);
+static void _seahorse_pkcs11_source_refresher_on_find_objects_gasync_ready_callback (GObject* source_object, GAsyncResult* res, gpointer self);
+static void seahorse_pkcs11_source_refresher_real_load_objects (SeahorsePkcs11SourceUpdater* base);
+static void __lambda0 (void* k, void* v, SeahorsePkcs11SourceRefresher* self);
+static void ___lambda0_gh_func (void* key, void* value, gpointer self);
+static void seahorse_pkcs11_source_refresher_on_find_objects (SeahorsePkcs11SourceRefresher* self, GObject* obj, GAsyncResult* result);
+static GObject * seahorse_pkcs11_source_refresher_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties);
+static gpointer seahorse_pkcs11_source_refresher_parent_class = NULL;
+static void seahorse_pkcs11_source_refresher_dispose (GObject * obj);
+static GType seahorse_pkcs11_source_refresher_get_type (void);
+struct _SeahorsePkcs11SourceLoaderPrivate {
+	GP11Attributes* _unique_attrs;
+};
+
+#define SEAHORSE_PKCS11_SOURCE_LOADER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAHORSE_PKCS11_SOURCE_TYPE_LOADER, SeahorsePkcs11SourceLoaderPrivate))
+enum  {
+	SEAHORSE_PKCS11_SOURCE_LOADER_DUMMY_PROPERTY,
+	SEAHORSE_PKCS11_SOURCE_LOADER_UNIQUE_ATTRS
+};
+static SeahorsePkcs11SourceLoader* seahorse_pkcs11_source_loader_new (SeahorsePkcs11Source* source, GP11Attributes* unique_attrs);
+static void _seahorse_pkcs11_source_loader_on_find_objects_gasync_ready_callback (GObject* source_object, GAsyncResult* res, gpointer self);
+static void seahorse_pkcs11_source_loader_real_load_objects (SeahorsePkcs11SourceUpdater* base);
+static void seahorse_pkcs11_source_loader_on_find_objects (SeahorsePkcs11SourceLoader* self, GObject* obj, GAsyncResult* result);
+static GP11Attributes* seahorse_pkcs11_source_loader_get_unique_attrs (SeahorsePkcs11SourceLoader* self);
+static void seahorse_pkcs11_source_loader_set_unique_attrs (SeahorsePkcs11SourceLoader* self, GP11Attributes* value);
+static gpointer seahorse_pkcs11_source_loader_parent_class = NULL;
+static void seahorse_pkcs11_source_loader_dispose (GObject * obj);
+static GType seahorse_pkcs11_source_loader_get_type (void);
+struct _SeahorsePkcs11SourceImporterPrivate {
+	GP11Attributes* _import_data;
+};
+
+#define SEAHORSE_PKCS11_SOURCE_IMPORTER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAHORSE_PKCS11_SOURCE_TYPE_IMPORTER, SeahorsePkcs11SourceImporterPrivate))
+enum  {
+	SEAHORSE_PKCS11_SOURCE_IMPORTER_DUMMY_PROPERTY,
+	SEAHORSE_PKCS11_SOURCE_IMPORTER_IMPORT_DATA
+};
+static SeahorsePkcs11SourceImporter* seahorse_pkcs11_source_importer_new (SeahorsePkcs11Source* source, GP11Attributes* import);
+static void _seahorse_pkcs11_source_importer_on_create_object_gasync_ready_callback (GObject* source_object, GAsyncResult* res, gpointer self);
+static void seahorse_pkcs11_source_importer_real_load_objects (SeahorsePkcs11SourceUpdater* base);
+static void _seahorse_pkcs11_source_importer_on_get_attribute_gasync_ready_callback (GObject* source_object, GAsyncResult* res, gpointer self);
+static void seahorse_pkcs11_source_importer_on_create_object (SeahorsePkcs11SourceImporter* self, GObject* obj, GAsyncResult* result);
+static void seahorse_pkcs11_source_importer_on_get_attribute (SeahorsePkcs11SourceImporter* self, GObject* obj, GAsyncResult* result);
+static GP11Attributes* seahorse_pkcs11_source_importer_get_import_data (SeahorsePkcs11SourceImporter* self);
+static gpointer seahorse_pkcs11_source_importer_parent_class = NULL;
+static void seahorse_pkcs11_source_importer_dispose (GObject * obj);
+static GType seahorse_pkcs11_source_importer_get_type (void);
+struct _SeahorsePkcs11SourceRemoverPrivate {
+	GCancellable* _cancellable;
+	SeahorsePkcs11Source* _source;
+	SeahorsePkcs11Certificate* _certificate;
+};
+
+#define SEAHORSE_PKCS11_SOURCE_REMOVER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SEAHORSE_PKCS11_SOURCE_TYPE_REMOVER, SeahorsePkcs11SourceRemoverPrivate))
+enum  {
+	SEAHORSE_PKCS11_SOURCE_REMOVER_DUMMY_PROPERTY,
+	SEAHORSE_PKCS11_SOURCE_REMOVER_CANCELLABLE,
+	SEAHORSE_PKCS11_SOURCE_REMOVER_SOURCE,
+	SEAHORSE_PKCS11_SOURCE_REMOVER_CERTIFICATE
+};
+static SeahorsePkcs11SourceRemover* seahorse_pkcs11_source_remover_new (SeahorsePkcs11Certificate* certificate);
+static void seahorse_pkcs11_source_remover_on_destroy_object (SeahorsePkcs11SourceRemover* self, GObject* obj, GAsyncResult* result);
+static void seahorse_pkcs11_source_remover_real_cancel (SeahorseOperation* base);
+static GCancellable* seahorse_pkcs11_source_remover_get_cancellable (SeahorsePkcs11SourceRemover* self);
+static SeahorsePkcs11Source* seahorse_pkcs11_source_remover_get_source (SeahorsePkcs11SourceRemover* self);
+static void seahorse_pkcs11_source_remover_set_source (SeahorsePkcs11SourceRemover* self, SeahorsePkcs11Source* value);
+static SeahorsePkcs11Certificate* seahorse_pkcs11_source_remover_get_certificate (SeahorsePkcs11SourceRemover* self);
+static void seahorse_pkcs11_source_remover_set_certificate (SeahorsePkcs11SourceRemover* self, SeahorsePkcs11Certificate* value);
+static void _seahorse_pkcs11_source_remover_on_destroy_object_gasync_ready_callback (GObject* source_object, GAsyncResult* res, gpointer self);
+static GObject * seahorse_pkcs11_source_remover_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties);
+static gpointer seahorse_pkcs11_source_remover_parent_class = NULL;
+static void seahorse_pkcs11_source_remover_dispose (GObject * obj);
+static GType seahorse_pkcs11_source_remover_get_type (void);
+static gpointer seahorse_pkcs11_source_parent_class = NULL;
+static void seahorse_pkcs11_source_dispose (GObject * obj);
+
+static const guint SEAHORSE_PKCS11_ATTRIBUTE_TYPES[] = {CKA_LABEL, CKA_ID, CKA_CLASS, CKA_TOKEN, CKA_GNOME_USER_TRUST, CKA_START_DATE, CKA_END_DATE};
+
+
+/* ---------------------------------------------------------------------------------
+ * PUBLIC STUFF
+ */
+SeahorsePkcs11Source* seahorse_pkcs11_source_new (GP11Slot* slot) {
+	GParameter * __params;
+	GParameter * __params_it;
+	SeahorsePkcs11Source * self;
+	g_return_val_if_fail (GP11_IS_SLOT (slot), NULL);
+	__params = g_new0 (GParameter, 1);
+	__params_it = __params;
+	__params_it->name = "slot";
+	g_value_init (&__params_it->value, GP11_TYPE_SLOT);
+	g_value_set_object (&__params_it->value, slot);
+	__params_it++;
+	self = g_object_newv (SEAHORSE_PKCS11_TYPE_SOURCE, __params_it - __params, __params);
+	while (__params_it > __params) {
+		--__params_it;
+		g_value_unset (&__params_it->value);
+	}
+	g_free (__params);
+	return self;
+}
+
+
+/* ---------------------------------------------------------------------------------
+ * VIRTUAL METHODS
+ */
+static SeahorseOperation* seahorse_pkcs11_source_real_load (SeahorseSource* base, GQuark id) {
+	SeahorsePkcs11Source * self;
+	GP11Attributes* attrs;
+	self = SEAHORSE_PKCS11_SOURCE (base);
+	/* Load all objects */
+	if (id == 0) {
+		return SEAHORSE_OPERATION (seahorse_pkcs11_source_refresher_new (self));
+	}
+	/* Load only objects described by the id */
+	attrs = gp11_attributes_new ();
+	if (!seahorse_pkcs11_id_to_attributes (id, attrs)) {
+		SeahorseOperation* _tmp1;
+		_tmp1 = NULL;
+		return (_tmp1 = seahorse_operation_new_complete (g_error_new (SEAHORSE_ERROR, 0, "%s", _ ("Invalid or unrecognized object."), NULL)), (attrs == NULL ? NULL : (attrs = (gp11_attributes_unref (attrs), NULL))), _tmp1);
+	} else {
+		SeahorseOperation* _tmp2;
+		_tmp2 = NULL;
+		return (_tmp2 = SEAHORSE_OPERATION (seahorse_pkcs11_source_loader_new (self, attrs)), (attrs == NULL ? NULL : (attrs = (gp11_attributes_unref (attrs), NULL))), _tmp2);
+	}
+	(attrs == NULL ? NULL : (attrs = (gp11_attributes_unref (attrs), NULL)));
+}
+
+
+static SeahorseOperation* seahorse_pkcs11_source_real_import (SeahorsePkcs11Source* self, GInputStream* input) {
+	guchar* _tmp1;
+	gint data_length1;
+	gint _tmp0;
+	guchar* data;
+	GP11Attributes* attrs;
+	SeahorseOperation* _tmp2;
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_SOURCE (self), NULL);
+	g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL);
+	_tmp1 = NULL;
+	data = (_tmp1 = seahorse_util_read_to_memory (input, &_tmp0), data_length1 = _tmp0, _tmp1);
+	attrs = gp11_attributes_new ();
+	gp11_attributes_add_boolean (attrs, CKA_GNOME_IMPORT_TOKEN, TRUE);
+	gp11_attributes_add_data (attrs, CKA_VALUE, data, data_length1);
+	_tmp2 = NULL;
+	return (_tmp2 = SEAHORSE_OPERATION (seahorse_pkcs11_source_importer_new (self, attrs)), (data = (g_free (data), NULL)), (attrs == NULL ? NULL : (attrs = (gp11_attributes_unref (attrs), NULL))), _tmp2);
+}
+
+
+SeahorseOperation* seahorse_pkcs11_source_import (SeahorsePkcs11Source* self, GInputStream* input) {
+	return SEAHORSE_PKCS11_SOURCE_GET_CLASS (self)->import (self, input);
+}
+
+
+static SeahorseOperation* seahorse_pkcs11_source_real_export (SeahorsePkcs11Source* self, GList* objects, GOutputStream* output) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_SOURCE (self), NULL);
+	g_return_val_if_fail (objects != NULL, NULL);
+	g_return_val_if_fail (G_IS_OUTPUT_STREAM (output), NULL);
+	return seahorse_operation_new_complete (g_error_new (SEAHORSE_ERROR, 0, "%s", _ ("Exporting is not yet supported."), NULL));
+}
+
+
+SeahorseOperation* seahorse_pkcs11_source_export (SeahorsePkcs11Source* self, GList* objects, GOutputStream* output) {
+	return SEAHORSE_PKCS11_SOURCE_GET_CLASS (self)->export (self, objects, output);
+}
+
+
+static SeahorseOperation* seahorse_pkcs11_source_real_remove (SeahorsePkcs11Source* self, SeahorseObject* object) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_SOURCE (self), NULL);
+	g_return_val_if_fail (SEAHORSE_IS_OBJECT (object), NULL);
+	return SEAHORSE_OPERATION (seahorse_pkcs11_source_remover_new (SEAHORSE_PKCS11_CERTIFICATE (object)));
+}
+
+
+SeahorseOperation* seahorse_pkcs11_source_remove (SeahorsePkcs11Source* self, SeahorseObject* object) {
+	return SEAHORSE_PKCS11_SOURCE_GET_CLASS (self)->remove (self, object);
+}
+
+
+/* --------------------------------------------------------------------------------
+ * HELPER METHODS
+ */
+static void seahorse_pkcs11_source_receive_object (SeahorsePkcs11Source* self, GP11Object* object, GP11Attributes* attrs) {
+	GQuark id;
+	gboolean created;
+	SeahorsePkcs11Certificate* cert;
+	SeahorseObject* _tmp0;
+	SeahorseObject* prev;
+	SeahorsePkcs11Certificate* _tmp3;
+	g_return_if_fail (SEAHORSE_PKCS11_IS_SOURCE (self));
+	g_return_if_fail (GP11_IS_OBJECT (object));
+	g_return_if_fail (attrs != NULL);
+	/* Build up an identifier for this object */
+	id = seahorse_pkcs11_id_from_attributes (attrs);
+	g_return_if_fail (id != 0);
+	created = FALSE;
+	cert = NULL;
+	/* Look for an already present object */
+	_tmp0 = NULL;
+	prev = (_tmp0 = seahorse_context_get_object (seahorse_context_for_app (), SEAHORSE_SOURCE (self), id), (_tmp0 == NULL ? NULL : g_object_ref (_tmp0)));
+	if (prev != NULL && G_TYPE_FROM_INSTANCE (G_OBJECT (prev)) == SEAHORSE_PKCS11_TYPE_CERTIFICATE) {
+		SeahorsePkcs11Certificate* _tmp2;
+		SeahorsePkcs11Certificate* _tmp1;
+		_tmp2 = NULL;
+		_tmp1 = NULL;
+		cert = (_tmp2 = (_tmp1 = SEAHORSE_PKCS11_CERTIFICATE (prev), (_tmp1 == NULL ? NULL : g_object_ref (_tmp1))), (cert == NULL ? NULL : (cert = (g_object_unref (cert), NULL))), _tmp2);
+		seahorse_pkcs11_certificate_set_pkcs11_object (cert, object);
+		seahorse_pkcs11_certificate_set_pkcs11_attributes (cert, attrs);
+		(cert == NULL ? NULL : (cert = (g_object_unref (cert), NULL)));
+		(prev == NULL ? NULL : (prev = (g_object_unref (prev), NULL)));
+		return;
+	}
+	/* Create a new object */
+	_tmp3 = NULL;
+	cert = (_tmp3 = seahorse_pkcs11_certificate_new (object, attrs), (cert == NULL ? NULL : (cert = (g_object_unref (cert), NULL))), _tmp3);
+	seahorse_context_add_object (seahorse_context_for_app (), SEAHORSE_OBJECT (cert));
+	(cert == NULL ? NULL : (cert = (g_object_unref (cert), NULL)));
+	(prev == NULL ? NULL : (prev = (g_object_unref (prev), NULL)));
+}
+
+
+GP11Slot* seahorse_pkcs11_source_get_slot (SeahorsePkcs11Source* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_SOURCE (self), NULL);
+	return self->priv->_slot;
+}
+
+
+static void seahorse_pkcs11_source_set_slot (SeahorsePkcs11Source* self, GP11Slot* value) {
+	GP11Slot* _tmp2;
+	GP11Slot* _tmp1;
+	g_return_if_fail (SEAHORSE_PKCS11_IS_SOURCE (self));
+	_tmp2 = NULL;
+	_tmp1 = NULL;
+	self->priv->_slot = (_tmp2 = (_tmp1 = value, (_tmp1 == NULL ? NULL : g_object_ref (_tmp1))), (self->priv->_slot == NULL ? NULL : (self->priv->_slot = (g_object_unref (self->priv->_slot), NULL))), _tmp2);
+	g_object_notify (((GObject *) (self)), "slot");
+}
+
+
+SeahorseLocation seahorse_pkcs11_source_get_location (SeahorsePkcs11Source* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_SOURCE (self), 0);
+	return SEAHORSE_LOCATION_LOCAL;
+}
+
+
+GQuark seahorse_pkcs11_source_get_key_type (SeahorsePkcs11Source* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_SOURCE (self), 0U);
+	return SEAHORSE_PKCS11_TYPE;
+}
+
+
+const char* seahorse_pkcs11_source_get_key_desc (SeahorsePkcs11Source* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_SOURCE (self), NULL);
+	return _ ("X509 Certificate");
+}
+
+
+static void _g_list_free_g_object_unref (GList* self) {
+	g_list_foreach (self, ((GFunc) (g_object_unref)), NULL);
+	g_list_free (self);
+}
+
+
+static void seahorse_pkcs11_source_updater_complete (SeahorsePkcs11SourceUpdater* self, GError* err) {
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_UPDATER (self));
+	if (err == NULL) {
+		seahorse_operation_mark_done (SEAHORSE_OPERATION (self), FALSE, NULL);
+	} else {
+		if (err->code == CKR_FUNCTION_CANCELED) {
+			seahorse_operation_mark_done (SEAHORSE_OPERATION (self), TRUE, NULL);
+		} else {
+			GError* _tmp0;
+			_tmp0 = NULL;
+			seahorse_operation_mark_done (SEAHORSE_OPERATION (self), FALSE, (_tmp0 = err, (_tmp0 == NULL || g_error_copy == NULL ? ((gpointer) (_tmp0)) : g_error_copy (((gpointer) (_tmp0))))));
+		}
+	}
+}
+
+
+static void seahorse_pkcs11_source_updater_on_open_session (SeahorsePkcs11SourceUpdater* self, GObject* obj, GAsyncResult* result) {
+	GError * inner_error;
+	GP11Slot* _tmp0;
+	GP11Slot* slot;
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_UPDATER (self));
+	g_return_if_fail (G_IS_OBJECT (obj));
+	g_return_if_fail (G_IS_ASYNC_RESULT (result));
+	inner_error = NULL;
+	_tmp0 = NULL;
+	slot = (_tmp0 = GP11_SLOT (obj), (_tmp0 == NULL ? NULL : g_object_ref (_tmp0)));
+	{
+		GP11Session* _tmp1;
+		_tmp1 = NULL;
+		self->_session = (_tmp1 = gp11_slot_open_session_finish (slot, result, &inner_error), (self->_session == NULL ? NULL : (self->_session = (g_object_unref (self->_session), NULL))), _tmp1);
+		if (inner_error != NULL) {
+			goto __catch0_g_error;
+		}
+	}
+	goto __finally0;
+	__catch0_g_error:
+	{
+		GError * err;
+		err = inner_error;
+		inner_error = NULL;
+		{
+			seahorse_pkcs11_source_updater_complete (self, err);
+			(err == NULL ? NULL : (err = (g_error_free (err), NULL)));
+			(slot == NULL ? NULL : (slot = (g_object_unref (slot), NULL)));
+			return;
+		}
+	}
+	__finally0:
+	;
+	/* Step 2. Load all the objects that we want */
+	seahorse_pkcs11_source_updater_load_objects (self);
+	(slot == NULL ? NULL : (slot = (g_object_unref (slot), NULL)));
+}
+
+
+static void seahorse_pkcs11_source_updater_real_load_objects (SeahorsePkcs11SourceUpdater* self) {
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_UPDATER (self));
+	g_critical ("Type `%s' does not implement abstract method `seahorse_pkcs11_source_updater_load_objects'", g_type_name (G_TYPE_FROM_INSTANCE (self)));
+	return;
+}
+
+
+static void seahorse_pkcs11_source_updater_load_objects (SeahorsePkcs11SourceUpdater* self) {
+	SEAHORSE_PKCS11_SOURCE_UPDATER_GET_CLASS (self)->load_objects (self);
+}
+
+
+static void seahorse_pkcs11_source_updater_loaded_objects (SeahorsePkcs11SourceUpdater* self, GList* objects) {
+	GList* _tmp0;
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_UPDATER (self));
+	g_return_if_fail (objects != NULL);
+	_tmp0 = NULL;
+	self->priv->_objects = (_tmp0 = NULL, (self->priv->_objects == NULL ? NULL : (self->priv->_objects = (_g_list_free_g_object_unref (self->priv->_objects), NULL))), _tmp0);
+	{
+		GList* object_collection;
+		GList* object_it;
+		object_collection = objects;
+		for (object_it = object_collection; object_it != NULL; object_it = object_it->next) {
+			GP11Object* _tmp2;
+			GP11Object* object;
+			_tmp2 = NULL;
+			object = (_tmp2 = ((GP11Object*) (object_it->data)), (_tmp2 == NULL ? NULL : g_object_ref (_tmp2)));
+			{
+				GP11Object* _tmp1;
+				_tmp1 = NULL;
+				self->priv->_objects = g_list_append (self->priv->_objects, (_tmp1 = object, (_tmp1 == NULL ? NULL : g_object_ref (_tmp1))));
+				(object == NULL ? NULL : (object = (g_object_unref (object), NULL)));
+			}
+		}
+	}
+	self->priv->_total = ((gint) (g_list_length (self->priv->_objects)));
+	/* Step 3. Load information for each object */
+	seahorse_pkcs11_source_updater_do_get_attributes (self);
+}
+
+
+static void _seahorse_pkcs11_source_updater_on_get_attributes_gasync_ready_callback (GObject* source_object, GAsyncResult* res, gpointer self) {
+	seahorse_pkcs11_source_updater_on_get_attributes (self, source_object, res);
+}
+
+
+static void seahorse_pkcs11_source_updater_do_get_attributes (SeahorsePkcs11SourceUpdater* self) {
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_UPDATER (self));
+	/* No more objects to load? */
+	if (g_list_length (self->priv->_objects) == 0) {
+		seahorse_pkcs11_source_updater_complete (self, NULL);
+	} else {
+		GP11Object* _tmp0;
+		GP11Object* object;
+		/* Load the next object */
+		seahorse_operation_mark_progress_full (SEAHORSE_OPERATION (self), _ ("Loading..."), ((gint) (g_list_length (self->priv->_objects))) - self->priv->_total, self->priv->_total);
+		_tmp0 = NULL;
+		object = (_tmp0 = ((GP11Object*) (((GP11Object*) (self->priv->_objects->data)))), (_tmp0 == NULL ? NULL : g_object_ref (_tmp0)));
+		self->priv->_objects = g_list_remove (self->priv->_objects, object);
+		gp11_object_get_async (object, SEAHORSE_PKCS11_ATTRIBUTE_TYPES, G_N_ELEMENTS (SEAHORSE_PKCS11_ATTRIBUTE_TYPES), self->priv->_cancellable, _seahorse_pkcs11_source_updater_on_get_attributes_gasync_ready_callback, self);
+		(object == NULL ? NULL : (object = (g_object_unref (object), NULL)));
+	}
+}
+
+
+static void seahorse_pkcs11_source_updater_on_get_attributes (SeahorsePkcs11SourceUpdater* self, GObject* obj, GAsyncResult* result) {
+	GError * inner_error;
+	GP11Object* _tmp0;
+	GP11Object* object;
+	GP11Attributes* attrs;
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_UPDATER (self));
+	g_return_if_fail (G_IS_OBJECT (obj));
+	g_return_if_fail (G_IS_ASYNC_RESULT (result));
+	inner_error = NULL;
+	_tmp0 = NULL;
+	object = (_tmp0 = GP11_OBJECT (obj), (_tmp0 == NULL ? NULL : g_object_ref (_tmp0)));
+	attrs = NULL;
+	{
+		GP11Attributes* _tmp1;
+		_tmp1 = NULL;
+		attrs = (_tmp1 = gp11_object_get_finish (object, result, &inner_error), (attrs == NULL ? NULL : (attrs = (gp11_attributes_unref (attrs), NULL))), _tmp1);
+		if (inner_error != NULL) {
+			goto __catch1_g_error;
+		}
+	}
+	goto __finally1;
+	__catch1_g_error:
+	{
+		GError * err;
+		err = inner_error;
+		inner_error = NULL;
+		{
+			/* Ignore objects that have gone away */
+			if (err->code != CKR_OBJECT_HANDLE_INVALID) {
+				seahorse_pkcs11_source_updater_complete (self, err);
+				(err == NULL ? NULL : (err = (g_error_free (err), NULL)));
+				(object == NULL ? NULL : (object = (g_object_unref (object), NULL)));
+				(attrs == NULL ? NULL : (attrs = (gp11_attributes_unref (attrs), NULL)));
+				return;
+			}
+			(err == NULL ? NULL : (err = (g_error_free (err), NULL)));
+		}
+	}
+	__finally1:
+	;
+	/* Process this object */
+	seahorse_pkcs11_source_receive_object (self->_source, object, attrs);
+	/* Do the next object */
+	seahorse_pkcs11_source_updater_do_get_attributes (self);
+	(object == NULL ? NULL : (object = (g_object_unref (object), NULL)));
+	(attrs == NULL ? NULL : (attrs = (gp11_attributes_unref (attrs), NULL)));
+}
+
+
+/* Cancel the operation */
+static void seahorse_pkcs11_source_updater_real_cancel (SeahorseOperation* base) {
+	SeahorsePkcs11SourceUpdater * self;
+	self = SEAHORSE_PKCS11_SOURCE_UPDATER (base);
+	g_cancellable_cancel (self->priv->_cancellable);
+}
+
+
+static GCancellable* seahorse_pkcs11_source_updater_get_cancellable (SeahorsePkcs11SourceUpdater* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_SOURCE_IS_UPDATER (self), NULL);
+	return self->priv->_cancellable;
+}
+
+
+static SeahorsePkcs11Source* seahorse_pkcs11_source_updater_get_source (SeahorsePkcs11SourceUpdater* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_SOURCE_IS_UPDATER (self), NULL);
+	return self->_source;
+}
+
+
+static void seahorse_pkcs11_source_updater_set_source (SeahorsePkcs11SourceUpdater* self, SeahorsePkcs11Source* value) {
+	SeahorsePkcs11Source* _tmp2;
+	SeahorsePkcs11Source* _tmp1;
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_UPDATER (self));
+	_tmp2 = NULL;
+	_tmp1 = NULL;
+	self->_source = (_tmp2 = (_tmp1 = value, (_tmp1 == NULL ? NULL : g_object_ref (_tmp1))), (self->_source == NULL ? NULL : (self->_source = (g_object_unref (self->_source), NULL))), _tmp2);
+	g_object_notify (((GObject *) (self)), "source");
+}
+
+
+static void _seahorse_pkcs11_source_updater_on_open_session_gasync_ready_callback (GObject* source_object, GAsyncResult* res, gpointer self) {
+	seahorse_pkcs11_source_updater_on_open_session (self, source_object, res);
+}
+
+
+static GObject * seahorse_pkcs11_source_updater_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
+	GObject * obj;
+	SeahorsePkcs11SourceUpdaterClass * klass;
+	GObjectClass * parent_class;
+	SeahorsePkcs11SourceUpdater * self;
+	klass = SEAHORSE_PKCS11_SOURCE_UPDATER_CLASS (g_type_class_peek (SEAHORSE_PKCS11_SOURCE_TYPE_UPDATER));
+	parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
+	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
+	self = SEAHORSE_PKCS11_SOURCE_UPDATER (obj);
+	{
+		GCancellable* _tmp0;
+		GP11Session* _tmp1;
+		_tmp0 = NULL;
+		self->priv->_cancellable = (_tmp0 = g_cancellable_new (), (self->priv->_cancellable == NULL ? NULL : (self->priv->_cancellable = (g_object_unref (self->priv->_cancellable), NULL))), _tmp0);
+		_tmp1 = NULL;
+		self->_session = (_tmp1 = NULL, (self->_session == NULL ? NULL : (self->_session = (g_object_unref (self->_session), NULL))), _tmp1);
+		/* Step 1. Load the session */
+		gp11_slot_open_session_async (seahorse_pkcs11_source_get_slot (self->_source), CKF_RW_SESSION, self->priv->_cancellable, _seahorse_pkcs11_source_updater_on_open_session_gasync_ready_callback, self);
+		seahorse_operation_mark_start (SEAHORSE_OPERATION (self));
+	}
+	return obj;
+}
+
+
+static void seahorse_pkcs11_source_updater_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
+	SeahorsePkcs11SourceUpdater * self;
+	self = SEAHORSE_PKCS11_SOURCE_UPDATER (object);
+	switch (property_id) {
+		case SEAHORSE_PKCS11_SOURCE_UPDATER_CANCELLABLE:
+		g_value_set_object (value, seahorse_pkcs11_source_updater_get_cancellable (self));
+		break;
+		case SEAHORSE_PKCS11_SOURCE_UPDATER_SOURCE:
+		g_value_set_object (value, seahorse_pkcs11_source_updater_get_source (self));
+		break;
+		default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+
+static void seahorse_pkcs11_source_updater_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
+	SeahorsePkcs11SourceUpdater * self;
+	self = SEAHORSE_PKCS11_SOURCE_UPDATER (object);
+	switch (property_id) {
+		case SEAHORSE_PKCS11_SOURCE_UPDATER_SOURCE:
+		seahorse_pkcs11_source_updater_set_source (self, g_value_get_object (value));
+		break;
+		default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+
+static void seahorse_pkcs11_source_updater_class_init (SeahorsePkcs11SourceUpdaterClass * klass) {
+	seahorse_pkcs11_source_updater_parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (SeahorsePkcs11SourceUpdaterPrivate));
+	G_OBJECT_CLASS (klass)->get_property = seahorse_pkcs11_source_updater_get_property;
+	G_OBJECT_CLASS (klass)->set_property = seahorse_pkcs11_source_updater_set_property;
+	G_OBJECT_CLASS (klass)->constructor = seahorse_pkcs11_source_updater_constructor;
+	G_OBJECT_CLASS (klass)->dispose = seahorse_pkcs11_source_updater_dispose;
+	SEAHORSE_PKCS11_SOURCE_UPDATER_CLASS (klass)->load_objects = seahorse_pkcs11_source_updater_real_load_objects;
+	SEAHORSE_OPERATION_CLASS (klass)->cancel = seahorse_pkcs11_source_updater_real_cancel;
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_SOURCE_UPDATER_CANCELLABLE, g_param_spec_object ("cancellable", "cancellable", "cancellable", G_TYPE_CANCELLABLE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_SOURCE_UPDATER_SOURCE, g_param_spec_object ("source", "source", "source", SEAHORSE_PKCS11_TYPE_SOURCE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+
+static void seahorse_pkcs11_source_updater_instance_init (SeahorsePkcs11SourceUpdater * self) {
+	self->priv = SEAHORSE_PKCS11_SOURCE_UPDATER_GET_PRIVATE (self);
+}
+
+
+static void seahorse_pkcs11_source_updater_dispose (GObject * obj) {
+	SeahorsePkcs11SourceUpdater * self;
+	self = SEAHORSE_PKCS11_SOURCE_UPDATER (obj);
+	(self->priv->_cancellable == NULL ? NULL : (self->priv->_cancellable = (g_object_unref (self->priv->_cancellable), NULL)));
+	(self->_source == NULL ? NULL : (self->_source = (g_object_unref (self->_source), NULL)));
+	(self->_session == NULL ? NULL : (self->_session = (g_object_unref (self->_session), NULL)));
+	(self->priv->_objects == NULL ? NULL : (self->priv->_objects = (_g_list_free_g_object_unref (self->priv->_objects), NULL)));
+	G_OBJECT_CLASS (seahorse_pkcs11_source_updater_parent_class)->dispose (obj);
+}
+
+
+static GType seahorse_pkcs11_source_updater_get_type (void) {
+	static GType seahorse_pkcs11_source_updater_type_id = 0;
+	if (G_UNLIKELY (seahorse_pkcs11_source_updater_type_id == 0)) {
+		static const GTypeInfo g_define_type_info = { sizeof (SeahorsePkcs11SourceUpdaterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) seahorse_pkcs11_source_updater_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SeahorsePkcs11SourceUpdater), 0, (GInstanceInitFunc) seahorse_pkcs11_source_updater_instance_init };
+		seahorse_pkcs11_source_updater_type_id = g_type_register_static (SEAHORSE_TYPE_OPERATION, "SeahorsePkcs11SourceUpdater", &g_define_type_info, G_TYPE_FLAG_ABSTRACT);
+	}
+	return seahorse_pkcs11_source_updater_type_id;
+}
+
+
+static SeahorsePkcs11SourceRefresher* seahorse_pkcs11_source_refresher_new (SeahorsePkcs11Source* source) {
+	GParameter * __params;
+	GParameter * __params_it;
+	SeahorsePkcs11SourceRefresher * self;
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_SOURCE (source), NULL);
+	__params = g_new0 (GParameter, 1);
+	__params_it = __params;
+	__params_it->name = "source";
+	g_value_init (&__params_it->value, SEAHORSE_PKCS11_TYPE_SOURCE);
+	g_value_set_object (&__params_it->value, source);
+	__params_it++;
+	self = g_object_newv (SEAHORSE_PKCS11_SOURCE_TYPE_REFRESHER, __params_it - __params, __params);
+	while (__params_it > __params) {
+		--__params_it;
+		g_value_unset (&__params_it->value);
+	}
+	g_free (__params);
+	return self;
+}
+
+
+static void _seahorse_pkcs11_source_refresher_on_find_objects_gasync_ready_callback (GObject* source_object, GAsyncResult* res, gpointer self) {
+	seahorse_pkcs11_source_refresher_on_find_objects (self, source_object, res);
+}
+
+
+/* Search for all token objects */
+static void seahorse_pkcs11_source_refresher_real_load_objects (SeahorsePkcs11SourceUpdater* base) {
+	SeahorsePkcs11SourceRefresher * self;
+	GP11Attributes* attrs;
+	self = SEAHORSE_PKCS11_SOURCE_REFRESHER (base);
+	attrs = gp11_attributes_new ();
+	gp11_attributes_add_boolean (attrs, CKA_TOKEN, TRUE);
+	gp11_attributes_add_ulong (attrs, CKA_CLASS, CKO_CERTIFICATE);
+	gp11_session_find_objects_async (SEAHORSE_PKCS11_SOURCE_UPDATER (self)->_session, attrs, seahorse_pkcs11_source_updater_get_cancellable (SEAHORSE_PKCS11_SOURCE_UPDATER (self)), _seahorse_pkcs11_source_refresher_on_find_objects_gasync_ready_callback, self);
+	(attrs == NULL ? NULL : (attrs = (gp11_attributes_unref (attrs), NULL)));
+}
+
+
+static void __lambda0 (void* k, void* v, SeahorsePkcs11SourceRefresher* self) {
+	seahorse_context_remove_object (seahorse_context_for_app (), SEAHORSE_OBJECT (v));
+}
+
+
+static void ___lambda0_gh_func (void* key, void* value, gpointer self) {
+	__lambda0 (key, value, self);
+}
+
+
+static void seahorse_pkcs11_source_refresher_on_find_objects (SeahorsePkcs11SourceRefresher* self, GObject* obj, GAsyncResult* result) {
+	GError * inner_error;
+	GP11Session* _tmp0;
+	GP11Session* session;
+	GList* objects;
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_REFRESHER (self));
+	g_return_if_fail (G_IS_OBJECT (obj));
+	g_return_if_fail (G_IS_ASYNC_RESULT (result));
+	inner_error = NULL;
+	_tmp0 = NULL;
+	session = (_tmp0 = GP11_SESSION (obj), (_tmp0 == NULL ? NULL : g_object_ref (_tmp0)));
+	objects = NULL;
+	{
+		GList* _tmp1;
+		_tmp1 = NULL;
+		objects = (_tmp1 = gp11_session_find_objects_finish (session, result, &inner_error), (objects == NULL ? NULL : (objects = (_g_list_free_g_object_unref (objects), NULL))), _tmp1);
+		if (inner_error != NULL) {
+			goto __catch2_g_error;
+		}
+	}
+	goto __finally2;
+	__catch2_g_error:
+	{
+		GError * err;
+		err = inner_error;
+		inner_error = NULL;
+		{
+			seahorse_pkcs11_source_updater_complete (SEAHORSE_PKCS11_SOURCE_UPDATER (self), err);
+			(err == NULL ? NULL : (err = (g_error_free (err), NULL)));
+			(session == NULL ? NULL : (session = (g_object_unref (session), NULL)));
+			(objects == NULL ? NULL : (objects = (_g_list_free_g_object_unref (objects), NULL)));
+			return;
+		}
+	}
+	__finally2:
+	;
+	/* Remove all objects that were found, from the check table */
+	{
+		GList* object_collection;
+		GList* object_it;
+		object_collection = objects;
+		for (object_it = object_collection; object_it != NULL; object_it = object_it->next) {
+			GP11Object* _tmp2;
+			GP11Object* object;
+			_tmp2 = NULL;
+			object = (_tmp2 = ((GP11Object*) (object_it->data)), (_tmp2 == NULL ? NULL : g_object_ref (_tmp2)));
+			{
+				g_hash_table_remove (self->priv->_checks, GUINT_TO_POINTER (gp11_object_get_handle (object)));
+				(object == NULL ? NULL : (object = (g_object_unref (object), NULL)));
+			}
+		}
+	}
+	g_hash_table_foreach (self->priv->_checks, ___lambda0_gh_func, self);
+	seahorse_pkcs11_source_updater_loaded_objects (SEAHORSE_PKCS11_SOURCE_UPDATER (self), objects);
+	(session == NULL ? NULL : (session = (g_object_unref (session), NULL)));
+	(objects == NULL ? NULL : (objects = (_g_list_free_g_object_unref (objects), NULL)));
+}
+
+
+static GObject * seahorse_pkcs11_source_refresher_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
+	GObject * obj;
+	SeahorsePkcs11SourceRefresherClass * klass;
+	GObjectClass * parent_class;
+	SeahorsePkcs11SourceRefresher * self;
+	klass = SEAHORSE_PKCS11_SOURCE_REFRESHER_CLASS (g_type_class_peek (SEAHORSE_PKCS11_SOURCE_TYPE_REFRESHER));
+	parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
+	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
+	self = SEAHORSE_PKCS11_SOURCE_REFRESHER (obj);
+	{
+		GHashTable* _tmp2;
+		/* Load all the current item into the check table */
+		_tmp2 = NULL;
+		self->priv->_checks = (_tmp2 = g_hash_table_new (g_direct_hash, g_direct_equal), (self->priv->_checks == NULL ? NULL : (self->priv->_checks = (g_hash_table_unref (self->priv->_checks), NULL))), _tmp2);
+		{
+			GList* object_collection;
+			GList* object_it;
+			object_collection = seahorse_context_get_objects (seahorse_context_for_app (), SEAHORSE_SOURCE (SEAHORSE_PKCS11_SOURCE_UPDATER (self)->_source));
+			for (object_it = object_collection; object_it != NULL; object_it = object_it->next) {
+				SeahorseObject* object;
+				object = ((SeahorseObject*) (object_it->data));
+				{
+					if (G_TYPE_FROM_INSTANCE (G_OBJECT (object)) == SEAHORSE_PKCS11_TYPE_CERTIFICATE) {
+						SeahorsePkcs11Certificate* _tmp3;
+						SeahorsePkcs11Certificate* certificate;
+						_tmp3 = NULL;
+						certificate = (_tmp3 = SEAHORSE_PKCS11_CERTIFICATE (object), (_tmp3 == NULL ? NULL : g_object_ref (_tmp3)));
+						if (seahorse_pkcs11_certificate_get_pkcs11_object (certificate) != NULL) {
+							SeahorseObject* _tmp4;
+							_tmp4 = NULL;
+							g_hash_table_insert (self->priv->_checks, GUINT_TO_POINTER (gp11_object_get_handle (seahorse_pkcs11_certificate_get_pkcs11_object (certificate))), (_tmp4 = object, (_tmp4 == NULL ? NULL : g_object_ref (_tmp4))));
+						}
+						(certificate == NULL ? NULL : (certificate = (g_object_unref (certificate), NULL)));
+					}
+				}
+			}
+			(object_collection == NULL ? NULL : (object_collection = (g_list_free (object_collection), NULL)));
+		}
+	}
+	return obj;
+}
+
+
+static void seahorse_pkcs11_source_refresher_class_init (SeahorsePkcs11SourceRefresherClass * klass) {
+	seahorse_pkcs11_source_refresher_parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (SeahorsePkcs11SourceRefresherPrivate));
+	G_OBJECT_CLASS (klass)->constructor = seahorse_pkcs11_source_refresher_constructor;
+	G_OBJECT_CLASS (klass)->dispose = seahorse_pkcs11_source_refresher_dispose;
+	SEAHORSE_PKCS11_SOURCE_UPDATER_CLASS (klass)->load_objects = seahorse_pkcs11_source_refresher_real_load_objects;
+}
+
+
+static void seahorse_pkcs11_source_refresher_instance_init (SeahorsePkcs11SourceRefresher * self) {
+	self->priv = SEAHORSE_PKCS11_SOURCE_REFRESHER_GET_PRIVATE (self);
+}
+
+
+static void seahorse_pkcs11_source_refresher_dispose (GObject * obj) {
+	SeahorsePkcs11SourceRefresher * self;
+	self = SEAHORSE_PKCS11_SOURCE_REFRESHER (obj);
+	(self->priv->_checks == NULL ? NULL : (self->priv->_checks = (g_hash_table_unref (self->priv->_checks), NULL)));
+	G_OBJECT_CLASS (seahorse_pkcs11_source_refresher_parent_class)->dispose (obj);
+}
+
+
+static GType seahorse_pkcs11_source_refresher_get_type (void) {
+	static GType seahorse_pkcs11_source_refresher_type_id = 0;
+	if (G_UNLIKELY (seahorse_pkcs11_source_refresher_type_id == 0)) {
+		static const GTypeInfo g_define_type_info = { sizeof (SeahorsePkcs11SourceRefresherClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) seahorse_pkcs11_source_refresher_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SeahorsePkcs11SourceRefresher), 0, (GInstanceInitFunc) seahorse_pkcs11_source_refresher_instance_init };
+		seahorse_pkcs11_source_refresher_type_id = g_type_register_static (SEAHORSE_PKCS11_SOURCE_TYPE_UPDATER, "SeahorsePkcs11SourceRefresher", &g_define_type_info, 0);
+	}
+	return seahorse_pkcs11_source_refresher_type_id;
+}
+
+
+static SeahorsePkcs11SourceLoader* seahorse_pkcs11_source_loader_new (SeahorsePkcs11Source* source, GP11Attributes* unique_attrs) {
+	GParameter * __params;
+	GParameter * __params_it;
+	SeahorsePkcs11SourceLoader * self;
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_SOURCE (source), NULL);
+	g_return_val_if_fail (unique_attrs != NULL, NULL);
+	__params = g_new0 (GParameter, 2);
+	__params_it = __params;
+	__params_it->name = "source";
+	g_value_init (&__params_it->value, SEAHORSE_PKCS11_TYPE_SOURCE);
+	g_value_set_object (&__params_it->value, source);
+	__params_it++;
+	__params_it->name = "unique-attrs";
+	g_value_init (&__params_it->value, GP11_TYPE_ATTRIBUTES);
+	g_value_set_pointer (&__params_it->value, unique_attrs);
+	__params_it++;
+	self = g_object_newv (SEAHORSE_PKCS11_SOURCE_TYPE_LOADER, __params_it - __params, __params);
+	while (__params_it > __params) {
+		--__params_it;
+		g_value_unset (&__params_it->value);
+	}
+	g_free (__params);
+	return self;
+}
+
+
+static void _seahorse_pkcs11_source_loader_on_find_objects_gasync_ready_callback (GObject* source_object, GAsyncResult* res, gpointer self) {
+	seahorse_pkcs11_source_loader_on_find_objects (self, source_object, res);
+}
+
+
+/* Search for the object to load */
+static void seahorse_pkcs11_source_loader_real_load_objects (SeahorsePkcs11SourceUpdater* base) {
+	SeahorsePkcs11SourceLoader * self;
+	self = SEAHORSE_PKCS11_SOURCE_LOADER (base);
+	gp11_session_find_objects_async (SEAHORSE_PKCS11_SOURCE_UPDATER (self)->_session, self->priv->_unique_attrs, seahorse_pkcs11_source_updater_get_cancellable (SEAHORSE_PKCS11_SOURCE_UPDATER (self)), _seahorse_pkcs11_source_loader_on_find_objects_gasync_ready_callback, self);
+}
+
+
+static void seahorse_pkcs11_source_loader_on_find_objects (SeahorsePkcs11SourceLoader* self, GObject* obj, GAsyncResult* result) {
+	GError * inner_error;
+	GP11Session* _tmp0;
+	GP11Session* session;
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_LOADER (self));
+	g_return_if_fail (G_IS_OBJECT (obj));
+	g_return_if_fail (G_IS_ASYNC_RESULT (result));
+	inner_error = NULL;
+	_tmp0 = NULL;
+	session = (_tmp0 = GP11_SESSION (obj), (_tmp0 == NULL ? NULL : g_object_ref (_tmp0)));
+	{
+		GList* objects;
+		objects = gp11_session_find_objects_finish (session, result, &inner_error);
+		if (inner_error != NULL) {
+			goto __catch3_g_error;
+		}
+		seahorse_pkcs11_source_updater_loaded_objects (SEAHORSE_PKCS11_SOURCE_UPDATER (self), objects);
+		(objects == NULL ? NULL : (objects = (_g_list_free_g_object_unref (objects), NULL)));
+	}
+	goto __finally3;
+	__catch3_g_error:
+	{
+		GError * err;
+		err = inner_error;
+		inner_error = NULL;
+		{
+			seahorse_pkcs11_source_updater_complete (SEAHORSE_PKCS11_SOURCE_UPDATER (self), err);
+			(err == NULL ? NULL : (err = (g_error_free (err), NULL)));
+			(session == NULL ? NULL : (session = (g_object_unref (session), NULL)));
+			return;
+		}
+	}
+	__finally3:
+	;
+	(session == NULL ? NULL : (session = (g_object_unref (session), NULL)));
+}
+
+
+static GP11Attributes* seahorse_pkcs11_source_loader_get_unique_attrs (SeahorsePkcs11SourceLoader* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_SOURCE_IS_LOADER (self), NULL);
+	return self->priv->_unique_attrs;
+}
+
+
+static void seahorse_pkcs11_source_loader_set_unique_attrs (SeahorsePkcs11SourceLoader* self, GP11Attributes* value) {
+	GP11Attributes* _tmp2;
+	GP11Attributes* _tmp1;
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_LOADER (self));
+	_tmp2 = NULL;
+	_tmp1 = NULL;
+	self->priv->_unique_attrs = (_tmp2 = (_tmp1 = value, (_tmp1 == NULL ? NULL : gp11_attributes_ref (_tmp1))), (self->priv->_unique_attrs == NULL ? NULL : (self->priv->_unique_attrs = (gp11_attributes_unref (self->priv->_unique_attrs), NULL))), _tmp2);
+	g_object_notify (((GObject *) (self)), "unique-attrs");
+}
+
+
+static void seahorse_pkcs11_source_loader_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
+	SeahorsePkcs11SourceLoader * self;
+	self = SEAHORSE_PKCS11_SOURCE_LOADER (object);
+	switch (property_id) {
+		case SEAHORSE_PKCS11_SOURCE_LOADER_UNIQUE_ATTRS:
+		g_value_set_pointer (value, seahorse_pkcs11_source_loader_get_unique_attrs (self));
+		break;
+		default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+
+static void seahorse_pkcs11_source_loader_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
+	SeahorsePkcs11SourceLoader * self;
+	self = SEAHORSE_PKCS11_SOURCE_LOADER (object);
+	switch (property_id) {
+		case SEAHORSE_PKCS11_SOURCE_LOADER_UNIQUE_ATTRS:
+		seahorse_pkcs11_source_loader_set_unique_attrs (self, g_value_get_pointer (value));
+		break;
+		default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+
+static void seahorse_pkcs11_source_loader_class_init (SeahorsePkcs11SourceLoaderClass * klass) {
+	seahorse_pkcs11_source_loader_parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (SeahorsePkcs11SourceLoaderPrivate));
+	G_OBJECT_CLASS (klass)->get_property = seahorse_pkcs11_source_loader_get_property;
+	G_OBJECT_CLASS (klass)->set_property = seahorse_pkcs11_source_loader_set_property;
+	G_OBJECT_CLASS (klass)->dispose = seahorse_pkcs11_source_loader_dispose;
+	SEAHORSE_PKCS11_SOURCE_UPDATER_CLASS (klass)->load_objects = seahorse_pkcs11_source_loader_real_load_objects;
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_SOURCE_LOADER_UNIQUE_ATTRS, g_param_spec_pointer ("unique-attrs", "unique-attrs", "unique-attrs", G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+
+static void seahorse_pkcs11_source_loader_instance_init (SeahorsePkcs11SourceLoader * self) {
+	self->priv = SEAHORSE_PKCS11_SOURCE_LOADER_GET_PRIVATE (self);
+}
+
+
+static void seahorse_pkcs11_source_loader_dispose (GObject * obj) {
+	SeahorsePkcs11SourceLoader * self;
+	self = SEAHORSE_PKCS11_SOURCE_LOADER (obj);
+	(self->priv->_unique_attrs == NULL ? NULL : (self->priv->_unique_attrs = (gp11_attributes_unref (self->priv->_unique_attrs), NULL)));
+	G_OBJECT_CLASS (seahorse_pkcs11_source_loader_parent_class)->dispose (obj);
+}
+
+
+static GType seahorse_pkcs11_source_loader_get_type (void) {
+	static GType seahorse_pkcs11_source_loader_type_id = 0;
+	if (G_UNLIKELY (seahorse_pkcs11_source_loader_type_id == 0)) {
+		static const GTypeInfo g_define_type_info = { sizeof (SeahorsePkcs11SourceLoaderClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) seahorse_pkcs11_source_loader_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SeahorsePkcs11SourceLoader), 0, (GInstanceInitFunc) seahorse_pkcs11_source_loader_instance_init };
+		seahorse_pkcs11_source_loader_type_id = g_type_register_static (SEAHORSE_PKCS11_SOURCE_TYPE_UPDATER, "SeahorsePkcs11SourceLoader", &g_define_type_info, 0);
+	}
+	return seahorse_pkcs11_source_loader_type_id;
+}
+
+
+static SeahorsePkcs11SourceImporter* seahorse_pkcs11_source_importer_new (SeahorsePkcs11Source* source, GP11Attributes* import) {
+	GParameter * __params;
+	GParameter * __params_it;
+	SeahorsePkcs11SourceImporter * self;
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_SOURCE (source), NULL);
+	g_return_val_if_fail (import != NULL, NULL);
+	__params = g_new0 (GParameter, 1);
+	__params_it = __params;
+	__params_it->name = "source";
+	g_value_init (&__params_it->value, SEAHORSE_PKCS11_TYPE_SOURCE);
+	g_value_set_object (&__params_it->value, source);
+	__params_it++;
+	self = g_object_newv (SEAHORSE_PKCS11_SOURCE_TYPE_IMPORTER, __params_it - __params, __params);
+	while (__params_it > __params) {
+		--__params_it;
+		g_value_unset (&__params_it->value);
+	}
+	g_free (__params);
+	return self;
+}
+
+
+static void _seahorse_pkcs11_source_importer_on_create_object_gasync_ready_callback (GObject* source_object, GAsyncResult* res, gpointer self) {
+	seahorse_pkcs11_source_importer_on_create_object (self, source_object, res);
+}
+
+
+/* Search for the object to load */
+static void seahorse_pkcs11_source_importer_real_load_objects (SeahorsePkcs11SourceUpdater* base) {
+	SeahorsePkcs11SourceImporter * self;
+	self = SEAHORSE_PKCS11_SOURCE_IMPORTER (base);
+	gp11_session_create_object_async (SEAHORSE_PKCS11_SOURCE_UPDATER (self)->_session, self->priv->_import_data, seahorse_pkcs11_source_updater_get_cancellable (SEAHORSE_PKCS11_SOURCE_UPDATER (self)), _seahorse_pkcs11_source_importer_on_create_object_gasync_ready_callback, self);
+}
+
+
+static void _seahorse_pkcs11_source_importer_on_get_attribute_gasync_ready_callback (GObject* source_object, GAsyncResult* res, gpointer self) {
+	seahorse_pkcs11_source_importer_on_get_attribute (self, source_object, res);
+}
+
+
+static void seahorse_pkcs11_source_importer_on_create_object (SeahorsePkcs11SourceImporter* self, GObject* obj, GAsyncResult* result) {
+	GError * inner_error;
+	GP11Session* _tmp0;
+	GP11Session* session;
+	GP11Object* import;
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_IMPORTER (self));
+	g_return_if_fail (G_IS_OBJECT (obj));
+	g_return_if_fail (G_IS_ASYNC_RESULT (result));
+	inner_error = NULL;
+	_tmp0 = NULL;
+	session = (_tmp0 = GP11_SESSION (obj), (_tmp0 == NULL ? NULL : g_object_ref (_tmp0)));
+	import = NULL;
+	{
+		GP11Object* _tmp1;
+		_tmp1 = NULL;
+		import = (_tmp1 = gp11_session_create_object_finish (session, result, &inner_error), (import == NULL ? NULL : (import = (g_object_unref (import), NULL))), _tmp1);
+		if (inner_error != NULL) {
+			goto __catch4_g_error;
+		}
+	}
+	goto __finally4;
+	__catch4_g_error:
+	{
+		GError * err;
+		err = inner_error;
+		inner_error = NULL;
+		{
+			seahorse_pkcs11_source_updater_complete (SEAHORSE_PKCS11_SOURCE_UPDATER (self), err);
+			(err == NULL ? NULL : (err = (g_error_free (err), NULL)));
+			(session == NULL ? NULL : (session = (g_object_unref (session), NULL)));
+			(import == NULL ? NULL : (import = (g_object_unref (import), NULL)));
+			return;
+		}
+	}
+	__finally4:
+	;
+	/* Get the list of objects imported */
+	gp11_object_get_one_async (import, CKA_GNOME_IMPORT_OBJECTS, seahorse_pkcs11_source_updater_get_cancellable (SEAHORSE_PKCS11_SOURCE_UPDATER (self)), _seahorse_pkcs11_source_importer_on_get_attribute_gasync_ready_callback, self);
+	(session == NULL ? NULL : (session = (g_object_unref (session), NULL)));
+	(import == NULL ? NULL : (import = (g_object_unref (import), NULL)));
+}
+
+
+static void seahorse_pkcs11_source_importer_on_get_attribute (SeahorsePkcs11SourceImporter* self, GObject* obj, GAsyncResult* result) {
+	GError * inner_error;
+	GP11Object* _tmp0;
+	GP11Object* import;
+	GP11Attribute* imported_handles;
+	GList* _tmp2;
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_IMPORTER (self));
+	g_return_if_fail (G_IS_OBJECT (obj));
+	g_return_if_fail (G_IS_ASYNC_RESULT (result));
+	inner_error = NULL;
+	_tmp0 = NULL;
+	import = (_tmp0 = GP11_OBJECT (obj), (_tmp0 == NULL ? NULL : g_object_ref (_tmp0)));
+	imported_handles = NULL;
+	{
+		GP11Attribute* _tmp1;
+		_tmp1 = NULL;
+		imported_handles = (_tmp1 = gp11_object_get_one_finish (import, result, &inner_error), (imported_handles == NULL ? NULL : (imported_handles = (gp11_attribute_free (imported_handles), NULL))), _tmp1);
+		if (inner_error != NULL) {
+			goto __catch5_g_error;
+		}
+	}
+	goto __finally5;
+	__catch5_g_error:
+	{
+		GError * err;
+		err = inner_error;
+		inner_error = NULL;
+		{
+			seahorse_pkcs11_source_updater_complete (SEAHORSE_PKCS11_SOURCE_UPDATER (self), err);
+			(err == NULL ? NULL : (err = (g_error_free (err), NULL)));
+			(import == NULL ? NULL : (import = (g_object_unref (import), NULL)));
+			(imported_handles == NULL ? NULL : (imported_handles = (gp11_attribute_free (imported_handles), NULL)));
+			return;
+		}
+	}
+	__finally5:
+	;
+	_tmp2 = NULL;
+	seahorse_pkcs11_source_updater_loaded_objects (SEAHORSE_PKCS11_SOURCE_UPDATER (self), (_tmp2 = gp11_objects_from_handle_array (SEAHORSE_PKCS11_SOURCE_UPDATER (self)->_session, imported_handles)));
+	(_tmp2 == NULL ? NULL : (_tmp2 = (_g_list_free_g_object_unref (_tmp2), NULL)));
+	(import == NULL ? NULL : (import = (g_object_unref (import), NULL)));
+	(imported_handles == NULL ? NULL : (imported_handles = (gp11_attribute_free (imported_handles), NULL)));
+}
+
+
+static GP11Attributes* seahorse_pkcs11_source_importer_get_import_data (SeahorsePkcs11SourceImporter* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_SOURCE_IS_IMPORTER (self), NULL);
+	return self->priv->_import_data;
+}
+
+
+static void seahorse_pkcs11_source_importer_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
+	SeahorsePkcs11SourceImporter * self;
+	self = SEAHORSE_PKCS11_SOURCE_IMPORTER (object);
+	switch (property_id) {
+		case SEAHORSE_PKCS11_SOURCE_IMPORTER_IMPORT_DATA:
+		g_value_set_pointer (value, seahorse_pkcs11_source_importer_get_import_data (self));
+		break;
+		default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+
+static void seahorse_pkcs11_source_importer_class_init (SeahorsePkcs11SourceImporterClass * klass) {
+	seahorse_pkcs11_source_importer_parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (SeahorsePkcs11SourceImporterPrivate));
+	G_OBJECT_CLASS (klass)->get_property = seahorse_pkcs11_source_importer_get_property;
+	G_OBJECT_CLASS (klass)->dispose = seahorse_pkcs11_source_importer_dispose;
+	SEAHORSE_PKCS11_SOURCE_UPDATER_CLASS (klass)->load_objects = seahorse_pkcs11_source_importer_real_load_objects;
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_SOURCE_IMPORTER_IMPORT_DATA, g_param_spec_pointer ("import-data", "import-data", "import-data", G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+}
+
+
+static void seahorse_pkcs11_source_importer_instance_init (SeahorsePkcs11SourceImporter * self) {
+	self->priv = SEAHORSE_PKCS11_SOURCE_IMPORTER_GET_PRIVATE (self);
+}
+
+
+static void seahorse_pkcs11_source_importer_dispose (GObject * obj) {
+	SeahorsePkcs11SourceImporter * self;
+	self = SEAHORSE_PKCS11_SOURCE_IMPORTER (obj);
+	(self->priv->_import_data == NULL ? NULL : (self->priv->_import_data = (gp11_attributes_unref (self->priv->_import_data), NULL)));
+	G_OBJECT_CLASS (seahorse_pkcs11_source_importer_parent_class)->dispose (obj);
+}
+
+
+static GType seahorse_pkcs11_source_importer_get_type (void) {
+	static GType seahorse_pkcs11_source_importer_type_id = 0;
+	if (G_UNLIKELY (seahorse_pkcs11_source_importer_type_id == 0)) {
+		static const GTypeInfo g_define_type_info = { sizeof (SeahorsePkcs11SourceImporterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) seahorse_pkcs11_source_importer_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SeahorsePkcs11SourceImporter), 0, (GInstanceInitFunc) seahorse_pkcs11_source_importer_instance_init };
+		seahorse_pkcs11_source_importer_type_id = g_type_register_static (SEAHORSE_PKCS11_SOURCE_TYPE_UPDATER, "SeahorsePkcs11SourceImporter", &g_define_type_info, 0);
+	}
+	return seahorse_pkcs11_source_importer_type_id;
+}
+
+
+static SeahorsePkcs11SourceRemover* seahorse_pkcs11_source_remover_new (SeahorsePkcs11Certificate* certificate) {
+	GParameter * __params;
+	GParameter * __params_it;
+	SeahorsePkcs11SourceRemover * self;
+	g_return_val_if_fail (SEAHORSE_PKCS11_IS_CERTIFICATE (certificate), NULL);
+	__params = g_new0 (GParameter, 1);
+	__params_it = __params;
+	__params_it->name = "certificate";
+	g_value_init (&__params_it->value, SEAHORSE_PKCS11_TYPE_CERTIFICATE);
+	g_value_set_object (&__params_it->value, certificate);
+	__params_it++;
+	self = g_object_newv (SEAHORSE_PKCS11_SOURCE_TYPE_REMOVER, __params_it - __params, __params);
+	while (__params_it > __params) {
+		--__params_it;
+		g_value_unset (&__params_it->value);
+	}
+	g_free (__params);
+	return self;
+}
+
+
+static void seahorse_pkcs11_source_remover_on_destroy_object (SeahorsePkcs11SourceRemover* self, GObject* obj, GAsyncResult* result) {
+	GError * inner_error;
+	GP11Object* _tmp0;
+	GP11Object* object;
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_REMOVER (self));
+	g_return_if_fail (G_IS_OBJECT (obj));
+	g_return_if_fail (G_IS_ASYNC_RESULT (result));
+	inner_error = NULL;
+	_tmp0 = NULL;
+	object = (_tmp0 = GP11_OBJECT (obj), (_tmp0 == NULL ? NULL : g_object_ref (_tmp0)));
+	{
+		gp11_object_destroy_finish (object, result, &inner_error);
+		if (inner_error != NULL) {
+			goto __catch6_g_error;
+		}
+	}
+	goto __finally6;
+	__catch6_g_error:
+	{
+		GError * err;
+		err = inner_error;
+		inner_error = NULL;
+		{
+			if (err->code == CKR_FUNCTION_CANCELED) {
+				seahorse_operation_mark_done (SEAHORSE_OPERATION (self), TRUE, NULL);
+			} else {
+				GError* _tmp1;
+				_tmp1 = NULL;
+				seahorse_operation_mark_done (SEAHORSE_OPERATION (self), FALSE, (_tmp1 = err, (_tmp1 == NULL || g_error_copy == NULL ? ((gpointer) (_tmp1)) : g_error_copy (((gpointer) (_tmp1))))));
+			}
+			(err == NULL ? NULL : (err = (g_error_free (err), NULL)));
+			(object == NULL ? NULL : (object = (g_object_unref (object), NULL)));
+			return;
+		}
+	}
+	__finally6:
+	;
+	seahorse_context_remove_object (seahorse_context_for_app (), SEAHORSE_OBJECT (seahorse_pkcs11_source_remover_get_certificate (self)));
+	seahorse_operation_mark_done (SEAHORSE_OPERATION (self), FALSE, NULL);
+	(object == NULL ? NULL : (object = (g_object_unref (object), NULL)));
+}
+
+
+/* Cancel the operation */
+static void seahorse_pkcs11_source_remover_real_cancel (SeahorseOperation* base) {
+	SeahorsePkcs11SourceRemover * self;
+	self = SEAHORSE_PKCS11_SOURCE_REMOVER (base);
+	g_cancellable_cancel (self->priv->_cancellable);
+}
+
+
+static GCancellable* seahorse_pkcs11_source_remover_get_cancellable (SeahorsePkcs11SourceRemover* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_SOURCE_IS_REMOVER (self), NULL);
+	return self->priv->_cancellable;
+}
+
+
+static SeahorsePkcs11Source* seahorse_pkcs11_source_remover_get_source (SeahorsePkcs11SourceRemover* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_SOURCE_IS_REMOVER (self), NULL);
+	return self->priv->_source;
+}
+
+
+static void seahorse_pkcs11_source_remover_set_source (SeahorsePkcs11SourceRemover* self, SeahorsePkcs11Source* value) {
+	SeahorsePkcs11Source* _tmp2;
+	SeahorsePkcs11Source* _tmp1;
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_REMOVER (self));
+	_tmp2 = NULL;
+	_tmp1 = NULL;
+	self->priv->_source = (_tmp2 = (_tmp1 = value, (_tmp1 == NULL ? NULL : g_object_ref (_tmp1))), (self->priv->_source == NULL ? NULL : (self->priv->_source = (g_object_unref (self->priv->_source), NULL))), _tmp2);
+	g_object_notify (((GObject *) (self)), "source");
+}
+
+
+static SeahorsePkcs11Certificate* seahorse_pkcs11_source_remover_get_certificate (SeahorsePkcs11SourceRemover* self) {
+	g_return_val_if_fail (SEAHORSE_PKCS11_SOURCE_IS_REMOVER (self), NULL);
+	return self->priv->_certificate;
+}
+
+
+static void seahorse_pkcs11_source_remover_set_certificate (SeahorsePkcs11SourceRemover* self, SeahorsePkcs11Certificate* value) {
+	SeahorsePkcs11Certificate* _tmp2;
+	SeahorsePkcs11Certificate* _tmp1;
+	g_return_if_fail (SEAHORSE_PKCS11_SOURCE_IS_REMOVER (self));
+	_tmp2 = NULL;
+	_tmp1 = NULL;
+	self->priv->_certificate = (_tmp2 = (_tmp1 = value, (_tmp1 == NULL ? NULL : g_object_ref (_tmp1))), (self->priv->_certificate == NULL ? NULL : (self->priv->_certificate = (g_object_unref (self->priv->_certificate), NULL))), _tmp2);
+	g_object_notify (((GObject *) (self)), "certificate");
+}
+
+
+static void _seahorse_pkcs11_source_remover_on_destroy_object_gasync_ready_callback (GObject* source_object, GAsyncResult* res, gpointer self) {
+	seahorse_pkcs11_source_remover_on_destroy_object (self, source_object, res);
+}
+
+
+static GObject * seahorse_pkcs11_source_remover_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties) {
+	GObject * obj;
+	SeahorsePkcs11SourceRemoverClass * klass;
+	GObjectClass * parent_class;
+	SeahorsePkcs11SourceRemover * self;
+	klass = SEAHORSE_PKCS11_SOURCE_REMOVER_CLASS (g_type_class_peek (SEAHORSE_PKCS11_SOURCE_TYPE_REMOVER));
+	parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (klass));
+	obj = parent_class->constructor (type, n_construct_properties, construct_properties);
+	self = SEAHORSE_PKCS11_SOURCE_REMOVER (obj);
+	{
+		GCancellable* _tmp5;
+		_tmp5 = NULL;
+		self->priv->_cancellable = (_tmp5 = g_cancellable_new (), (self->priv->_cancellable == NULL ? NULL : (self->priv->_cancellable = (g_object_unref (self->priv->_cancellable), NULL))), _tmp5);
+		gp11_object_destroy_async (seahorse_pkcs11_certificate_get_pkcs11_object (self->priv->_certificate), self->priv->_cancellable, _seahorse_pkcs11_source_remover_on_destroy_object_gasync_ready_callback, self);
+		seahorse_operation_mark_start (SEAHORSE_OPERATION (self));
+	}
+	return obj;
+}
+
+
+static void seahorse_pkcs11_source_remover_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
+	SeahorsePkcs11SourceRemover * self;
+	self = SEAHORSE_PKCS11_SOURCE_REMOVER (object);
+	switch (property_id) {
+		case SEAHORSE_PKCS11_SOURCE_REMOVER_CANCELLABLE:
+		g_value_set_object (value, seahorse_pkcs11_source_remover_get_cancellable (self));
+		break;
+		case SEAHORSE_PKCS11_SOURCE_REMOVER_SOURCE:
+		g_value_set_object (value, seahorse_pkcs11_source_remover_get_source (self));
+		break;
+		case SEAHORSE_PKCS11_SOURCE_REMOVER_CERTIFICATE:
+		g_value_set_object (value, seahorse_pkcs11_source_remover_get_certificate (self));
+		break;
+		default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+
+static void seahorse_pkcs11_source_remover_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
+	SeahorsePkcs11SourceRemover * self;
+	self = SEAHORSE_PKCS11_SOURCE_REMOVER (object);
+	switch (property_id) {
+		case SEAHORSE_PKCS11_SOURCE_REMOVER_SOURCE:
+		seahorse_pkcs11_source_remover_set_source (self, g_value_get_object (value));
+		break;
+		case SEAHORSE_PKCS11_SOURCE_REMOVER_CERTIFICATE:
+		seahorse_pkcs11_source_remover_set_certificate (self, g_value_get_object (value));
+		break;
+		default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+
+static void seahorse_pkcs11_source_remover_class_init (SeahorsePkcs11SourceRemoverClass * klass) {
+	seahorse_pkcs11_source_remover_parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (SeahorsePkcs11SourceRemoverPrivate));
+	G_OBJECT_CLASS (klass)->get_property = seahorse_pkcs11_source_remover_get_property;
+	G_OBJECT_CLASS (klass)->set_property = seahorse_pkcs11_source_remover_set_property;
+	G_OBJECT_CLASS (klass)->constructor = seahorse_pkcs11_source_remover_constructor;
+	G_OBJECT_CLASS (klass)->dispose = seahorse_pkcs11_source_remover_dispose;
+	SEAHORSE_OPERATION_CLASS (klass)->cancel = seahorse_pkcs11_source_remover_real_cancel;
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_SOURCE_REMOVER_CANCELLABLE, g_param_spec_object ("cancellable", "cancellable", "cancellable", G_TYPE_CANCELLABLE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_SOURCE_REMOVER_SOURCE, g_param_spec_object ("source", "source", "source", SEAHORSE_PKCS11_TYPE_SOURCE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_SOURCE_REMOVER_CERTIFICATE, g_param_spec_object ("certificate", "certificate", "certificate", SEAHORSE_PKCS11_TYPE_CERTIFICATE, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+
+static void seahorse_pkcs11_source_remover_instance_init (SeahorsePkcs11SourceRemover * self) {
+	self->priv = SEAHORSE_PKCS11_SOURCE_REMOVER_GET_PRIVATE (self);
+}
+
+
+static void seahorse_pkcs11_source_remover_dispose (GObject * obj) {
+	SeahorsePkcs11SourceRemover * self;
+	self = SEAHORSE_PKCS11_SOURCE_REMOVER (obj);
+	(self->priv->_cancellable == NULL ? NULL : (self->priv->_cancellable = (g_object_unref (self->priv->_cancellable), NULL)));
+	(self->priv->_source == NULL ? NULL : (self->priv->_source = (g_object_unref (self->priv->_source), NULL)));
+	(self->priv->_certificate == NULL ? NULL : (self->priv->_certificate = (g_object_unref (self->priv->_certificate), NULL)));
+	G_OBJECT_CLASS (seahorse_pkcs11_source_remover_parent_class)->dispose (obj);
+}
+
+
+static GType seahorse_pkcs11_source_remover_get_type (void) {
+	static GType seahorse_pkcs11_source_remover_type_id = 0;
+	if (G_UNLIKELY (seahorse_pkcs11_source_remover_type_id == 0)) {
+		static const GTypeInfo g_define_type_info = { sizeof (SeahorsePkcs11SourceRemoverClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) seahorse_pkcs11_source_remover_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SeahorsePkcs11SourceRemover), 0, (GInstanceInitFunc) seahorse_pkcs11_source_remover_instance_init };
+		seahorse_pkcs11_source_remover_type_id = g_type_register_static (SEAHORSE_TYPE_OPERATION, "SeahorsePkcs11SourceRemover", &g_define_type_info, 0);
+	}
+	return seahorse_pkcs11_source_remover_type_id;
+}
+
+
+static void seahorse_pkcs11_source_get_property (GObject * object, guint property_id, GValue * value, GParamSpec * pspec) {
+	SeahorsePkcs11Source * self;
+	self = SEAHORSE_PKCS11_SOURCE (object);
+	switch (property_id) {
+		case SEAHORSE_PKCS11_SOURCE_SLOT:
+		g_value_set_object (value, seahorse_pkcs11_source_get_slot (self));
+		break;
+		case SEAHORSE_PKCS11_SOURCE_LOCATION:
+		g_value_set_enum (value, seahorse_pkcs11_source_get_location (self));
+		break;
+		case SEAHORSE_PKCS11_SOURCE_KEY_TYPE:
+		g_value_set_uint (value, seahorse_pkcs11_source_get_key_type (self));
+		break;
+		case SEAHORSE_PKCS11_SOURCE_KEY_DESC:
+		g_value_set_string (value, seahorse_pkcs11_source_get_key_desc (self));
+		break;
+		default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+
+static void seahorse_pkcs11_source_set_property (GObject * object, guint property_id, const GValue * value, GParamSpec * pspec) {
+	SeahorsePkcs11Source * self;
+	self = SEAHORSE_PKCS11_SOURCE (object);
+	switch (property_id) {
+		case SEAHORSE_PKCS11_SOURCE_SLOT:
+		seahorse_pkcs11_source_set_slot (self, g_value_get_object (value));
+		break;
+		default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+
+static void seahorse_pkcs11_source_class_init (SeahorsePkcs11SourceClass * klass) {
+	seahorse_pkcs11_source_parent_class = g_type_class_peek_parent (klass);
+	g_type_class_add_private (klass, sizeof (SeahorsePkcs11SourcePrivate));
+	G_OBJECT_CLASS (klass)->get_property = seahorse_pkcs11_source_get_property;
+	G_OBJECT_CLASS (klass)->set_property = seahorse_pkcs11_source_set_property;
+	G_OBJECT_CLASS (klass)->dispose = seahorse_pkcs11_source_dispose;
+	SEAHORSE_SOURCE_CLASS (klass)->load = seahorse_pkcs11_source_real_load;
+	SEAHORSE_PKCS11_SOURCE_CLASS (klass)->import = seahorse_pkcs11_source_real_import;
+	SEAHORSE_PKCS11_SOURCE_CLASS (klass)->export = seahorse_pkcs11_source_real_export;
+	SEAHORSE_PKCS11_SOURCE_CLASS (klass)->remove = seahorse_pkcs11_source_real_remove;
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_SOURCE_SLOT, g_param_spec_object ("slot", "slot", "slot", GP11_TYPE_SLOT, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_SOURCE_LOCATION, g_param_spec_enum ("location", "location", "location", SEAHORSE_TYPE_LOCATION, 0, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_SOURCE_KEY_TYPE, g_param_spec_uint ("key-type", "key-type", "key-type", 0, G_MAXUINT, 0U, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+	g_object_class_install_property (G_OBJECT_CLASS (klass), SEAHORSE_PKCS11_SOURCE_KEY_DESC, g_param_spec_string ("key-desc", "key-desc", "key-desc", NULL, G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB | G_PARAM_READABLE));
+}
+
+
+static void seahorse_pkcs11_source_instance_init (SeahorsePkcs11Source * self) {
+	self->priv = SEAHORSE_PKCS11_SOURCE_GET_PRIVATE (self);
+}
+
+
+static void seahorse_pkcs11_source_dispose (GObject * obj) {
+	SeahorsePkcs11Source * self;
+	self = SEAHORSE_PKCS11_SOURCE (obj);
+	(self->priv->_slot == NULL ? NULL : (self->priv->_slot = (g_object_unref (self->priv->_slot), NULL)));
+	G_OBJECT_CLASS (seahorse_pkcs11_source_parent_class)->dispose (obj);
+}
+
+
+GType seahorse_pkcs11_source_get_type (void) {
+	static GType seahorse_pkcs11_source_type_id = 0;
+	if (G_UNLIKELY (seahorse_pkcs11_source_type_id == 0)) {
+		static const GTypeInfo g_define_type_info = { sizeof (SeahorsePkcs11SourceClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) seahorse_pkcs11_source_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (SeahorsePkcs11Source), 0, (GInstanceInitFunc) seahorse_pkcs11_source_instance_init };
+		seahorse_pkcs11_source_type_id = g_type_register_static (SEAHORSE_TYPE_SOURCE, "SeahorsePkcs11Source", &g_define_type_info, 0);
+	}
+	return seahorse_pkcs11_source_type_id;
+}
+
+
+
+

Added: trunk/pkcs11/seahorse-pkcs11-source.h
==============================================================================
--- (empty file)
+++ trunk/pkcs11/seahorse-pkcs11-source.h	Sun Aug  3 20:48:08 2008
@@ -0,0 +1,56 @@
+
+#ifndef __SEAHORSE_PKCS11_SOURCE_H__
+#define __SEAHORSE_PKCS11_SOURCE_H__
+
+#include <glib.h>
+#include <glib-object.h>
+#include <seahorse-source.h>
+#include <gp11.h>
+#include <seahorse-operation.h>
+#include <gio/gio.h>
+#include <seahorse-object.h>
+#include <seahorse-types.h>
+#include <stdlib.h>
+#include <string.h>
+
+G_BEGIN_DECLS
+
+
+#define SEAHORSE_PKCS11_TYPE_SOURCE (seahorse_pkcs11_source_get_type ())
+#define SEAHORSE_PKCS11_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_PKCS11_TYPE_SOURCE, SeahorsePkcs11Source))
+#define SEAHORSE_PKCS11_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_PKCS11_TYPE_SOURCE, SeahorsePkcs11SourceClass))
+#define SEAHORSE_PKCS11_IS_SOURCE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_PKCS11_TYPE_SOURCE))
+#define SEAHORSE_PKCS11_IS_SOURCE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_PKCS11_TYPE_SOURCE))
+#define SEAHORSE_PKCS11_SOURCE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_PKCS11_TYPE_SOURCE, SeahorsePkcs11SourceClass))
+
+typedef struct _SeahorsePkcs11Source SeahorsePkcs11Source;
+typedef struct _SeahorsePkcs11SourceClass SeahorsePkcs11SourceClass;
+typedef struct _SeahorsePkcs11SourcePrivate SeahorsePkcs11SourcePrivate;
+
+struct _SeahorsePkcs11Source {
+	SeahorseSource parent_instance;
+	SeahorsePkcs11SourcePrivate * priv;
+};
+
+struct _SeahorsePkcs11SourceClass {
+	SeahorseSourceClass parent_class;
+	SeahorseOperation* (*import) (SeahorsePkcs11Source* self, GInputStream* input);
+	SeahorseOperation* (*export) (SeahorsePkcs11Source* self, GList* objects, GOutputStream* output);
+	SeahorseOperation* (*remove) (SeahorsePkcs11Source* self, SeahorseObject* object);
+};
+
+
+SeahorsePkcs11Source* seahorse_pkcs11_source_new (GP11Slot* slot);
+SeahorseOperation* seahorse_pkcs11_source_import (SeahorsePkcs11Source* self, GInputStream* input);
+SeahorseOperation* seahorse_pkcs11_source_export (SeahorsePkcs11Source* self, GList* objects, GOutputStream* output);
+SeahorseOperation* seahorse_pkcs11_source_remove (SeahorsePkcs11Source* self, SeahorseObject* object);
+GP11Slot* seahorse_pkcs11_source_get_slot (SeahorsePkcs11Source* self);
+SeahorseLocation seahorse_pkcs11_source_get_location (SeahorsePkcs11Source* self);
+GQuark seahorse_pkcs11_source_get_key_type (SeahorsePkcs11Source* self);
+const char* seahorse_pkcs11_source_get_key_desc (SeahorsePkcs11Source* self);
+GType seahorse_pkcs11_source_get_type (void);
+
+
+G_END_DECLS
+
+#endif

Added: trunk/pkcs11/seahorse-pkcs11-source.vala
==============================================================================
--- (empty file)
+++ trunk/pkcs11/seahorse-pkcs11-source.vala	Sun Aug  3 20:48:08 2008
@@ -0,0 +1,432 @@
+
+/* TODO: Load objects other than certificates. */
+
+namespace Seahorse.Pkcs11 {
+	
+	static const uint[] ATTRIBUTE_TYPES = {
+		P11.CKA_LABEL,
+		P11.CKA_ID,
+		P11.CKA_CLASS,
+		P11.CKA_TOKEN,
+		P11.CKA_GNOME_USER_TRUST,
+		P11.CKA_START_DATE,
+		P11.CKA_END_DATE
+	};
+	
+	public class Source : Seahorse.Source {
+		
+		private GP11.Slot _slot;
+		public GP11.Slot slot {
+			get { return _slot; }
+			construct { _slot = value; }
+		}
+		
+		public Location location {
+			get { return Location.LOCAL; } 
+		}
+		
+		public GLib.Quark key_type {
+			get { return Pkcs11.TYPE; }
+		}
+		
+		public string key_desc {
+			get { return _("X509 Certificate"); }
+		}
+		
+		/* ------------------------------------------------------------------------------
+		 * Base class for several operations that all load objects (refresh, load, import)
+		 */ 
+		
+		private abstract class Updater : Operation {
+
+			/* For cancelling the GP11 operations */
+			private GLib.Cancellable _cancellable;
+			public GLib.Cancellable cancellable { 
+				get { return _cancellable; }
+			}
+
+			/* The source we're updating into */
+			protected Source _source;
+			public Source source {
+				get { return _source; }
+				construct { _source = value; }
+			}
+			
+			/* The PKCS#11 session to load from */
+			protected GP11.Session _session;            
+
+			/* The list of objects that we found, need to load attrs for */
+			private GLib.List<GP11.Object> _objects;  
+			
+			/* Total number of objects that loading/loaded loaded */
+			private int _total;
+
+			construct {
+				_cancellable = new Cancellable();
+				_session = null;
+				
+				/* Step 1. Load the session */
+				_source.slot.open_session_async(P11.CKF_RW_SESSION, _cancellable, on_open_session);
+				mark_start ();
+			}
+			
+			protected void complete(GLib.Error? err = null) {
+				if (err == null) {
+					mark_done(false, null);
+				} else {
+					if (err.code == P11.CKR_FUNCTION_CANCELED)
+						mark_done(true, null);
+					else
+						mark_done(false, err);
+				} 
+			}
+			
+			private void on_open_session(GLib.Object obj, GLib.AsyncResult result) {
+				GP11.Slot slot = (GP11.Slot)obj;
+				
+				/* Check for errors */
+				try {
+					_session = slot.open_session_finish(result);
+				} catch (GLib.Error err) {
+					complete(err);
+					return;
+				}
+
+				/* Step 2. Load all the objects that we want */
+				load_objects();
+			}
+			
+			protected abstract void load_objects();
+			
+			protected void loaded_objects(GLib.List<GP11.Object> objects) {
+				
+				_objects = new GLib.List<GP11.Object>();
+				foreach(var object in objects)
+					_objects.append(object);
+				_total = (int)_objects.length();
+
+				/* Step 3. Load information for each object */
+				do_get_attributes();
+			}
+			
+			private void do_get_attributes() {
+				
+				/* No more objects to load? */
+				if (_objects.length() == 0) {
+					complete();
+					
+				/* Load the next object */ 
+				} else {
+					mark_progress(_("Loading..."), (int)_objects.length() - _total, _total);
+		
+					var object = _objects.data;
+					_objects.remove(object);
+					object.get_attributes_async(ATTRIBUTE_TYPES, _cancellable, on_get_attributes);
+				}
+			}
+			
+			private void on_get_attributes(GLib.Object obj, GLib.AsyncResult result) {
+				GP11.Object object = (GP11.Object)obj;
+				GP11.Attributes attrs;
+				
+				/* Get the results */
+				try {
+					attrs = object.get_attributes_finish(result);
+				} catch (GLib.Error err) {
+					/* Ignore objects that have gone away */
+					if (err.code != P11.CKR_OBJECT_HANDLE_INVALID) {
+						complete(err);
+						return;
+					}
+				}
+				
+				/* Process this object */
+				_source.receive_object(object, attrs);
+				
+				/* Do the next object */
+				do_get_attributes();
+			}
+			
+			/* Cancel the operation */
+			public override void cancel() {
+				_cancellable.cancel();
+			}
+		}
+		
+		/* ------------------------------------------------------------------------------- 
+		 * REFRESH OPREATION
+		 */
+		
+		private class Refresher : Updater {
+			
+			/* Checks so we can determine those that are missing */
+			private GLib.HashTable<uint, Seahorse.Object> _checks;
+			
+			public Refresher(Source source) {
+				this.source = source;
+			}
+
+			construct {
+
+				/* Load all the current item into the check table */
+				_checks = new GLib.HashTable<uint, Seahorse.Object>(GLib.direct_hash, GLib.direct_equal);
+				foreach(var object in Context.for_app().get_objects(_source)) {
+					if (object.get_type() == typeof(Pkcs11.Certificate)) {
+						Certificate certificate = (Pkcs11.Certificate)object;
+						if (certificate.pkcs11_object != null)
+							_checks.insert(certificate.pkcs11_object.handle, object);
+					}
+				}
+			}
+			
+			/* Search for all token objects */
+			protected override void load_objects() {
+				var attrs = new GP11.Attributes();
+				attrs.add_boolean(P11.CKA_TOKEN, true);
+				attrs.add_ulong(P11.CKA_CLASS, P11.CKO_CERTIFICATE);
+				_session.find_objects_async(attrs, cancellable, on_find_objects);
+			}
+			
+			private void on_find_objects(GLib.Object obj, GLib.AsyncResult result) {
+				GP11.Session session = (GP11.Session)obj;
+				GLib.List<GP11.Object> objects;
+				
+				/* Get the results */
+				try {
+					objects = session.find_objects_finish(result);
+				} catch (GLib.Error err) {
+					complete(err);
+					return;
+				}
+
+				/* Remove all objects that were found, from the check table */
+				foreach (var object in objects)
+					_checks.remove(object.handle);
+				
+				/* Remove everything not found from the context */
+				_checks.for_each((k, v) => { Context.for_app().remove_object((Seahorse.Object)v); });
+
+				loaded_objects(objects);
+			}
+		}
+
+		/* ------------------------------------------------------------------------------- 
+		 * LOAD OPREATION
+		 */
+
+		private class Loader : Updater {
+			
+			/* The handle to load */
+			private GP11.Attributes _unique_attrs;
+			public GP11.Attributes unique_attrs {
+				get { return _unique_attrs; }
+				construct { _unique_attrs = value; }
+			}
+			
+			public Loader(Source source, GP11.Attributes unique_attrs) {
+				this.source = source;
+				this.unique_attrs = unique_attrs;
+			}
+			
+			/* Search for the object to load */
+			protected override void load_objects() {
+				_session.find_objects_async(_unique_attrs, cancellable, on_find_objects);
+			}
+			
+			private void on_find_objects(GLib.Object obj, GLib.AsyncResult result) {
+				GP11.Session session = (GP11.Session)obj;
+				/* Get the results */
+				try {
+					var objects = session.find_objects_finish(result);
+					loaded_objects(objects);
+				} catch (GLib.Error err) {
+					complete(err);
+					return;
+				}
+			}
+		}
+
+		/* ------------------------------------------------------------------------------- 
+		 * IMPORT OPREATION
+		 */
+
+		private class Importer : Updater {
+			
+			private GP11.Attributes _import_data;
+			public GP11.Attributes import_data {
+				get { return _import_data; }
+			}
+			
+			public Importer(Source source, GP11.Attributes import) {
+				this.source = source;
+			}
+
+			/* Search for the object to load */
+			protected override void load_objects() {
+				_session.create_object_async(_import_data, cancellable, on_create_object);
+			}
+			
+			private void on_create_object(GLib.Object obj, GLib.AsyncResult result) {
+				GP11.Session session = (GP11.Session)obj;
+				GP11.Object import;
+				
+				/* Get the results */
+				try {
+					import = session.create_object_finish(result);
+				} catch (GLib.Error err) {
+					complete(err);
+					return;
+				}
+				
+				/* Get the list of objects imported */
+				import.get_attribute_async(P11.CKA_GNOME_IMPORT_OBJECTS, cancellable, on_get_attribute);
+			}
+			
+			private void on_get_attribute(GLib.Object obj, GLib.AsyncResult result) {
+				GP11.Object import = (GP11.Object)obj;
+				GP11.Attribute imported_handles;
+				
+				/* Get the results */
+				try {
+					imported_handles = import.get_attribute_finish(result);
+				} catch (GLib.Error err) {
+					complete(err);
+					return;
+				}
+				
+				loaded_objects(GP11.Object.from_handle_array(_session, imported_handles));
+			}
+		}
+		
+		/* ------------------------------------------------------------------------------- 
+		 * REMOVE OPREATION
+		 */
+
+		private class Remover : Operation {
+
+			/* For cancelling the GP11 operations */
+			private GLib.Cancellable _cancellable;
+			public GLib.Cancellable cancellable { 
+				get { return _cancellable; }
+			}
+
+			/* The source we're removing from */
+			private Source _source;
+			public Source source {
+				get { return _source; }
+				construct { _source = value; }
+			}
+			
+			private Certificate _certificate;
+			public Certificate certificate {
+				get { return _certificate; }
+				construct { _certificate = value; }
+			}
+
+			public Remover(Certificate certificate) {
+				this.certificate = certificate;
+			}
+			
+			construct {
+				_cancellable = new Cancellable();
+				_certificate.pkcs11_object.destroy_async(_cancellable, on_destroy_object);
+				mark_start ();
+			}
+			
+			private void on_destroy_object(GLib.Object obj, GLib.AsyncResult result) {
+				GP11.Object object = (GP11.Object)obj;
+				
+				/* Check for errors */
+				try {
+					object.destroy_finish(result);
+				} catch (GLib.Error err) {
+					if (err.code == P11.CKR_FUNCTION_CANCELED)
+						mark_done(true, null);
+					else
+						mark_done(false, err);
+					return;
+				}
+				
+				Context.for_app().remove_object(certificate);
+				mark_done(false, null);
+			}
+			
+			/* Cancel the operation */
+			public override void cancel() {
+				_cancellable.cancel();
+			}
+		}
+		
+		/* ---------------------------------------------------------------------------------
+		 * PUBLIC STUFF
+		 */
+		
+		public Source(GP11.Slot slot) {
+			this.slot = slot;
+		}
+
+		/* ---------------------------------------------------------------------------------
+		 * VIRTUAL METHODS
+		 */
+		
+		public override Operation load(GLib.Quark id) {
+			
+			/* Load all objects */
+			if (id == 0) 
+				return new Refresher(this);
+
+			/* Load only objects described by the id */
+			GP11.Attributes attrs = new GP11.Attributes();
+			if (!Pkcs11.id_to_attributes (id, attrs))
+				return new Operation.complete(new GLib.Error(ERROR_DOMAIN, 0, "%s", _("Invalid or unrecognized object.")));
+			else 
+				return new Loader(this, attrs);
+		}
+		
+		public virtual Operation import (GLib.InputStream input) {
+			uchar[] data = Util.read_to_memory(input);
+			
+			var attrs = new GP11.Attributes();
+			attrs.add_boolean(P11.CKA_GNOME_IMPORT_TOKEN, true);
+			attrs.add_data(P11.CKA_VALUE, data);
+			
+			return new Importer(this, attrs);
+		}
+		
+		public virtual Operation export (GLib.List<weak Object> objects, 
+		                                 GLib.OutputStream output) {
+			return new Operation.complete(new GLib.Error(ERROR_DOMAIN, 0, "%s", _("Exporting is not yet supported.")));
+		}
+		
+		public virtual Operation remove (Object object) {
+			return new Remover((Pkcs11.Certificate)object);
+		}
+		
+		/* --------------------------------------------------------------------------------
+		 * HELPER METHODS
+		 */
+		
+		void receive_object(GP11.Object object, GP11.Attributes attrs) {
+			
+			/* Build up an identifier for this object */
+			GLib.Quark id = Pkcs11.id_from_attributes(attrs);
+			return_if_fail(id != 0);
+
+			bool created = false;
+			Pkcs11.Certificate cert;
+			
+			/* Look for an already present object */
+			var prev = Context.for_app().get_object(this, id);
+			if (prev != null && prev.get_type() == typeof(Pkcs11.Certificate)) {
+				cert = (Pkcs11.Certificate)prev;
+				cert.pkcs11_object = object;
+				cert.pkcs11_attributes = attrs;
+				return;
+			}
+			
+			/* Create a new object */
+			cert = new Pkcs11.Certificate(object, attrs);
+			Context.for_app().add_object(cert);
+		}
+	}
+}

Modified: trunk/pkcs11/seahorse-pkcs11.c
==============================================================================
--- trunk/pkcs11/seahorse-pkcs11.c	(original)
+++ trunk/pkcs11/seahorse-pkcs11.c	Sun Aug  3 20:48:08 2008
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <pkcs11.h>
+#include <pkcs11g.h>
 
 
 

Modified: trunk/pkcs11/vala-build.stamp
==============================================================================
--- trunk/pkcs11/vala-build.stamp	(original)
+++ trunk/pkcs11/vala-build.stamp	Sun Aug  3 20:48:08 2008
@@ -1 +1 @@
-1217171779
+1217796417

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Sun Aug  3 20:48:08 2008
@@ -58,6 +58,12 @@
 SSH_LDADD = 
 endif
 
+if WITH_PKCS11
+PKCS11_LDADD = $(top_builddir)/pkcs11/libseahorse-pkcs11.la
+else
+PKCS11_LDADD = 
+endif
+
 bin_PROGRAMS = seahorse
 
 seahorse_SOURCES = main.c \
@@ -72,6 +78,7 @@
 	$(top_builddir)/libseahorse/libseahorse.la \
 	$(PGP_LDADD) \
 	$(SSH_LDADD) \
+	$(PKCS11_LDADD) \
 	$(top_builddir)/gkr/libseahorse-gkr.la \
 	$(top_builddir)/common/libseahorse-common.la \
 	$(top_builddir)/libcryptui/libcryptui.la \

Modified: trunk/src/main.c
==============================================================================
--- trunk/src/main.c	(original)
+++ trunk/src/main.c	Sun Aug  3 20:48:08 2008
@@ -41,6 +41,10 @@
 #include "ssh/seahorse-ssh-module.h"
 #endif
 
+#ifdef WITH_PKCS11
+#include "pkcs11/seahorse-pkcs11-module.h"
+#endif
+
 #include "gkr/seahorse-gkr-module.h"
 
 #include <locale.h>
@@ -78,6 +82,9 @@
 #ifdef WITH_SSH
     seahorse_ssh_module_init ();
 #endif
+#ifdef WITH_PKCS11
+    seahorse_pkcs11_module_init ();
+#endif
 
     op = seahorse_context_refresh_local (SCTX_APP ());
 

Modified: trunk/src/vala-build.stamp
==============================================================================
--- trunk/src/vala-build.stamp	(original)
+++ trunk/src/vala-build.stamp	Sun Aug  3 20:48:08 2008
@@ -1 +1 @@
-1217175278
+1217782718

Modified: trunk/ssh/seahorse-ssh-source.c
==============================================================================
--- trunk/ssh/seahorse-ssh-source.c	(original)
+++ trunk/ssh/seahorse-ssh-source.c	Sun Aug  3 20:48:08 2008
@@ -569,7 +569,7 @@
     	g_return_val_if_fail (SEAHORSE_IS_SSH_SOURCE (ssrc), NULL);
     	g_return_val_if_fail (G_IS_INPUT_STREAM (input), NULL);
 
-    	contents = seahorse_util_read_to_text (input, NULL);
+    	contents = (gchar*)seahorse_util_read_to_memory (input, NULL);
     
     memset (&ctx, 0, sizeof (ctx));
     ctx.ssrc = ssrc;

Modified: trunk/ssh/vala-build.stamp
==============================================================================
--- trunk/ssh/vala-build.stamp	(original)
+++ trunk/ssh/vala-build.stamp	Sun Aug  3 20:48:08 2008
@@ -1 +1 @@
-1217171790
+1217782699



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