[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