summaryrefslogtreecommitdiff
path: root/gcr/gcr-pkcs11-importer.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcr/gcr-pkcs11-importer.c')
-rw-r--r--gcr/gcr-pkcs11-importer.c910
1 files changed, 0 insertions, 910 deletions
diff --git a/gcr/gcr-pkcs11-importer.c b/gcr/gcr-pkcs11-importer.c
deleted file mode 100644
index 5cc60b62..00000000
--- a/gcr/gcr-pkcs11-importer.c
+++ /dev/null
@@ -1,910 +0,0 @@
-/*
- * gnome-keyring
- *
- * Copyright (C) 2008 Stefan Walter
- * Copyright (C) 2011 Collabora Ltd.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
- *
- * Author: Stef Walter <stefw@collabora.co.uk>
- */
-
-#include "config.h"
-
-#define DEBUG_FLAG GCR_DEBUG_IMPORT
-#include "gcr-debug.h"
-#include "gcr-fingerprint.h"
-#include "gcr-icons.h"
-#include "gcr-internal.h"
-#include "gcr-library.h"
-#include "gcr-import-interaction.h"
-#include "gcr-internal.h"
-#include "gcr-parser.h"
-#include "gcr-pkcs11-importer.h"
-
-#include "egg/egg-hex.h"
-
-#include <gck/gck.h>
-
-#include <gcrypt.h>
-
-#include <glib/gi18n-lib.h>
-
-enum {
- PROP_0,
- PROP_LABEL,
- PROP_ICON,
- PROP_INTERACTION,
- PROP_SLOT,
- PROP_IMPORTED,
- PROP_QUEUED
-};
-
-typedef struct _GcrPkcs11ImporterClass GcrPkcs11ImporterClass;
-
-struct _GcrPkcs11Importer {
- GObject parent;
- GckSlot *slot;
- GList *objects;
- GckSession *session;
- GQueue *queue;
- GTlsInteraction *interaction;
- gboolean any_private;
-};
-
-struct _GcrPkcs11ImporterClass {
- GObjectClass parent_class;
-};
-
-typedef struct {
- GcrPkcs11Importer *importer;
- GCancellable *cancellable;
- gboolean prompted;
- gboolean async;
- GckAttributes *supplement;
-} GcrImporterData;
-
-/* State forward declarations */
-static void state_cancelled (GSimpleAsyncResult *res,
- gboolean async);
-
-static void state_complete (GSimpleAsyncResult *res,
- gboolean async);
-
-static void state_create_object (GSimpleAsyncResult *res,
- gboolean async);
-
-static void state_supplement (GSimpleAsyncResult *res,
- gboolean async);
-
-static void state_open_session (GSimpleAsyncResult *res,
- gboolean async);
-
-static void _gcr_pkcs11_importer_init_iface (GcrImporterIface *iface);
-
-G_DEFINE_TYPE_WITH_CODE (GcrPkcs11Importer, _gcr_pkcs11_importer, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (GCR_TYPE_IMPORTER, _gcr_pkcs11_importer_init_iface);
-);
-
-#define BLOCK 4096
-
-static void
-gcr_importer_data_free (gpointer data)
-{
- GcrImporterData *state = data;
-
- g_clear_object (&state->cancellable);
- g_clear_object (&state->importer);
- g_free (state);
-}
-
-static void
-next_state (GSimpleAsyncResult *res,
- void (*state) (GSimpleAsyncResult *, gboolean))
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
-
- g_assert (state);
-
- if (g_cancellable_is_cancelled (data->cancellable))
- state = state_cancelled;
-
- (state) (res, data->async);
-}
-
-/* ---------------------------------------------------------------------------------
- * COMPLETE
- */
-
-static void
-state_complete (GSimpleAsyncResult *res,
- gboolean async)
-{
- g_simple_async_result_complete (res);
-}
-
-static void
-state_cancelled (GSimpleAsyncResult *res,
- gboolean async)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GError *error = NULL;
-
- if (data->cancellable && !g_cancellable_is_cancelled (data->cancellable))
- g_cancellable_cancel (data->cancellable);
-
- g_cancellable_set_error_if_cancelled (data->cancellable, &error);
- g_simple_async_result_take_error (res, error);
- next_state (res, state_complete);
-}
-
-/* ---------------------------------------------------------------------------------
- * CREATE OBJECTS
- */
-
-static void
-complete_create_object (GSimpleAsyncResult *res,
- GckObject *object,
- GError *error)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GcrPkcs11Importer *self = data->importer;
-
- if (object == NULL) {
- g_simple_async_result_take_error (res, error);
- next_state (res, state_complete);
-
- } else {
- self->objects = g_list_append (self->objects, object);
- next_state (res, state_create_object);
- }
-}
-
-static void
-on_create_object (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- GError *error = NULL;
- GckObject *object;
-
- object = gck_session_create_object_finish (GCK_SESSION (source), result, &error);
- complete_create_object (res, object, error);
- g_object_unref (res);
-}
-
-static void
-state_create_object (GSimpleAsyncResult *res,
- gboolean async)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GcrPkcs11Importer *self = data->importer;
- GckAttributes *attrs;
- GckObject *object;
- GError *error = NULL;
-
- /* No more objects */
- if (g_queue_is_empty (self->queue)) {
- next_state (res, state_complete);
-
- } else {
-
- /* Pop first one off the list */
- attrs = g_queue_pop_head (self->queue);
- g_assert (attrs != NULL);
-
- if (async) {
- gck_session_create_object_async (self->session, attrs,
- data->cancellable, on_create_object,
- g_object_ref (res));
- } else {
- object = gck_session_create_object (self->session, attrs,
- data->cancellable, &error);
- complete_create_object (res, object, error);
- }
-
- gck_attributes_unref (attrs);
- }
-}
-
-/* ---------------------------------------------------------------------------------
- * SUPPLEMENTING and FIXING UP
- */
-
-typedef struct {
- GckAttributes *certificate;
- GckAttributes *private_key;
-} CertificateKeyPair;
-
-static void
-supplement_with_attributes (GckAttributes *attrs,
- GckAttributes *supplements)
-{
- GckAttribute *supplement;
- gint i;
-
- for (i = 0; i < gck_attributes_count (supplements); i++) {
- supplement = gck_attributes_at (supplements, i);
- if (!gck_attribute_is_invalid (supplement) && supplement->length != 0)
- gck_attributes_add (attrs, supplement);
- }
-}
-
-static void
-supplement_id_for_data (GckAttributes *attrs,
- guchar *nonce,
- gsize n_once,
- gpointer data,
- gsize n_data)
-{
- gcry_md_hd_t mdh;
- gcry_error_t gcry;
-
- if (gck_attributes_find (attrs, CKA_ID) != NULL)
- return;
-
- gcry = gcry_md_open (&mdh, GCRY_MD_SHA1, 0);
- g_return_if_fail (gcry == 0);
-
- gcry_md_write (mdh, nonce, n_once);
- gcry_md_write (mdh, data, n_data);
-
- gck_attributes_add_data (attrs, CKA_ID,
- gcry_md_read (mdh, 0),
- gcry_md_get_algo_dlen (GCRY_MD_SHA1));
-
- gcry_md_close (mdh);
-}
-
-static void
-supplement_attributes (GcrPkcs11Importer *self,
- GckAttributes *supplements)
-{
- GHashTable *pairs;
- GHashTable *paired;
- CertificateKeyPair *pair;
- gboolean supplemented = FALSE;
- GckAttributes *attrs;
- gulong klass;
- guchar *finger;
- gchar *fingerprint;
- guchar nonce[20];
- GHashTableIter iter;
- gsize n_finger;
- GQueue *queue;
- GList *l;
-
- /* A table of certificate/key pairs by fingerprint */
- pairs = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, g_free);
-
- for (l = self->queue->head; l != NULL; l = g_list_next (l)) {
- attrs = l->data;
- if (!gck_attributes_find_ulong (attrs, CKA_CLASS, &klass))
- g_return_if_reached ();
-
- /* Make a string fingerprint for this guy */
- finger = gcr_fingerprint_from_attributes (attrs, G_CHECKSUM_SHA1,
- &n_finger);
- if (finger) {
- fingerprint = egg_hex_encode (finger, n_finger);
- g_free (finger);
-
- pair = g_hash_table_lookup (pairs, fingerprint);
- if (pair == NULL) {
- pair = g_new0 (CertificateKeyPair, 1);
- g_hash_table_insert (pairs, fingerprint, pair);
- } else {
- g_free (fingerprint);
- }
- } else {
- pair = NULL;
- }
-
- fingerprint = NULL;
-
- gck_attributes_set_boolean (attrs, CKA_TOKEN, CK_TRUE);
-
- switch (klass) {
- case CKO_CERTIFICATE:
- gck_attributes_set_boolean (attrs, CKA_PRIVATE, FALSE);
- if (pair != NULL && pair->certificate == NULL)
- pair->certificate = attrs;
- break;
- case CKO_PRIVATE_KEY:
- gck_attributes_set_boolean (attrs, CKA_PRIVATE, TRUE);
- gck_attributes_add_boolean (attrs, CKA_DECRYPT, TRUE);
- gck_attributes_add_boolean (attrs, CKA_SIGN, TRUE);
- gck_attributes_add_boolean (attrs, CKA_SIGN_RECOVER, TRUE);
- gck_attributes_add_boolean (attrs, CKA_UNWRAP, TRUE);
- gck_attributes_add_boolean (attrs, CKA_SENSITIVE, TRUE);
- if (pair != NULL && pair->private_key == NULL)
- pair->private_key = attrs;
- break;
- }
- }
-
- /* For generation of CKA_ID's */
- gcry_create_nonce (nonce, sizeof (nonce));
-
- /* A table for marking which attributes are in the pairs table */
- paired = g_hash_table_new (g_direct_hash, g_direct_equal);
-
- /* Now move everything in pairs to the front */
- queue = g_queue_new ();
- g_hash_table_iter_init (&iter, pairs);
- while (g_hash_table_iter_next (&iter, (gpointer *)&fingerprint, (gpointer *)&pair)) {
- if (pair->certificate != NULL && pair->private_key != NULL) {
- /*
- * Generate a CKA_ID based on the fingerprint and nonce,
- * and do the same CKA_ID for both private key and certificate.
- */
-
- supplement_with_attributes (pair->private_key, supplements);
- supplement_id_for_data (pair->private_key, nonce, sizeof (nonce),
- fingerprint, strlen (fingerprint));
- g_queue_push_tail (queue, pair->private_key);
- g_hash_table_insert (paired, pair->private_key, "present");
-
- supplement_with_attributes (pair->private_key, supplements);
- supplement_id_for_data (pair->certificate, nonce, sizeof (nonce),
- fingerprint, strlen (fingerprint));
- g_queue_push_tail (queue, pair->certificate);
- g_hash_table_insert (paired, pair->certificate, "present");
-
- /* Used the suplements for the pairs, don't use for unpaired stuff */
- supplemented = TRUE;
- }
- }
-
- /* Go through the old queue, and look for anything not paired */
- for (l = self->queue->head; l != NULL; l = g_list_next (l)) {
- attrs = l->data;
- if (!g_hash_table_lookup (paired, attrs)) {
- if (!supplemented)
- supplement_with_attributes (attrs, supplements);
-
- /*
- * Generate a CKA_ID based on the location of attrs in,
- * memory, since this together with the nonce should
- * be unique.
- */
- supplement_id_for_data (attrs, nonce, sizeof (nonce),
- &attrs, sizeof (gpointer));
-
- g_queue_push_tail (queue, l->data);
- }
- }
-
- /* And swap the new queue into place */
- g_queue_free (self->queue);
- self->queue = queue;
-
- g_hash_table_destroy (paired);
- g_hash_table_destroy (pairs);
-}
-
-static void
-complete_supplement (GSimpleAsyncResult *res,
- GError *error)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
-
- if (error == NULL) {
- supplement_attributes (data->importer, data->supplement);
- next_state (res, state_create_object);
- } else {
- g_simple_async_result_take_error (res, error);
- next_state (res, state_complete);
- }
-}
-
-static void
-on_supplement_done (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GcrPkcs11Importer *self = data->importer;
- GError *error = NULL;
-
- gcr_import_interaction_supplement_finish (GCR_IMPORT_INTERACTION (self->interaction),
- result, &error);
- complete_supplement (res, error);
- g_object_unref (res);
-}
-
-static void
-state_supplement (GSimpleAsyncResult *res,
- gboolean async)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GcrPkcs11Importer *self = data->importer;
- GError *error = NULL;
-
- if (self->interaction == NULL || !GCR_IS_IMPORT_INTERACTION (self->interaction)) {
- complete_supplement (res, NULL);
-
- } else if (async) {
- gcr_import_interaction_supplement_async (GCR_IMPORT_INTERACTION (self->interaction),
- data->supplement, data->cancellable,
- on_supplement_done, g_object_ref (res));
-
- } else {
- gcr_import_interaction_supplement (GCR_IMPORT_INTERACTION (self->interaction),
- data->supplement, data->cancellable, &error);
- complete_supplement (res, error);
- }
-}
-
-static void
-supplement_prep (GSimpleAsyncResult *res)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GcrPkcs11Importer *self = data->importer;
- GckAttribute *the_label = NULL;
- GckAttribute *attr;
- gboolean first = TRUE;
- GList *l;
-
- if (data->supplement)
- gck_attributes_unref (data->supplement);
- data->supplement = gck_attributes_new ();
-
- /* Do we have a consistent label across all objects? */
- for (l = self->queue->head; l != NULL; l = g_list_next (l)) {
- attr = gck_attributes_find (l->data, CKA_LABEL);
- if (first)
- the_label = attr;
- else if (!gck_attribute_equal (the_label, attr))
- the_label = NULL;
- first = FALSE;
- }
-
- /* If consistent label, set that in supplement data */
- if (the_label != NULL)
- gck_attributes_add (data->supplement, the_label);
- else
- gck_attributes_add_empty (data->supplement, CKA_LABEL);
-
- if (GCR_IS_IMPORT_INTERACTION (self->interaction))
- gcr_import_interaction_supplement_prep (GCR_IMPORT_INTERACTION (self->interaction),
- data->supplement);
-}
-
-/* ---------------------------------------------------------------------------------
- * OPEN SESSION
- */
-
-static void
-complete_open_session (GSimpleAsyncResult *res,
- GckSession *session,
- GError *error)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GcrPkcs11Importer *self = data->importer;
-
- if (!session) {
- g_simple_async_result_take_error (res, error);
- next_state (res, state_complete);
-
- } else {
- g_clear_object (&self->session);
- self->session = session;
- next_state (res, state_supplement);
- }
-}
-
-static void
-on_open_session (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- GSimpleAsyncResult *res = G_SIMPLE_ASYNC_RESULT (user_data);
- GError *error = NULL;
- GckSession *session;
-
- session = gck_slot_open_session_finish (GCK_SLOT (source), result, &error);
- complete_open_session (res, session, error);
- g_object_unref (res);
-}
-
-static void
-state_open_session (GSimpleAsyncResult *res,
- gboolean async)
-{
- GcrImporterData *data = g_simple_async_result_get_op_res_gpointer (res);
- GcrPkcs11Importer *self = data->importer;
- guint options = GCK_SESSION_READ_WRITE | GCK_SESSION_LOGIN_USER;
- GckSession *session;
- GError *error = NULL;
-
- if (async) {
- gck_slot_open_session_async (self->slot, options,
- data->cancellable, on_open_session,
- g_object_ref (res));
- } else {
- session = gck_slot_open_session_full (self->slot, options, 0,
- NULL, NULL, data->cancellable, &error);
- complete_open_session (res, session, error);
- }
-}
-
-static void
-_gcr_pkcs11_importer_init (GcrPkcs11Importer *self)
-{
- self->queue = g_queue_new ();
-}
-
-static void
-_gcr_pkcs11_importer_dispose (GObject *obj)
-{
- GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (obj);
-
- gck_list_unref_free (self->objects);
- self->objects = NULL;
- g_clear_object (&self->session);
- g_clear_object (&self->interaction);
-
- while (!g_queue_is_empty (self->queue))
- gck_attributes_unref (g_queue_pop_head (self->queue));
-
- G_OBJECT_CLASS (_gcr_pkcs11_importer_parent_class)->dispose (obj);
-}
-
-static void
-_gcr_pkcs11_importer_finalize (GObject *obj)
-{
- GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (obj);
-
- g_clear_object (&self->slot);
-
- G_OBJECT_CLASS (_gcr_pkcs11_importer_parent_class)->finalize (obj);
-}
-
-static void
-_gcr_pkcs11_importer_set_property (GObject *obj,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (obj);
-
- switch (prop_id) {
- case PROP_SLOT:
- self->slot = g_value_dup_object (value);
- g_return_if_fail (self->slot);
- break;
- case PROP_INTERACTION:
- g_clear_object (&self->interaction);
- self->interaction = g_value_dup_object (value);
- g_object_notify (G_OBJECT (self), "interaction");
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static gchar *
-calculate_label (GcrPkcs11Importer *self)
-{
- GckTokenInfo *info;
- gchar *result;
-
- info = gck_slot_get_token_info (self->slot);
- result = g_strdup (info->label);
- gck_token_info_free (info);
-
- return result;
-}
-
-static GIcon *
-calculate_icon (GcrPkcs11Importer *self,
- GckTokenInfo *token_info)
-{
- GckTokenInfo *info = NULL;
- GIcon *result;
-
- if (token_info == NULL)
- info = token_info = gck_slot_get_token_info (self->slot);
- result = gcr_icon_for_token (token_info);
- gck_token_info_free (info);
-
- return result;
-}
-
-static void
-_gcr_pkcs11_importer_get_property (GObject *obj,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (obj);
-
- switch (prop_id) {
- case PROP_LABEL:
- g_value_take_string (value, calculate_label (self));
- break;
- case PROP_ICON:
- g_value_take_object (value, calculate_icon (self, NULL));
- break;
- case PROP_SLOT:
- g_value_set_object (value, _gcr_pkcs11_importer_get_slot (self));
- break;
- case PROP_IMPORTED:
- g_value_take_boxed (value, _gcr_pkcs11_importer_get_imported (self));
- break;
- case PROP_QUEUED:
- g_value_set_pointer (value, _gcr_pkcs11_importer_get_queued (self));
- break;
- case PROP_INTERACTION:
- g_value_set_object (value, self->interaction);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
- break;
- }
-}
-
-static void
-_gcr_pkcs11_importer_class_init (GcrPkcs11ImporterClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
- GckAttributes *registered;
-
- gobject_class->dispose = _gcr_pkcs11_importer_dispose;
- gobject_class->finalize = _gcr_pkcs11_importer_finalize;
- gobject_class->set_property = _gcr_pkcs11_importer_set_property;
- gobject_class->get_property = _gcr_pkcs11_importer_get_property;
-
- g_object_class_override_property (gobject_class, PROP_LABEL, "label");
-
- g_object_class_override_property (gobject_class, PROP_ICON, "icon");
-
- g_object_class_override_property (gobject_class, PROP_INTERACTION, "interaction");
-
- g_object_class_install_property (gobject_class, PROP_SLOT,
- g_param_spec_object ("slot", "Slot", "PKCS#11 slot to import data into",
- GCK_TYPE_SLOT, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
-
- g_object_class_install_property (gobject_class, PROP_IMPORTED,
- g_param_spec_boxed ("imported", "Imported", "Imported objects",
- GCK_TYPE_LIST, G_PARAM_READABLE));
-
- g_object_class_install_property (gobject_class, PROP_QUEUED,
- g_param_spec_pointer ("queued", "Queued", "Queued attributes",
- G_PARAM_READABLE));
-
- registered = gck_attributes_new ();
- gck_attributes_add_ulong (registered, CKA_CLASS, CKO_CERTIFICATE);
- gck_attributes_add_ulong (registered, CKA_CERTIFICATE_TYPE, CKC_X_509);
- gcr_importer_register (GCR_TYPE_PKCS11_IMPORTER, registered);
- gck_attributes_unref (registered);
-
- registered = gck_attributes_new ();
- gck_attributes_add_ulong (registered, CKA_CLASS, CKO_PRIVATE_KEY);
- gcr_importer_register (GCR_TYPE_PKCS11_IMPORTER, registered);
- gck_attributes_unref (registered);
-
- _gcr_initialize_library ();
-}
-
-static GList *
-list_all_slots (void)
-{
- GList *modules;
- GList *results;
-
- modules = gcr_pkcs11_get_modules ();
- results = gck_modules_get_slots (modules, TRUE);
- gck_list_unref_free (modules);
-
- return results;
-}
-
-static const char *token_blacklist[] = {
- "pkcs11:manufacturer=Gnome%20Keyring;serial=1:SECRET:MAIN",
- "pkcs11:manufacturer=Gnome%20Keyring;serial=1:USER:DEFAULT",
- NULL
-};
-
-static gboolean
-is_slot_importable (GckSlot *slot,
- GckTokenInfo *token)
-{
- GError *error = NULL;
- GckUriData *uri;
- gboolean match;
- guint i;
-
- if (token->flags & CKF_WRITE_PROTECTED) {
- _gcr_debug ("token is not importable: %s: write protected", token->label);
- return FALSE;
- }
- if (!(token->flags & CKF_TOKEN_INITIALIZED)) {
- _gcr_debug ("token is not importable: %s: not initialized", token->label);
- return FALSE;
- }
- if ((token->flags & CKF_LOGIN_REQUIRED) &&
- !(token->flags & CKF_USER_PIN_INITIALIZED)) {
- _gcr_debug ("token is not importable: %s: user pin not initialized", token->label);
- return FALSE;
- }
-
- for (i = 0; token_blacklist[i] != NULL; i++) {
- uri = gck_uri_parse (token_blacklist[i], GCK_URI_FOR_TOKEN | GCK_URI_FOR_MODULE, &error);
- if (uri == NULL) {
- g_warning ("couldn't parse pkcs11 blacklist uri: %s", error->message);
- g_clear_error (&error);
- continue;
- }
-
- match = gck_slot_match (slot, uri);
- gck_uri_data_free (uri);
-
- if (match) {
- _gcr_debug ("token is not importable: %s: on the black list", token->label);
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-static GList *
-_gcr_pkcs11_importer_create_for_parsed (GcrParsed *parsed)
-{
- GcrImporter *self;
- GList *slots, *l;
- GList *results = NULL;
- GckTokenInfo *token_info;
- gboolean importable;
-
- slots = list_all_slots ();
- for (l = slots; l != NULL; l = g_list_next (l)) {
- token_info = gck_slot_get_token_info (l->data);
- importable = is_slot_importable (l->data, token_info);
-
- if (importable) {
- _gcr_debug ("creating importer for token: %s", token_info->label);
- self = _gcr_pkcs11_importer_new (l->data);
- if (!gcr_importer_queue_for_parsed (self, parsed))
- g_assert_not_reached ();
- results = g_list_prepend (results, self);
- }
-
- gck_token_info_free (token_info);
- }
- gck_list_unref_free (slots);
-
- return g_list_reverse (results);
-}
-
-static gboolean
-_gcr_pkcs11_importer_queue_for_parsed (GcrImporter *importer,
- GcrParsed *parsed)
-{
- GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (importer);
- GckAttributes *attrs;
- const gchar *label;
-
- attrs = gcr_parsed_get_attributes (parsed);
- label = gcr_parsed_get_label (parsed);
- _gcr_pkcs11_importer_queue (self, label, attrs);
-
- return TRUE;
-}
-
-static void
-_gcr_pkcs11_importer_import_async (GcrImporter *importer,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GcrPkcs11Importer *self = GCR_PKCS11_IMPORTER (importer);
- GSimpleAsyncResult *res;
- GcrImporterData *data;
-
- res = g_simple_async_result_new (G_OBJECT (importer), callback, user_data,
- _gcr_pkcs11_importer_import_async);
- data = g_new0 (GcrImporterData, 1);
- data->async = TRUE;
- data->importer = g_object_ref (importer);
- data->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- g_simple_async_result_set_op_res_gpointer (res, data, gcr_importer_data_free);
-
- supplement_prep (res);
- gck_slot_set_interaction (self->slot, self->interaction);
-
- next_state (res, state_open_session);
- g_object_unref (res);
-}
-
-static gboolean
-_gcr_pkcs11_importer_import_finish (GcrImporter *importer,
- GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (importer),
- _gcr_pkcs11_importer_import_async), FALSE);
-
- if (g_simple_async_result_propagate_error (G_SIMPLE_ASYNC_RESULT (result), error))
- return FALSE;
-
- return TRUE;
-}
-
-static void
-_gcr_pkcs11_importer_init_iface (GcrImporterIface *iface)
-{
- iface->create_for_parsed = _gcr_pkcs11_importer_create_for_parsed;
- iface->queue_for_parsed = _gcr_pkcs11_importer_queue_for_parsed;
- iface->import_async = _gcr_pkcs11_importer_import_async;
- iface->import_finish = _gcr_pkcs11_importer_import_finish;
-}
-
-/**
- * _gcr_pkcs11_importer_new:
- *
- * Returns: (transfer full) (type Gcr.Pkcs11Importer): the new importer
- */
-GcrImporter *
-_gcr_pkcs11_importer_new (GckSlot *slot)
-{
- g_return_val_if_fail (GCK_IS_SLOT (slot), NULL);
-
- return g_object_new (GCR_TYPE_PKCS11_IMPORTER,
- "slot", slot,
- NULL);
-}
-
-GckSlot *
-_gcr_pkcs11_importer_get_slot (GcrPkcs11Importer *self)
-{
- g_return_val_if_fail (GCR_IS_PKCS11_IMPORTER (self), NULL);
- return self->slot;
-}
-
-GList *
-_gcr_pkcs11_importer_get_imported (GcrPkcs11Importer *self)
-{
- g_return_val_if_fail (GCR_IS_PKCS11_IMPORTER (self), NULL);
- return g_list_copy (self->objects);
-}
-
-GList *
-_gcr_pkcs11_importer_get_queued (GcrPkcs11Importer *self)
-{
- g_return_val_if_fail (GCR_IS_PKCS11_IMPORTER (self), NULL);
- return g_list_copy (self->queue->head);
-}
-
-void
-_gcr_pkcs11_importer_queue (GcrPkcs11Importer *self,
- const gchar *label,
- GckAttributes *attrs)
-{
- g_return_if_fail (GCR_IS_PKCS11_IMPORTER (self));
- g_return_if_fail (attrs != NULL);
-
- if (label != NULL && !gck_attributes_find (attrs, CKA_LABEL))
- gck_attributes_add_string (attrs, CKA_LABEL, label);
-
- g_queue_push_tail (self->queue, gck_attributes_ref (attrs));
-}