[rs-commit] r35 - 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
Mon Sep 5 12:50:21 CEST 2022
Author: minfrin at redwax.eu
Date: Mon Sep 5 12:50:20 2022
New Revision: 35
Log:
Have the UI respond to the pinpad type / pin params for each certificate.
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 Mon Sep 5 12:50:20 2022
@@ -29,7 +29,7 @@
GckAttributes *attrs;
gulong category;
gboolean is_ca;
-
+return TRUE;
if (!GCR_IS_PKCS11_CERTIFICATE(obj)) {
return FALSE;
}
@@ -88,36 +88,103 @@
gck_slot_info_free(info);
}
-static void
-crypto_slots_done (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- SignTextData *signtext = user_data;
+static gboolean
+crypto_slots_do (
+ gpointer user_data
+);
+
+static void
+crypto_slot_do (gpointer user_data);
+
+static void
+crypto_slot_done (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ SignTextToken *signtext_token = user_data;
+ SignTextData *signtext = signtext_token->signtext;
GList *incoming, *current, *l;
GError *gerror = NULL;
g_printerr("crypto_slots_done\n");
- current = gcr_collection_get_objects(signtext->certificates);
-
incoming = gck_enumerator_next_finish(GCK_ENUMERATOR(source_object), res, &gerror);
- for (l = current; l; l = g_list_next (l)) {
- if (!g_list_find(incoming, l->data)) {
- gcr_simple_collection_remove(GCR_SIMPLE_COLLECTION(signtext->certificates), l->data);
- g_object_unref(l->data);
- }
- }
-
for (l = incoming; l; l = g_list_next (l)) {
- if (!g_list_find(current, l->data)) {
+ if (!gcr_collection_contains(signtext->incoming, l->data)) {
g_object_ref(l->data);
- gcr_simple_collection_add(GCR_SIMPLE_COLLECTION(signtext->certificates), l->data);
+ g_object_set_data_full(l->data, "token-info",
+ gck_token_info_copy(signtext_token->token_info),
+ (GDestroyNotify)gck_token_info_free);
+ gcr_simple_collection_add(GCR_SIMPLE_COLLECTION(signtext->incoming), l->data);
}
}
gck_list_unref_free(incoming);
+
+ if (signtext_token->next) {
+ g_idle_add((GSourceFunc)crypto_slot_do, signtext_token->next);
+ }
+ else {
+
+ incoming = gcr_collection_get_objects(signtext->incoming);
+
+ for (l = incoming; l; l = g_list_next (l)) {
+ if (!gcr_collection_contains(signtext->certificates, l->data)) {
+ g_object_ref(l->data);
+ gcr_simple_collection_add(GCR_SIMPLE_COLLECTION(signtext->certificates), l->data);
+ }
+ }
+
+ current = gcr_collection_get_objects(signtext->certificates);
+
+ for (l = current; l; l = g_list_next (l)) {
+ if (!gcr_collection_contains(signtext->incoming, l->data)) {
+ gcr_simple_collection_remove(GCR_SIMPLE_COLLECTION(signtext->certificates), l->data);
+ g_object_unref(l->data);
+ }
+ }
+
+ g_object_unref(signtext->incoming);
+ signtext->incoming = gcr_simple_collection_new();
+
+ g_timeout_add_seconds(2, crypto_slots_do, signtext_token->signtext);
+ }
+
+ signtext_token_free(signtext_token);
+}
+
+static void
+crypto_slot_do (gpointer user_data)
+{
+ SignTextToken *signtext_token = user_data;
+
+ /*
+ * The minumum you must request to get a certificate back that will display in a dropdown
+ * is CKA_VALUE, CKA_CLASS, CKA_CERTIFICATE_TYPE. Any less than that and you get nothing.
+ *
+ * CKA_CERTIFICATE_CATEGORY tells us if the certificate is a user certificate, or an
+ * intermediate/root.
+ */
+ static const gulong CERTIFICATE_ATTRS[] = {CKA_VALUE, CKA_ID, CKA_LABEL, CKA_CLASS, CKA_CERTIFICATE_TYPE, CKA_CERTIFICATE_CATEGORY, CKA_MODIFIABLE};
+
+ GckEnumerator *cenum;
+
+ GckBuilder builder = GCK_BUILDER_INIT;
+
+ /*
+ * Search for all certificates on a token (ie not in a session).
+ */
+ gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE);
+ gck_builder_add_ulong(&builder, CKA_CLASS, CKO_CERTIFICATE);
+
+ signtext_token->token_info = gck_slot_get_token_info (signtext_token->slot);
+
+ cenum = gck_slot_enumerate_objects(signtext_token->slot, gck_builder_end (&builder), GCK_SESSION_READ_ONLY);
+
+ 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_token->signtext->cancellable, crypto_slot_done, signtext_token);
}
@@ -127,7 +194,7 @@
)
{
SignTextData *signtext = user_data;
- GList *slots;
+ GList *slots, *l;
guint slots_len = 0;
@@ -137,46 +204,46 @@
if (slots_len != signtext->slots_len) {
+ SignTextToken *signtext_token = NULL, *st;
+
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
- * is CKA_VALUE, CKA_CLASS, CKA_CERTIFICATE_TYPE. Any less than that and you get nothing.
- *
- * CKA_CERTIFICATE_CATEGORY tells us if the certificate is a user certificate, or an
- * intermediate/root.
- */
- static const gulong CERTIFICATE_ATTRS[] = {CKA_VALUE, CKA_ID, CKA_LABEL, CKA_CLASS, CKA_CERTIFICATE_TYPE, CKA_CERTIFICATE_CATEGORY, CKA_MODIFIABLE};
-
- GckEnumerator *cenum;
-
- GckBuilder builder = GCK_BUILDER_INIT;
-
- /*
- * Search for all certificates on a token (ie not in a session).
- */
- gck_builder_add_boolean (&builder, CKA_TOKEN, TRUE);
- gck_builder_add_ulong(&builder, CKA_CLASS, CKO_CERTIFICATE);
-
- cenum = gck_modules_enumerate_objects(signtext->modules, gck_builder_end (&builder), GCK_SESSION_READ_ONLY);
-
- 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_slots_done, signtext);
+ for (l = slots; l; l = g_list_next (l)) {
+
+ GckSlot *slot = GCK_SLOT(l->data);
+
+ st = signtext_token_new();
+
+ st->signtext = signtext;
+ st->slot = slot;
+ //st->token_info = gck_slot_get_token_info (slot);
+ //st->certificates = gcr_simple_collection_new();
+ st->next = signtext_token;
+
+ signtext_token = st;
+
+ }
+
+ g_idle_add((GSourceFunc)crypto_slot_do, signtext_token);
signtext->slots_len = slots_len;
- }
-
- gck_list_unref_free(slots);
-
- return TRUE;
+ return FALSE;
+ }
+
+ else {
+ gck_list_unref_free(slots);
+ }
+
+ g_timeout_add_seconds(2, crypto_slots_do, signtext);
+
+ return FALSE;
}
static void
crypto_slots_start(SignTextData *signtext)
{
- g_timeout_add_seconds(2, crypto_slots_do, signtext);
+ crypto_slots_do(signtext);
}
static void
@@ -232,4 +299,78 @@
gck_modules_initialize_registered_async(signtext->cancellable, (GAsyncReadyCallback)crypto_init_done, signtext);
}
-
+void crypto_selector_changed(GcrComboSelector *selector,
+ gpointer user_data)
+{
+ GObject *selected;
+ SignTextInstance *instance = user_data;
+
+ g_printerr("crypto_selector_changed\n");
+
+ selected = gcr_combo_selector_get_selected(selector);
+
+ if (selected && GCR_IS_PKCS11_CERTIFICATE(selected)) {
+
+ GcrPkcs11Certificate *certificate = GCR_PKCS11_CERTIFICATE(selected);
+
+ GckTokenInfo *token_info = g_object_get_data(G_OBJECT (certificate), "token-info");
+
+ if (token_info) {
+ g_printerr("crypto_selector_changed: token\n");
+
+ gtk_entry_set_max_length(instance->pin, token_info->max_pin_len);
+
+ if (token_info->flags & CKF_PROTECTED_AUTHENTICATION_PATH) {
+ gtk_entry_set_icon_from_icon_name(instance->pin, GTK_ENTRY_ICON_PRIMARY, "accessories-calculator-symbolic");
+ gtk_widget_set_sensitive(GTK_WIDGET(instance->pin), FALSE);
+ gtk_entry_set_placeholder_text(GTK_ENTRY(instance->pin), "Use pinpad to enter PIN");
+ gtk_entry_set_text(GTK_ENTRY(instance->pin), "");
+ }
+ else {
+ gtk_entry_set_icon_from_icon_name(instance->pin, GTK_ENTRY_ICON_PRIMARY, "dialog-password-symbolic");
+ gtk_widget_set_sensitive(GTK_WIDGET(instance->pin), TRUE);
+ gtk_entry_set_placeholder_text(GTK_ENTRY(instance->pin), "Enter your PIN");
+ gtk_entry_set_text(GTK_ENTRY(instance->pin), "");
+ }
+
+ if (!(token_info->flags & CKF_USER_PIN_INITIALIZED)) {
+ gtk_entry_set_icon_from_icon_name(instance->pin, GTK_ENTRY_ICON_PRIMARY, "dialog-error-symbolic");
+ gtk_widget_set_sensitive(GTK_WIDGET(instance->pin), FALSE);
+ gtk_entry_set_placeholder_text(GTK_ENTRY(instance->pin), "PIN is not initialised");
+ }
+ else if (token_info->flags & CKF_USER_PIN_LOCKED) {
+ gtk_entry_set_icon_from_icon_name(instance->pin, GTK_ENTRY_ICON_PRIMARY, "dialog-error-symbolic");
+ gtk_widget_set_sensitive(GTK_WIDGET(instance->pin), FALSE);
+ gtk_entry_set_placeholder_text(GTK_ENTRY(instance->pin), "PIN is locked");
+ }
+ else if (token_info->flags & CKF_USER_PIN_TO_BE_CHANGED) {
+ gtk_entry_set_icon_from_icon_name(instance->pin, GTK_ENTRY_ICON_PRIMARY, "dialog-unavailable-symbolic");
+ gtk_widget_set_sensitive(GTK_WIDGET(instance->pin), FALSE);
+ gtk_entry_set_placeholder_text(GTK_ENTRY(instance->pin), "PIN must be changed before use");
+ }
+ else if (token_info->flags & CKF_USER_PIN_FINAL_TRY) {
+ gtk_entry_set_icon_from_icon_name(instance->pin, GTK_ENTRY_ICON_PRIMARY, "dialog-warning-symbolic");
+ gtk_widget_set_sensitive(GTK_WIDGET(instance->pin), TRUE);
+ gtk_entry_set_placeholder_text(GTK_ENTRY(instance->pin), "Final try on PIN");
+ }
+ else if (token_info->flags & CKF_USER_PIN_COUNT_LOW) {
+ gtk_entry_set_icon_from_icon_name(instance->pin, GTK_ENTRY_ICON_PRIMARY, "dialog-warning-symbolic");
+ gtk_widget_set_sensitive(GTK_WIDGET(instance->pin), TRUE);
+ gtk_entry_set_placeholder_text(GTK_ENTRY(instance->pin), "PIN retries are low");
+ }
+
+ }
+ }
+
+}
+
+void
+crypto_instance_start(SignTextInstance *instance, GcrCollection *certificates)
+{
+
+ instance->selector = gcr_combo_selector_new(certificates);
+
+ g_signal_connect(instance->selector, "changed", (GCallback)crypto_selector_changed, instance);
+
+}
+
Modified: redwax-signtext/trunk/src/linux/crypto.h
==============================================================================
--- redwax-signtext/trunk/src/linux/crypto.h (original)
+++ redwax-signtext/trunk/src/linux/crypto.h Mon Sep 5 12:50:20 2022
@@ -28,6 +28,8 @@
GcrCollection *
crypto_filter(GcrCollection *certificates);
+void
+crypto_instance_start(SignTextInstance *instance, 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 Mon Sep 5 12:50:20 2022
@@ -39,8 +39,6 @@
g_printerr ("activate\n");
signtext->cancellable = g_cancellable_new();
-
- signtext->certificates = gcr_simple_collection_new();
signtext->stack = GTK_STACK(gtk_stack_new ());
gtk_widget_show (GTK_WIDGET(signtext->stack));
Modified: redwax-signtext/trunk/src/linux/message.c
==============================================================================
--- redwax-signtext/trunk/src/linux/message.c (original)
+++ redwax-signtext/trunk/src/linux/message.c Mon Sep 5 12:50:20 2022
@@ -151,15 +151,17 @@
else if (json_node_get_node_type(request) == JSON_NODE_OBJECT) {
GcrCollection *certificates = crypto_filter(signtext->certificates);
+
+ crypto_instance_start(instance, certificates);
- instance->selector = gcr_combo_selector_new(certificates);
-
#ifdef HAVE_GTK_BOX_APPEND
gtk_box_append (instance->box, GTK_WIDGET(instance->textview));
gtk_box_append (instance->box, GTK_WIDGET(instance->selector));
+ gtk_box_append (instance->box, GTK_WIDGET(instance->pin));
#else
gtk_box_pack_start (instance->box, GTK_WIDGET(instance->textview), TRUE, TRUE, 0);
gtk_box_pack_start (instance->box, GTK_WIDGET(instance->selector), FALSE, FALSE, 0);
+ gtk_box_pack_start (instance->box, GTK_WIDGET(instance->pin), FALSE, FALSE, 0);
#endif
gtk_stack_add_titled(signtext->stack, GTK_WIDGET (instance->box), instance->uuid, g_uri_get_host(instance->uri));
Modified: redwax-signtext/trunk/src/linux/signtext.c
==============================================================================
--- redwax-signtext/trunk/src/linux/signtext.c (original)
+++ redwax-signtext/trunk/src/linux/signtext.c Mon Sep 5 12:50:20 2022
@@ -33,16 +33,36 @@
memset(signtext, 0, sizeof(SignTextData));
+ signtext->incoming = gcr_simple_collection_new();
+ signtext->certificates = gcr_simple_collection_new();
+
return signtext;
}
void signtext_data_free(SignTextData *data)
{
if (data) {
+ if (data->incoming) g_object_unref(data->incoming);
if (data->certificates) g_object_unref(data->certificates);
if (data->modules) gck_list_unref_free(data->modules);
+ if (data->slots) gck_list_unref_free(data->slots);
}
g_free(data);
+}
+
+SignTextToken *signtext_token_new()
+{
+ SignTextToken *token = g_new (SignTextToken, 1);
+
+ memset(token, 0, sizeof(SignTextToken));
+
+ return token;
+}
+
+void signtext_token_free(SignTextToken *signtext_token)
+{
+ if (signtext_token->token_info) gck_token_info_free(signtext_token->token_info);
+ g_free(signtext_token);
}
SignTextInstance *signtext_instance_new(gint64 id, const gchar *uuid, GUri *uri)
@@ -63,6 +83,10 @@
gtk_text_view_set_cursor_visible(instance->textview, FALSE);
gtk_text_view_set_wrap_mode(instance->textview, GTK_WRAP_WORD_CHAR);
+ instance->pin_buffer = gcr_secure_entry_buffer_new();
+ instance->pin = GTK_ENTRY(gtk_entry_new_with_buffer(instance->pin_buffer));
+ gtk_entry_set_visibility(GTK_ENTRY(instance->pin), FALSE);
+ gtk_entry_set_icon_from_icon_name(instance->pin, GTK_ENTRY_ICON_PRIMARY, "dialog-password-symbolic");
return instance;
}
@@ -73,6 +97,7 @@
if (instance->uri) g_uri_unref(instance->uri);
if (instance->textview) g_object_unref(instance->textview);
if (instance->buffer) g_object_unref(instance->buffer);
+ if (instance->pin) g_object_unref(instance->pin);
}
g_free(instance);
}
Modified: redwax-signtext/trunk/src/linux/signtext.h
==============================================================================
--- redwax-signtext/trunk/src/linux/signtext.h (original)
+++ redwax-signtext/trunk/src/linux/signtext.h Mon Sep 5 12:50:20 2022
@@ -51,9 +51,20 @@
GtkStackSwitcher *switcher;
GtkStack *stack;
GList *modules;
+ GList *slots;
+ GcrCollection *incoming;
GcrCollection *certificates;
guint slots_len;
} SignTextData;
+
+typedef struct SignTextToken SignTextToken;
+
+struct SignTextToken {
+ SignTextData *signtext;
+ GckSlot *slot;
+ GckTokenInfo *token_info;
+ SignTextToken *next;
+};
typedef struct SignTextInstance {
GUri *uri;
@@ -64,10 +75,15 @@
GtkTextBuffer *buffer;
GtkTextView *textview;
GcrComboSelector *selector;
+ GtkEntryBuffer *pin_buffer;
+ GtkEntry *pin;
} SignTextInstance;
SignTextData *signtext_data_new();
void signtext_data_free(SignTextData *data);
+
+SignTextToken *signtext_token_new();
+void signtext_token_free(SignTextToken *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