[rs-commit] r34 - in /redwax-signtext/trunk/src/linux: crypto.c crypto.h main.c message.c signtext.c signtext.h

rs-commit at redwax.eu rs-commit at redwax.eu
Sun Sep 4 13:59:35 CEST 2022


Author: minfrin at redwax.eu
Date: Sun Sep  4 13:59:34 2022
New Revision: 34

Log:
Add ability to plug/unplug smartcard. Filter to end entity certs only.

Modified:
    redwax-signtext/trunk/src/linux/crypto.c
    redwax-signtext/trunk/src/linux/crypto.h
    redwax-signtext/trunk/src/linux/main.c
    redwax-signtext/trunk/src/linux/message.c
    redwax-signtext/trunk/src/linux/signtext.c
    redwax-signtext/trunk/src/linux/signtext.h

Modified: redwax-signtext/trunk/src/linux/crypto.c
==============================================================================
--- redwax-signtext/trunk/src/linux/crypto.c	(original)
+++ redwax-signtext/trunk/src/linux/crypto.c	Sun Sep  4 13:59:34 2022
@@ -18,62 +18,78 @@
 
 #include "crypto.h"
 
-#if 0
-static void
-crypto_slot_done (GObject *source_object,
-                  GAsyncResult *res,
-                  gpointer user_data)
-{
-  SignTextData *signtext = user_data;
-  GckSession *session;
-  GError *gerror = NULL;
-
-  g_printerr("crypto_init_done\n");
-
-//  session = gck_slot_open_session_async(res, &gerror);
-
-  if (!session) {
-    goto fatal;
-  }
-  else {
-
-//    signtext->slots = gck_modules_get_slots(signtext->modules, FALSE);
-
-  }
-
-  if (gerror) {
-fatal:
-
-    GtkWidget* dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
-                                                GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
-                                                "%s", ("Redwax SignText - Error"));
-    gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
-                                                  ("Error: %s"),
-                                                  gerror->message);
-
-    g_error_free (gerror);
-
-    gtk_widget_show (dialog);
-
-  }
-}
-
-static void
-crypto_slot_init (gpointer data, gpointer user_data)
+#ifndef CK_CERTIFICATE_CATEGORY_TOKEN_USER
+#define CK_CERTIFICATE_CATEGORY_TOKEN_USER 0x00000001UL
+#endif
+
+static gboolean
+crypto_filter_match (GObject *obj,
+                    gpointer data)
+{
+  GckAttributes *attrs;
+  gulong category;
+  gboolean is_ca;
+
+  if (!GCR_IS_PKCS11_CERTIFICATE(obj)) {
+    return FALSE;
+  }
+
+  attrs = gcr_pkcs11_certificate_get_attributes(GCR_PKCS11_CERTIFICATE(obj));
+
+  /*
+   * Some smartcards have no CKA_CERTIFICATE_CATEGORY, and so silently fail. Keep
+   * the filter active when the CKA_CERTIFICATE_CATEGORY is present, but let the
+   * certificate be visible if CKA_CERTIFICATE_CATEGORY is absent.
+   */
+  if (gck_attributes_find_ulong(attrs, CKA_CERTIFICATE_CATEGORY, &category)) {
+    if (category != CK_CERTIFICATE_CATEGORY_TOKEN_USER) {
+      return FALSE;
+    }
+  }
+
+  /*
+   * Is our certificate an intermediate? Filter them out at this stage.
+   */
+  if (gcr_certificate_get_basic_constraints(GCR_CERTIFICATE(obj), &is_ca, NULL)) {
+    if (is_ca) {
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+GcrCollection *
+crypto_filter(GcrCollection *certificates)
+{
+  GcrCollection *collection;
+
+  collection = gcr_filter_collection_new_with_callback (GCR_COLLECTION (certificates),
+			crypto_filter_match,
+			NULL, NULL);
+
+
+  return collection;
+}
+
+static void
+crypto_slots_count (gpointer data, gpointer user_data)
 {
   GckSlot *slot = data;
-  SignTextData *signtext = user_data;
-
-  g_printerr("crypto_slot_init\n");
-
-//  gck_slot_open_session_async(slot, GCK_SESSION_READ_ONLY, signtext->cancellable, (GAsyncReadyCallback)crypto_slot_done, signtext);
-
-
-}
-#endif
-
-static void
-crypto_certs_done (GObject *source_object,
+  guint *slots_len = user_data;
+  GckSlotInfo *info;
+
+  info = gck_slot_get_info (slot);
+
+  if ((info->flags & CKF_TOKEN_PRESENT)) {
+    (*slots_len)++;
+  }
+
+  gck_slot_info_free(info);
+}
+
+static void
+crypto_slots_done (GObject *source_object,
                    GAsyncResult *res,
                    gpointer user_data)
 {
@@ -81,7 +97,7 @@
   GList *incoming, *current, *l;
   GError *gerror = NULL;
 
-  g_printerr("crypto_certs_done\n");
+  g_printerr("crypto_slots_done\n");
 
   current = gcr_collection_get_objects(signtext->certificates);
 
@@ -105,23 +121,23 @@
 
 }
 
-static void
-crypto_init_done (GObject *source_object,
-                      GAsyncResult *res,
-                      gpointer user_data)
+static gboolean
+crypto_slots_do (
+  gpointer user_data
+)
 {
   SignTextData *signtext = user_data;
-  GError *gerror = NULL;
-
-  g_printerr("crypto_init_done\n");
-
-  signtext->modules = gck_modules_initialize_registered_finish(res, &gerror);
-
-  if (!g_list_length(signtext->modules)) {
-    gerror = g_error_new(RST_CORE_ERROR, RST_CORE_ERROR_NO_MODULES, "No PKCS11 modules are available on this system. Text cannot be signed.");
-    goto fatal;
-  }
-  else {
+  GList *slots;
+
+  guint slots_len = 0;
+
+  slots = gck_modules_get_slots(signtext->modules, TRUE);
+
+  g_list_foreach(slots, crypto_slots_count, &slots_len);
+
+  if (slots_len != signtext->slots_len) {
+
+    g_printerr("crypto_slots_do: %d/%d\n", slots_len, signtext->slots_len);
 
     /*
      * The minumum you must request to get a certificate back that will display in a dropdown
@@ -146,19 +162,54 @@
 
     gck_enumerator_set_object_type_full(cenum, GCR_TYPE_PKCS11_CERTIFICATE, CERTIFICATE_ATTRS, G_N_ELEMENTS (CERTIFICATE_ATTRS));
 
-    gck_enumerator_next_async(cenum, -1, signtext->cancellable, crypto_certs_done, signtext);
-
-//    signtext->slots = gck_modules_get_slots(signtext->modules, FALSE);
-
-//    g_list_foreach(signtext->slots, crypto_slot_init, signtext);
-
-//    gck_slots_enumerate_objects(signtext->slots, gck_builder_end (&builder), GCK_SESSION_READ_ONLY);
+    gck_enumerator_next_async(cenum, -1, signtext->cancellable, crypto_slots_done, signtext);
+
+    signtext->slots_len = slots_len;
+
+  }
+
+  gck_list_unref_free(slots);
+
+  return TRUE;
+}
+
+static void
+crypto_slots_start(SignTextData *signtext)
+{
+  g_timeout_add_seconds(2, crypto_slots_do, signtext);
+}
+
+static void
+crypto_init_done (GObject *source_object,
+                  GAsyncResult *res,
+                  gpointer user_data)
+{
+  SignTextData *signtext = user_data;
+  GError *gerror = NULL;
+
+  g_printerr("crypto_init_done\n");
+
+  signtext->modules = gck_modules_initialize_registered_finish(res, &gerror);
+
+  if (!g_list_length(signtext->modules)) {
+    gerror = g_error_new(RST_CORE_ERROR, RST_CORE_ERROR_NO_MODULES, "No PKCS11 modules are available on this system. Text cannot be signed.");
+    goto fatal;
+  }
+  else {
+
+    /*
+     * Start watching the slots for changes.
+     */
+    crypto_slots_start(signtext);
+
   }
 
   if (gerror) {
+    GtkWidget* dialog;
+
 fatal:
 
-    GtkWidget* dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
+    dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
                                                 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
                                                 "%s", ("Redwax SignText - Error"));
     gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),

Modified: redwax-signtext/trunk/src/linux/crypto.h
==============================================================================
--- redwax-signtext/trunk/src/linux/crypto.h	(original)
+++ redwax-signtext/trunk/src/linux/crypto.h	Sun Sep  4 13:59:34 2022
@@ -25,6 +25,10 @@
 void
 crypto_start(SignTextData *signtext);
 
+GcrCollection *
+crypto_filter(GcrCollection *certificates);
+
+
 #endif
 
 

Modified: redwax-signtext/trunk/src/linux/main.c
==============================================================================
--- redwax-signtext/trunk/src/linux/main.c	(original)
+++ redwax-signtext/trunk/src/linux/main.c	Sun Sep  4 13:59:34 2022
@@ -119,7 +119,7 @@
   GtkApplication *app;
   int status;
 
-  SignTextData *signtext = g_new (SignTextData, 1);
+  SignTextData *signtext = signtext_data_new();
 
   app = gtk_application_new("eu.redwax.signtext", G_APPLICATION_NON_UNIQUE | G_APPLICATION_HANDLES_COMMAND_LINE);
 
@@ -128,7 +128,7 @@
   status = g_application_run(G_APPLICATION (app), argc, argv);
   g_object_unref(app);
 
-  g_free(signtext);
+  signtext_data_free(signtext);
 
   return status;
 }

Modified: redwax-signtext/trunk/src/linux/message.c
==============================================================================
--- redwax-signtext/trunk/src/linux/message.c	(original)
+++ redwax-signtext/trunk/src/linux/message.c	Sun Sep  4 13:59:34 2022
@@ -22,6 +22,7 @@
 #include <json-glib/json-glib.h>
 
 #include "signtext.h"
+#include "crypto.h"
 #include "message.h"
 #include "config.h"
 
@@ -149,9 +150,9 @@
      */
     else if (json_node_get_node_type(request) == JSON_NODE_OBJECT) {
 
-        instance->selector = gcr_combo_selector_new(signtext->certificates);
-
-	//gcr_filter_collection_new_with_callback();
+        GcrCollection *certificates = crypto_filter(signtext->certificates);
+ 
+        instance->selector = gcr_combo_selector_new(certificates);
 
 #ifdef HAVE_GTK_BOX_APPEND
   	gtk_box_append (instance->box, GTK_WIDGET(instance->textview));
@@ -180,9 +181,11 @@
   }
 
   if (gerror) {
+    GtkWidget* dialog;
+
 fatal:
 
-    GtkWidget* dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
+    dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL,
                                                 GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
                                                 "%s", ("Redwax SignText - Error"));
     gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),

Modified: redwax-signtext/trunk/src/linux/signtext.c
==============================================================================
--- redwax-signtext/trunk/src/linux/signtext.c	(original)
+++ redwax-signtext/trunk/src/linux/signtext.c	Sun Sep  4 13:59:34 2022
@@ -27,11 +27,19 @@
   return quark;
 }
 
+SignTextData *signtext_data_new()
+{
+  SignTextData *signtext = g_new (SignTextData, 1);
+
+  memset(signtext, 0, sizeof(SignTextData));
+
+  return signtext;
+}
+
 void signtext_data_free(SignTextData *data)
 {
   if (data) {
     if (data->certificates) g_object_unref(data->certificates);
-    if (data->slots) gck_list_unref_free(data->slots);
     if (data->modules) gck_list_unref_free(data->modules);
   }
   g_free(data);

Modified: redwax-signtext/trunk/src/linux/signtext.h
==============================================================================
--- redwax-signtext/trunk/src/linux/signtext.h	(original)
+++ redwax-signtext/trunk/src/linux/signtext.h	Sun Sep  4 13:59:34 2022
@@ -51,8 +51,8 @@
   GtkStackSwitcher *switcher;
   GtkStack *stack;
   GList *modules;
-  GList *slots;
   GcrCollection *certificates;
+  guint slots_len;
 } SignTextData;
 
 typedef struct SignTextInstance {
@@ -66,6 +66,9 @@
   GcrComboSelector *selector;
 } SignTextInstance;
 
+SignTextData *signtext_data_new();
+void signtext_data_free(SignTextData *data);
+
 SignTextInstance *signtext_instance_new(gint64 id, const gchar *uuid, GUri *uri);
 void signtext_instance_free(SignTextInstance *instance);
 



More information about the rs-commit mailing list