[git] GPA - branch, master, updated. gpa-0.9.4-36-g80dd3c0

by Werner Koch cvs at cvs.gnupg.org
Wed May 14 18:10:21 CEST 2014


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The GNU Privacy Assistant".

The branch, master has been updated
       via  80dd3c0d4c3b11e2e84dcb55644643f22cbdd8d3 (commit)
       via  f22a7f18e9e02d7a819fdd1b8504bb161472c4ce (commit)
       via  da2dab9ef07bfb9706a853c54d9f6f9094b1bdc2 (commit)
       via  65a3491a4e9ac4a79de473ba28a5314a13dcfe99 (commit)
       via  b079da56b43cc0191699d0f83778ca3ea1dc8742 (commit)
       via  7a08aa710b4df95f38bfbbd3509f40f92175397d (commit)
       via  a7da4281e8c515411d66ebd93a280a408bc517a2 (commit)
       via  cfa5b413f38ce21865731b0cf31d552cbdbf5313 (commit)
       via  107c1465ebd6447ac4ec04a5fd3ca582cf9e5686 (commit)
       via  af81899cf7b7c61ef4fd40b0b2edca3a3f438c74 (commit)
      from  cff74792b61c71a19ca51eb954e3540f2433e9bb (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 80dd3c0d4c3b11e2e84dcb55644643f22cbdd8d3
Author: Werner Koch <wk at gnupg.org>
Date:   Wed May 14 18:11:00 2014 +0200

    Let OpenPGP specific commands only use OpenPGP keys.
    
    * src/gpakeysignop.c (gpa_key_sign_operation_start): Skip non OpenPGP
    keys.
    * src/keylist.c (gpa_keylist_get_selected_keys): Add arg optional arg
    PROTOCOL.  Adjust all callers.
    * src/keymanager.c (key_manager_can_sign): Cehck for OpenPGP.
    (key_manager_sign, key_manager_trust, key_manager_send): Act only on
    OpenPGP keys.

diff --git a/src/gpakeysignop.c b/src/gpakeysignop.c
index 95db5be..ede4be8 100644
--- a/src/gpakeysignop.c
+++ b/src/gpakeysignop.c
@@ -38,10 +38,10 @@
 
 /* Internal functions */
 static gboolean gpa_key_sign_operation_idle_cb (gpointer data);
-static void gpa_key_sign_operation_done_error_cb (GpaContext *context, 
+static void gpa_key_sign_operation_done_error_cb (GpaContext *context,
 						    gpg_error_t err,
 						    GpaKeySignOperation *op);
-static void gpa_key_sign_operation_done_cb (GpaContext *context, 
+static void gpa_key_sign_operation_done_cb (GpaContext *context,
 					      gpg_error_t err,
 					      GpaKeySignOperation *op);
 
@@ -98,7 +98,7 @@ static void
 gpa_key_sign_operation_class_init (GpaKeySignOperationClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
-  
+
   parent_class = g_type_class_peek_parent (klass);
 
   object_class->constructor = gpa_key_sign_operation_constructor;
@@ -109,7 +109,7 @@ GType
 gpa_key_sign_operation_get_type (void)
 {
   static GType key_sign_operation_type = 0;
-  
+
   if (!key_sign_operation_type)
     {
       static const GTypeInfo key_sign_operation_info =
@@ -124,12 +124,12 @@ gpa_key_sign_operation_get_type (void)
         0,              /* n_preallocs */
         (GInstanceInitFunc) gpa_key_sign_operation_init,
       };
-      
-      key_sign_operation_type = g_type_register_static 
+
+      key_sign_operation_type = g_type_register_static
 	(GPA_KEY_OPERATION_TYPE, "GpaKeySignOperation",
 	 &key_sign_operation_info, 0);
     }
-  
+
   return key_sign_operation_type;
 }
 
@@ -141,7 +141,7 @@ GpaKeySignOperation*
 gpa_key_sign_operation_new (GtkWidget *window, GList *keys)
 {
   GpaKeySignOperation *op;
-  
+
   op = g_object_new (GPA_KEY_SIGN_OPERATION_TYPE,
 		     "window", window,
 		     "keys", keys,
@@ -154,13 +154,15 @@ gpa_key_sign_operation_new (GtkWidget *window, GList *keys)
 
 static gpg_error_t
 gpa_key_sign_operation_start (GpaKeySignOperation *op)
-{ 
+{
   gpg_error_t err;
   gpgme_key_t key;
   gboolean sign_locally = FALSE;
 
   key = gpa_key_operation_current_key (GPA_KEY_OPERATION (op));
   g_return_val_if_fail (key, gpg_error (GPG_ERR_CANCELED));
+  if (key->protocol != GPGME_PROTOCOL_OpenPGP)
+    return 0;
 
   if (! gpa_key_sign_run_dialog (GPA_OPERATION (op)->window,
 				 key, &sign_locally))
@@ -222,9 +224,10 @@ gpa_key_sign_operation_next (GpaKeySignOperation *op)
 }
 
 
-static void gpa_key_sign_operation_done_error_cb (GpaContext *context, 
-						  gpg_error_t err,
-						  GpaKeySignOperation *op)
+static void
+gpa_key_sign_operation_done_error_cb (GpaContext *context,
+                                      gpg_error_t err,
+                                      GpaKeySignOperation *op)
 {
   switch (gpg_err_code (err))
     {
@@ -256,9 +259,10 @@ static void gpa_key_sign_operation_done_error_cb (GpaContext *context,
     }
 }
 
-static void gpa_key_sign_operation_done_cb (GpaContext *context, 
-					    gpg_error_t err,
-					    GpaKeySignOperation *op)
+static void
+gpa_key_sign_operation_done_cb (GpaContext *context,
+                                gpg_error_t err,
+                                GpaKeySignOperation *op)
 {
   GPA_KEY_OPERATION (op)->current = g_list_next
     (GPA_KEY_OPERATION (op)->current);
diff --git a/src/keylist.c b/src/keylist.c
index 2932d41..7a89d92 100644
--- a/src/keylist.c
+++ b/src/keylist.c
@@ -819,9 +819,11 @@ gpa_keylist_has_single_secret_selection (GpaKeyList *keylist)
 
 
 /* Return a GList of selected keys. The caller must not dereference
-   the keys as they belong to the caller.  */
+   the keys as they belong to the caller.  Unless PROTOCOL is
+   GPGME_PROTOCOL_UNKNOWN, only keys matching thhe requested protocol
+   are returned.  */
 GList *
-gpa_keylist_get_selected_keys (GpaKeyList * keylist)
+gpa_keylist_get_selected_keys (GpaKeyList * keylist, gpgme_protocol_t protocol)
 {
   GtkTreeSelection *selection =
     gtk_tree_view_get_selection (GTK_TREE_VIEW (keylist));
@@ -843,7 +845,10 @@ gpa_keylist_get_selected_keys (GpaKeyList * keylist)
       key = g_value_get_pointer (&value);
       g_value_unset(&value);
 
-      keys = g_list_append (keys, key);
+      /* Fixme: Why don't we ref KEY? */
+      if (key && (protocol == GPGME_PROTOCOL_UNKNOWN
+                  || protocol == key->protocol))
+        keys = g_list_append (keys, key);
     }
 
   g_list_foreach (list, (GFunc) gtk_tree_path_free, NULL);
diff --git a/src/keylist.h b/src/keylist.h
index 9e97572..c4382d0 100644
--- a/src/keylist.h
+++ b/src/keylist.h
@@ -72,10 +72,10 @@ GType gpa_keylist_get_type (void) G_GNUC_CONST;
 
 
 /* Usage flags.  */
-#define KEY_USAGE_SIGN 1   /* Good for signatures. */            
-#define KEY_USAGE_ENCR 2   /* Good for encryption. */            
+#define KEY_USAGE_SIGN 1   /* Good for signatures. */
+#define KEY_USAGE_ENCR 2   /* Good for encryption. */
 #define KEY_USAGE_CERT 4   /* Good to certify other keys. */
-#define KEY_USAGE_AUTH 8   /* Good for authentication. */        
+#define KEY_USAGE_AUTH 8   /* Good for authentication. */
 
 
 /* Create a new key list widget.  */
@@ -107,7 +107,8 @@ gboolean gpa_keylist_has_single_secret_selection (GpaKeyList * keylist);
 
 /* Return a GList of selected keys. The caller must not dereference
    the keys as they belong to the caller.  */
-GList *gpa_keylist_get_selected_keys (GpaKeyList * keylist);
+GList *gpa_keylist_get_selected_keys (GpaKeyList *keylist,
+                                      gpgme_protocol_t protocol);
 
 /* Return the selected key.  This function returns NULL if no or more
    than one key has been selected.  */
diff --git a/src/keymanager.c b/src/keymanager.c
index 2c73777..7b9fe97 100644
--- a/src/keymanager.c
+++ b/src/keymanager.c
@@ -373,7 +373,8 @@ register_operation (GpaKeyManager *self, GpaOperation *op)
 static void
 key_manager_delete (GtkAction *action, GpaKeyManager *self)
 {
-  GList *selection = gpa_keylist_get_selected_keys (self->keylist);
+  GList *selection = gpa_keylist_get_selected_keys (self->keylist,
+                                                    GPGME_PROTOCOL_UNKNOWN);
   GpaKeyDeleteOperation *op = gpa_key_delete_operation_new (GTK_WIDGET (self),
 							    selection);
   register_key_operation (self, GPA_KEY_OPERATION (op));
@@ -423,7 +424,8 @@ key_manager_can_sign (gpointer param)
 	 the selected key was already signed with the default key.  */
       GpaKeyManager *self = param;
       gpgme_key_t key = key_manager_current_key (self);
-      result = ! key_has_been_signed (key, default_key);
+      if (key->protocol == GPGME_PROTOCOL_OpenPGP)
+        result = ! key_has_been_signed (key, default_key);
     }
   else if (default_key && key_manager_has_selection (param))
     /* Always allow signing many keys at once.  */
@@ -448,9 +450,13 @@ key_manager_sign (GtkAction *action, gpointer param)
       return;
     }
 
-  selection = gpa_keylist_get_selected_keys (self->keylist);
-  op = gpa_key_sign_operation_new (GTK_WIDGET (self), selection);
-  register_key_operation (self, GPA_KEY_OPERATION (op));
+  selection = gpa_keylist_get_selected_keys (self->keylist,
+                                             GPGME_PROTOCOL_OpenPGP);
+  if (selection)
+    {
+      op = gpa_key_sign_operation_new (GTK_WIDGET (self), selection);
+      register_key_operation (self, GPA_KEY_OPERATION (op));
+    }
 }
 
 /* Invoke the "edit key" dialog.  */
@@ -488,9 +494,13 @@ key_manager_trust (GtkAction *action, gpointer param)
   if (! key_manager_has_single_selection (self))
     return;
 
-  selection = gpa_keylist_get_selected_keys (self->keylist);
-  op = gpa_key_trust_operation_new (GTK_WIDGET (self), selection);
-  register_key_operation (self, GPA_KEY_OPERATION (op));
+  selection = gpa_keylist_get_selected_keys (self->keylist,
+                                             GPGME_PROTOCOL_OpenPGP);
+  if (selection)
+    {
+      op = gpa_key_trust_operation_new (GTK_WIDGET (self), selection);
+      register_key_operation (self, GPA_KEY_OPERATION (op));
+    }
 }
 
 
@@ -514,7 +524,8 @@ key_manager_export (GtkAction *action, gpointer param)
   GList *selection;
   GpaExportFileOperation *op;
 
-  selection = gpa_keylist_get_selected_keys (self->keylist);
+  selection = gpa_keylist_get_selected_keys (self->keylist,
+                                             GPGME_PROTOCOL_UNKNOWN);
   if (! selection)
     return;
 
@@ -551,9 +562,13 @@ key_manager_send (GtkAction *action, gpointer param)
   if (! key_manager_has_single_selection (self))
     return;
 
-  selection = gpa_keylist_get_selected_keys (self->keylist);
-  op = gpa_export_server_operation_new (GTK_WIDGET (self), selection);
-  register_operation (self, GPA_OPERATION (op));
+  selection = gpa_keylist_get_selected_keys (self->keylist,
+                                             GPGME_PROTOCOL_OPENPGP);
+  if (selection)
+    {
+      op = gpa_export_server_operation_new (GTK_WIDGET (self), selection);
+      register_operation (self, GPA_OPERATION (op));
+    }
 }
 #endif /*ENABLE_KEYSERVER_SUPPORT*/
 
@@ -643,6 +658,7 @@ key_manager_selection_changed (GtkTreeSelection *treeselection,
 				  gpointer param)
 {
   GpaKeyManager *self = param;
+  GList *selection;
 
   /* Some other piece of the keyring wants us to ignore this signal.  */
   if (self->freeze_selection)
@@ -661,14 +677,14 @@ key_manager_selection_changed (GtkTreeSelection *treeselection,
     gpgme_op_keylist_end (self->ctx->ctx);
 
   /* Load the new one.  */
-  if (gpa_keylist_has_single_selection (self->keylist))
+  if (gpa_keylist_has_single_selection (self->keylist)
+      && (selection = gpa_keylist_get_selected_keys (self->keylist,
+                                                     GPGME_PROTOCOL_UNKNOWN)))
     {
       gpg_error_t err;
-      GList *selection;
       gpgme_key_t key;
       int old_mode;
 
-      selection = gpa_keylist_get_selected_keys (self->keylist);
       key = (gpgme_key_t) selection->data;
       old_mode = gpgme_get_keylist_mode (self->ctx->ctx);
 
@@ -822,7 +838,8 @@ key_manager_copy (GtkAction *action, gpointer param)
   GList *selection;
   GpaExportClipboardOperation *op;
 
-  selection = gpa_keylist_get_selected_keys (self->keylist);
+  selection = gpa_keylist_get_selected_keys (self->keylist,
+                                             GPGME_PROTOCOL_UNKNOWN);
   if (! selection)
     return;
 
@@ -1141,10 +1158,14 @@ idle_update_details (gpointer param)
     }
   else
     {
-      GList *selection = gpa_keylist_get_selected_keys (self->keylist);
-      gpa_key_details_update (self->details, NULL,
-                              g_list_length (selection));
-      g_list_free (selection);
+      GList *selection = gpa_keylist_get_selected_keys (self->keylist,
+                                                        GPGME_PROTOCOL_UNKNOWN);
+      if (selection)
+        {
+          gpa_key_details_update (self->details, NULL,
+                                  g_list_length (selection));
+          g_list_free (selection);
+        }
     }
 
   /* Set the idle id to NULL to indicate that the idle handler has

commit f22a7f18e9e02d7a819fdd1b8504bb161472c4ce
Author: Werner Koch <wk at gnupg.org>
Date:   Wed May 14 15:40:32 2014 +0200

    w32: Fix directory separator in backup dialog.
    
    * src/gpabackupop.c (gpa_backup_operation_dialog_run): Use correct
    directory separator.

diff --git a/src/gpabackupop.c b/src/gpabackupop.c
index 4f5ddc7..46aeba3 100644
--- a/src/gpabackupop.c
+++ b/src/gpabackupop.c
@@ -275,8 +275,10 @@ gpa_backup_operation_dialog_run (GtkWidget *parent, const gchar *key_id,
 
   /* Set the default file name.  I am not sure whether ".p12" or
      ".pem" is better for an _armored_ pkcs#12. */
-  default_comp = g_strdup_printf ("%s/secret-key-%s.%s",
-                                  gnupg_homedir, key_id,
+  default_comp = g_strdup_printf ("%s%csecret-key-%s.%s",
+                                  gnupg_homedir,
+                                  G_DIR_SEPARATOR,
+                                  key_id,
                                   is_x509? "p12":"asc");
   gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), default_comp);
   g_free (default_comp);

commit da2dab9ef07bfb9706a853c54d9f6f9094b1bdc2
Author: Werner Koch <wk at gnupg.org>
Date:   Wed May 14 14:52:32 2014 +0200

    Add command line option --stop-server.
    
    * src/gpa.c (main): Implement option.
    * src/server.c (cmd_kill_uiserver): New.
    (register_commands): Register new command.

diff --git a/src/gpa.c b/src/gpa.c
index 4e67bb2..1ff0c5e 100644
--- a/src/gpa.c
+++ b/src/gpa.c
@@ -69,6 +69,7 @@ typedef struct
   gboolean start_clipboard;
   gboolean start_settings;
   gboolean start_only_server;
+  gboolean stop_running_server;
   gboolean disable_x509;
   gboolean no_remote;
   gboolean enable_logging;
@@ -121,6 +122,8 @@ static GOptionEntry option_entries[] =
       N_("Read options from file"), "FILE" },
     { "no-remote", 0, 0, G_OPTION_ARG_NONE, &args.no_remote,
       N_("Do not connect to a running instance"), NULL },
+    { "stop-server", 0, G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE,
+      &args.stop_running_server, NULL, NULL },
     /* Note:  the cms option will eventually be removed.  */
     { "cms", 'x', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE,
       &cms_hack, NULL, NULL },
@@ -545,8 +548,18 @@ main (int argc, char *argv[])
   gpa_options_set_file (gpa_options_get_instance (), configname);
   g_free (configname);
 
+  if (args.stop_running_server)
+    {
+      /* If a UI server with the same name is already running, stop
+         it.  If not, do nothing.  */
+      if (gpa_check_server () == 2)
+        gpa_send_to_server ("KILL_UISERVER");
+      return 0;
+    }
+
+
   /* Check whether we need to start a server or to simply open a
-     windowin an existing server.  */
+     window in an already running server.  */
   switch (gpa_check_server ())
     {
     case 0: /* No running server on the expected socket.  Start one.  */
diff --git a/src/server.c b/src/server.c
index 78bb4b9..023eaf8 100644
--- a/src/server.c
+++ b/src/server.c
@@ -1583,6 +1583,18 @@ cmd_checksum_verify_files (assuan_context_t ctx, char *line)
   return assuan_process_done (ctx, err);
 }
 
+
+

+/* KILL_UISERVER  */
+static gpg_error_t
+cmd_kill_uiserver (assuan_context_t ctx, char *line)
+{
+  (void)line;
+  shutdown_pending = TRUE;
+  return assuan_process_done (ctx, 0);
+}
+
+
 

 static gpg_error_t
 reset_notify (assuan_context_t ctx, char *line)
@@ -1668,6 +1680,7 @@ register_commands (assuan_context_t ctx)
     { "IMPORT_FILES", cmd_import_files },
     { "CHECKSUM_CREATE_FILES", cmd_checksum_create_files },
     { "CHECKSUM_VERIFY_FILES", cmd_checksum_verify_files },
+    { "KILL_UISERVER", cmd_kill_uiserver },
     { NULL }
   };
   int i, rc;

commit 65a3491a4e9ac4a79de473ba28a5314a13dcfe99
Author: Werner Koch <wk at gnupg.org>
Date:   Tue May 13 16:13:34 2014 +0200

    Fix regression in edit dialogs due to new status lines.
    
    * src/gpgmeedit.c (edit_fnc): Ignore pinentry launched status.

diff --git a/src/gpgmeedit.c b/src/gpgmeedit.c
index 36e8824..7ff9a05 100644
--- a/src/gpgmeedit.c
+++ b/src/gpgmeedit.c
@@ -214,6 +214,7 @@ edit_fnc (void *opaque, gpgme_status_code_t status,
       || status == GPGME_STATUS_BACKUP_KEY_CREATED
       || status == GPGME_STATUS_CARDCTRL       /* Issued by gpg1.  */
       || status == GPGME_STATUS_SC_OP_SUCCESS
+      || status == GPGME_STATUS_PINENTRY_LAUNCHED
       || status == GPGME_STATUS_PROGRESS)
     {
       return parms->err;

commit b079da56b43cc0191699d0f83778ca3ea1dc8742
Author: Werner Koch <wk at gnupg.org>
Date:   Tue May 13 14:36:54 2014 +0200

    Implement backup of X.509 keys.
    
    * src/gpgmetools.c (gpa_backup_key): Add arg is_x509 and support X.509
    backups.
    * src/gpabackupop.c (PROP_PROTOCOL): New.
    (gpa_backup_operation_get_property): Add it.
    (gpa_backup_operation_set_property): Add it.
    (gpa_backup_operation_class_init): Install new property
    (gpa_backup_operation_finalize): Remove surplus NULL check.
    (gpa_backup_operation_do_backup): Pass x509 flag to gpa_backup_key.
    (gpa_backup_operation_dialog_run): Add arg is_x509.  Move extra label
    generation out of the static dialog generation.  Use ".p12" for X.509
    keys.
    (gpa_backup_operation_idle_cb): Pass x509 flag to the dialog run call.
    (gpa_backup_operation_new): Create protocol property from KEY.
    (gpa_backup_operation_new_from_fpr): Add arg protocol.
    * src/gpabackupop.h (_GpaBackupOperation): Add field protocol.
    * src/gpagenkeysimpleop.c (gpa_gen_key_simple_operation_done_cb): Pass
    PROTOCOL to gpa_backup_operation_new_from_fpr.
    * src/keymanager.c (key_manager_mapped): Assure that
    gpa_backup_oepration_new is never called with a NULL key.

diff --git a/src/gpabackupop.c b/src/gpabackupop.c
index 8a48c03..4f5ddc7 100644
--- a/src/gpabackupop.c
+++ b/src/gpabackupop.c
@@ -38,6 +38,7 @@ enum
   PROP_0,
   PROP_KEY,
   PROP_FINGERPRINT,
+  PROP_PROTOCOL
 };
 
 static void
@@ -56,6 +57,10 @@ gpa_backup_operation_get_property (GObject     *object,
     case PROP_FINGERPRINT:
       g_value_set_string (value, op->fpr);
       break;
+    case PROP_PROTOCOL:
+      g_value_set_int (value, op->protocol);
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -93,6 +98,9 @@ gpa_backup_operation_set_property (GObject     *object,
 	  op->key_id = g_strdup (fpr + strlen (fpr) - 8);
 	}
       break;
+    case PROP_PROTOCOL:
+      op->protocol = g_value_get_int (value);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -104,10 +112,7 @@ gpa_backup_operation_finalize (GObject *object)
 {
   GpaBackupOperation *op = GPA_BACKUP_OPERATION (object);
 
-  if (op->key)
-    {
-      gpgme_key_unref (op->key);
-    }
+  gpgme_key_unref (op->key);
   g_free (op->fpr);
   g_free (op->key_id);
 
@@ -120,6 +125,7 @@ gpa_backup_operation_init (GpaBackupOperation *op)
   op->key = NULL;
   op->fpr = NULL;
   op->key_id = NULL;
+  op->protocol = GPGME_PROTOCOL_UNKNOWN;
 }
 
 static GObject*
@@ -167,6 +173,13 @@ gpa_backup_operation_class_init (GpaBackupOperationClass *klass)
 				   ("fpr", "fpr",
 				    "Fingerprint",
 				    G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
+  g_object_class_install_property
+    (object_class, PROP_PROTOCOL,
+     g_param_spec_int
+     ("protocol", "Protocol",
+      "The gpgme protocol used for FPR.",
+      GPGME_PROTOCOL_OpenPGP, GPGME_PROTOCOL_UNKNOWN, GPGME_PROTOCOL_UNKNOWN,
+      G_PARAM_WRITABLE|G_PARAM_CONSTRUCT_ONLY));
 }
 
 GType
@@ -202,7 +215,7 @@ gpa_backup_operation_get_type (void)
 static void
 gpa_backup_operation_do_backup (GpaBackupOperation *op, gchar *filename)
 {
-  if (gpa_backup_key (op->fpr, filename))
+  if (gpa_backup_key (op->fpr, filename, (op->protocol == GPGME_PROTOCOL_CMS)))
     {
       gchar *message;
       message = g_strdup_printf (_("A copy of your secret key has "
@@ -229,17 +242,18 @@ gpa_backup_operation_do_backup (GpaBackupOperation *op, gchar *filename)
 
 /* Return the filename in filename encoding.  */
 static gchar*
-gpa_backup_operation_dialog_run (GtkWidget *parent, const gchar *key_id)
+gpa_backup_operation_dialog_run (GtkWidget *parent, const gchar *key_id,
+                                 int is_x509)
 {
   static GtkWidget *dialog;
   GtkResponseType response;
   gchar *default_comp;
   gchar *filename = NULL;
+  gchar *id_text;
+  GtkWidget *id_label;
 
   if (! dialog)
     {
-      gchar *id_text;
-      GtkWidget *id_label;
 
       dialog = gtk_file_chooser_dialog_new
 	(_("Backup key to file"), GTK_WINDOW (parent),
@@ -251,16 +265,19 @@ gpa_backup_operation_dialog_run (GtkWidget *parent, const gchar *key_id)
       gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog),
 					   g_get_home_dir ());
 
-      /* Set the label with more explanations.  */
-      id_text = g_strdup_printf (_("Generating backup of key: %s"), key_id);
-      id_label = gtk_label_new (id_text);
-      g_free (id_text);
-      gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), id_label);
     }
 
-  /* Set the default file name.  */
-  default_comp = g_strdup_printf ("%s/secret-key-%s.asc",
-                                  gnupg_homedir, key_id);
+  /* Set the label with more explanations.  */
+  id_text = g_strdup_printf (_("Generating backup of key: 0x%s"), key_id);
+  id_label = gtk_label_new (id_text);
+  g_free (id_text);
+  gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), id_label);
+
+  /* Set the default file name.  I am not sure whether ".p12" or
+     ".pem" is better for an _armored_ pkcs#12. */
+  default_comp = g_strdup_printf ("%s/secret-key-%s.%s",
+                                  gnupg_homedir, key_id,
+                                  is_x509? "p12":"asc");
   gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), default_comp);
   g_free (default_comp);
 
@@ -284,7 +301,8 @@ gpa_backup_operation_idle_cb (gpointer data)
   gchar *file;
 
   file = gpa_backup_operation_dialog_run (GPA_OPERATION (op)->window,
-                                          op->key_id);
+                                          op->key_id,
+                                          !!(op->protocol==GPGME_PROTOCOL_CMS));
   if (file)
     gpa_backup_operation_do_backup (op, file);
 
@@ -304,19 +322,22 @@ gpa_backup_operation_new (GtkWidget *window, gpgme_key_t key)
   op = g_object_new (GPA_BACKUP_OPERATION_TYPE,
 		     "window", window,
 		     "key", key,
+                     "protocol", key->protocol,
 		     NULL);
 
   return op;
 }
 
 GpaBackupOperation*
-gpa_backup_operation_new_from_fpr (GtkWidget *window, const gchar *fpr)
+gpa_backup_operation_new_from_fpr (GtkWidget *window,
+                                   const gchar *fpr, gpgme_protocol_t protocol)
 {
   GpaBackupOperation *op;
 
   op = g_object_new (GPA_BACKUP_OPERATION_TYPE,
 		     "window", window,
 		     "fpr", fpr,
+                     "protocol", protocol,
 		     NULL);
 
   return op;
diff --git a/src/gpabackupop.h b/src/gpabackupop.h
index 979d5b4..5002e89 100644
--- a/src/gpabackupop.h
+++ b/src/gpabackupop.h
@@ -43,6 +43,7 @@ struct _GpaBackupOperation {
 
   gpgme_key_t key;
   gchar *fpr, *key_id;
+  gpgme_protocol_t protocol;
 };
 
 struct _GpaBackupOperationClass {
@@ -51,11 +52,12 @@ struct _GpaBackupOperationClass {
 
 GType gpa_backup_operation_get_type (void) G_GNUC_CONST;
 
-/* API */					   
-GpaBackupOperation* 
+/* API */
+GpaBackupOperation*
 gpa_backup_operation_new (GtkWidget *window, gpgme_key_t key);
 
-GpaBackupOperation* 
-gpa_backup_operation_new_from_fpr (GtkWidget *window, const gchar *fpr);
+GpaBackupOperation*
+gpa_backup_operation_new_from_fpr (GtkWidget *window, const gchar *fpr,
+                                   gpgme_protocol_t protocol);
 
 #endif
diff --git a/src/gpagenkeysimpleop.c b/src/gpagenkeysimpleop.c
index fd6c21a..a298ac7 100644
--- a/src/gpagenkeysimpleop.c
+++ b/src/gpagenkeysimpleop.c
@@ -192,7 +192,8 @@ gpa_gen_key_simple_operation_done_cb (GpaContext *context,
 	{
 	  GpaBackupOperation *backup;
 
-          backup = gpa_backup_operation_new_from_fpr (op->wizard, result->fpr);
+          backup = gpa_backup_operation_new_from_fpr
+            (op->wizard, result->fpr, gpgme_get_protocol (context->ctx));
 
 	  g_signal_connect (backup, "completed", G_CALLBACK
 			    (gpa_gen_key_simple_operation_backup_complete),
diff --git a/src/gpgmetools.c b/src/gpgmetools.c
index 8c16622..621ea23 100644
--- a/src/gpgmetools.c
+++ b/src/gpgmetools.c
@@ -522,10 +522,11 @@ get_gpg_connect_agent_path (void)
 
 
 /* Backup a key. It exports both the public and secret keys to a file.
-   Returns TRUE on success and FALSE on error. It displays errors to
-   the user.  */
+   IS_X509 tells the function that the fingerprint is from an X.509
+   key.  Returns TRUE on success and FALSE on error. It displays
+   errors to the user.  */
 gboolean
-gpa_backup_key (const gchar *fpr, const char *filename)
+gpa_backup_key (const gchar *fpr, const char *filename, int is_x509)
 {
   gchar *header, *pub_key, *sec_key;
   gchar *err;
@@ -544,17 +545,26 @@ gpa_backup_key (const gchar *fpr, const char *filename)
       NULL, "--batch", "--no-tty", "--armor", "--export-secret-key",
       (gchar*) fpr, NULL
     };
+  gchar *seccms_argv[] =
+    {
+      NULL, "--batch", "--no-tty", "--armor", "--export-secret-key-p12",
+      (gchar*) fpr, NULL
+    };
   const gchar *path;
   mode_t mask;
 
   /* Get the gpg path.  */
-  path = get_gpg_path ();
+  if (is_x509)
+    path = get_gpgsm_path ();
+  else
+    path = get_gpg_path ();
   g_return_val_if_fail (path && *path, FALSE);
 
   /* Add the executable to the arg arrays */
   header_argv[0] = (gchar*) path;
   pub_argv[0] = (gchar*) path;
   sec_argv[0] = (gchar*) path;
+  seccms_argv[0] = (gchar*) path;
   /* Open the file */
   mask = umask (0077);
   file = g_fopen (filename, "w");
@@ -568,11 +578,13 @@ gpa_backup_key (const gchar *fpr, const char *filename)
       return FALSE;
     }
   /* Get the keys and write them into the file */
-  fputs (_("************************************************************************\n"
-	   "* WARNING: This file is a backup of your secret key. Please keep it in *\n"
-	   "* a safe place.                                                        *\n"
-	   "************************************************************************\n\n"),
-	 file);
+  fputs (_(
+    "************************************************************************\n"
+    "* WARNING: This file is a backup of your secret key. Please keep it in *\n"
+    "* a safe place.                                                        *\n"
+    "************************************************************************\n"
+    "\n"), file);
+
   fputs (_("The key backed up in this file is:\n\n"), file);
   if( !g_spawn_sync (NULL, header_argv, NULL, 0, NULL, NULL, &header,
 		     &err, &ret_code, NULL))
@@ -584,7 +596,7 @@ gpa_backup_key (const gchar *fpr, const char *filename)
   g_free (header);
   fputs ("\n", file);
   if( !g_spawn_sync (NULL, pub_argv, NULL, 0, NULL, NULL, &pub_key,
-		     &err, &ret_code, NULL))
+                     &err, &ret_code, NULL))
     {
       fclose (file);
       return FALSE;
@@ -593,7 +605,9 @@ gpa_backup_key (const gchar *fpr, const char *filename)
   g_free (err);
   g_free (pub_key);
   fputs ("\n", file);
-  if( !g_spawn_sync (NULL, sec_argv, NULL, 0, NULL, NULL, &sec_key,
+  if( !g_spawn_sync (NULL,
+                     is_x509? seccms_argv : sec_argv,
+                     NULL, 0, NULL, NULL, &sec_key,
 		     &err, &ret_code, NULL))
     {
       fclose (file);
diff --git a/src/gpgmetools.h b/src/gpgmetools.h
index 8f08ae8..c6d4885 100644
--- a/src/gpgmetools.h
+++ b/src/gpgmetools.h
@@ -127,9 +127,10 @@ gpg_error_t gpa_generate_key_start (gpgme_ctx_t ctx,
 				    gpa_keygen_para_t *params);
 
 /* Backup a key.  It exports both the public and secret keys to a
-   file.  Returns TRUE on success and FALSE on error.  It displays
-   errors to the user.  */
-gboolean gpa_backup_key (const gchar *fpr, const char *filename);
+   file.  IS_X509 tells the function that the fingerprint is from an
+   X.509 key.  Returns TRUE on success and FALSE on error.  It
+   displays errors to the user.  */
+gboolean gpa_backup_key (const gchar *fpr, const char *filename, int is_x509);
 
 gpa_keygen_para_t *gpa_keygen_para_new (void);
 
diff --git a/src/keymanager.c b/src/keymanager.c
index b9a5dbc..2c73777 100644
--- a/src/keymanager.c
+++ b/src/keymanager.c
@@ -764,10 +764,15 @@ key_manager_mapped (gpointer param)
 	  gtk_widget_destroy (dialog);
           if (response == GTK_RESPONSE_OK)
 	    {
-	      GpaBackupOperation *op = gpa_backup_operation_new
-		(GTK_WIDGET (self), gpa_options_get_default_key
-		 (gpa_options_get_instance ()));
-	      register_operation (self, GPA_OPERATION (op));
+              gpgme_key_t key;
+	      GpaBackupOperation *op;
+
+              key = gpa_options_get_default_key (gpa_options_get_instance ());
+              if (key)
+                {
+                  op = gpa_backup_operation_new (GTK_WIDGET (self), key);
+                  register_operation (self, GPA_OPERATION (op));
+                }
 	    }
           asked_about_key_backup = TRUE;
         }

commit 7a08aa710b4df95f38bfbbd3509f40f92175397d
Author: Werner Koch <wk at gnupg.org>
Date:   Mon May 12 11:59:37 2014 +0200

    In the subkey view show tooltips for the entire check box columns.
    
    * src/gpasubkeylist.c (query_tooltip_cb): New.
    (gpa_subkey_list_new): Connect handler.

diff --git a/src/gpasubkeylist.c b/src/gpasubkeylist.c
index 8e53cac..78e933b 100644
--- a/src/gpasubkeylist.c
+++ b/src/gpasubkeylist.c
@@ -26,6 +26,13 @@
 #include "keytable.h"
 #include "gpasubkeylist.h"
 
+
+static gboolean query_tooltip_cb (GtkWidget *wdiget, int x, int y,
+                                  gboolean keyboard_mode,
+                                  GtkTooltip *tooltip, gpointer user_data);
+
+
+
 /*
  *  Implement a List showing the subkeys in a given key
  */
@@ -154,6 +161,10 @@ gpa_subkey_list_new (void)
                         _("Serial number of the smart card."));
   gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
 
+  g_object_set (list, "has-tooltip", TRUE, NULL);
+  g_signal_connect (list, "query-tooltip",
+                    G_CALLBACK (query_tooltip_cb), list);
+
   return list;
 }
 
@@ -254,3 +265,32 @@ gpa_subkey_list_set_key (GtkWidget *list, gpgme_key_t key)
 	}
     }
 }
+
+
+/* Tooltip display callback.  */
+static gboolean
+query_tooltip_cb (GtkWidget *widget, int x, int y, gboolean keyboard_tip,
+                  GtkTooltip *tooltip, gpointer user_data)
+{
+  GtkTreeView *tv = GTK_TREE_VIEW (widget);
+  GtkTreeViewColumn *column;
+  char *text;
+
+  (void)user_data;
+
+  if (!gtk_tree_view_get_tooltip_context (tv, &x, &y, keyboard_tip,
+                                          NULL, NULL, NULL))
+    return FALSE; /* Not at a row - do not show a tooltip.  */
+  if (!gtk_tree_view_get_path_at_pos (tv, x, y, NULL, &column, NULL, NULL))
+    return FALSE;
+
+  widget = gtk_tree_view_column_get_widget (column);
+  text = widget? gtk_widget_get_tooltip_text (widget) : NULL;
+  if (!text)
+    return FALSE; /* No tooltip desired.  */
+
+  gtk_tooltip_set_text (tooltip, text);
+  g_free (text);
+
+  return TRUE; /* Show tooltip.  */
+}

commit a7da4281e8c515411d66ebd93a280a408bc517a2
Author: Werner Koch <wk at gnupg.org>
Date:   Mon May 12 09:52:14 2014 +0200

    Decorate expire date popup window in key generation.
    
    * src/gpadatebutton.c (gpa_date_button_clicked): Pass parent window
    to gtk_dialog_new.  Add close button to the dialog.

diff --git a/src/gpadatebutton.c b/src/gpadatebutton.c
index 6ea1a09..77b2513 100644
--- a/src/gpadatebutton.c
+++ b/src/gpadatebutton.c
@@ -161,12 +161,20 @@ static void
 gpa_date_button_clicked (GtkButton *button)
 {
   GpaDateButton *self = GPA_DATE_BUTTON (button);
+  GtkWidget *toplevel;
 
   if (!self->dialog)
     {
-      self->dialog = gtk_dialog_new ();
-      gtk_window_set_decorated (GTK_WINDOW (self->dialog), FALSE);
-      gtk_window_set_modal (GTK_WINDOW (self->dialog), TRUE);
+      toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
+      if (!gtk_widget_is_toplevel (toplevel))
+        toplevel = NULL;
+
+      self->dialog = gtk_dialog_new_with_buttons
+        (NULL,
+         GTK_WINDOW (toplevel),
+         (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT),
+         GTK_STOCK_CLOSE, GTK_RESPONSE_REJECT,
+         NULL);
 
       g_signal_connect (self->dialog, "destroy",
                         G_CALLBACK (destroy_cb), self);
@@ -183,7 +191,6 @@ gpa_date_button_clicked (GtkButton *button)
                         G_CALLBACK (month_changed_cb), self);
 
       gtk_widget_show_all (self->dialog);
-
     }
 
   update_widgets (self);

commit cfa5b413f38ce21865731b0cf31d552cbdbf5313
Author: Werner Koch <wk at gnupg.org>
Date:   Fri May 9 17:23:54 2014 +0200

    Use ".asc" for armored detached OpenPGP signatures.
    
    * src/gpafilesignop.c (destination_filename): Take care of ARMOR.

diff --git a/src/gpafilesignop.c b/src/gpafilesignop.c
index ff3a142..5ecef78 100644
--- a/src/gpafilesignop.c
+++ b/src/gpafilesignop.c
@@ -244,7 +244,7 @@ destination_filename (const gchar *filename, gboolean armor,
   else if (protocol == GPGME_PROTOCOL_CMS)
     extension = ".p7s";
   else if (sign_type == GPGME_SIG_MODE_DETACH)
-    extension = ".sig";
+    extension = (armor && protocol == GPGME_PROTOCOL_OPENPGP)? ".asc" : ".sig";
   else if (sign_type == GPGME_SIG_MODE_CLEAR)
     extension = ".asc";
   else

commit 107c1465ebd6447ac4ec04a5fd3ca582cf9e5686
Author: Werner Koch <wk at gnupg.org>
Date:   Fri May 9 17:08:10 2014 +0200

    Improve detection of detached signature files.
    
    * src/gpafileverifyop.c (is_detached_sig): Rewrite and add test for
    file.
    --
    
    GnuPG-bug-id: 1637

diff --git a/src/gpafileverifyop.c b/src/gpafileverifyop.c
index 5f45308..67fc412 100644
--- a/src/gpafileverifyop.c
+++ b/src/gpafileverifyop.c
@@ -196,45 +196,48 @@ static gboolean
 is_detached_sig (const gchar *filename, gchar **signature_file,
 		 gchar **signed_file, GtkWidget *window)
 {
-  const gchar *sig_extension[] = {".sig", ".sign"};
+  const gchar *sig_extension[] = {".sig", ".asc", ".sign"};
   int i;
   gchar *extension;
-  /* First, check whether this file is a dettached signature */
+
+  /* First, check whether this file is a detached signature.  */
   *signed_file = g_strdup (filename);
   extension = g_strrstr (*signed_file, ".");
-  if (extension &&
-      (g_str_equal (extension, ".sig") ||
-       g_str_equal (extension, ".sign")))
+  if (extension)
     {
-      *extension++ = '\0';
-      *signature_file = g_strdup (filename);
-      return TRUE;
+      for (i = 0; i < DIM (sig_extension); i++)
+        if (g_str_equal (extension, sig_extension[i]))
+          {
+            *extension = '\0';  /* That makes SIGNED_FILE */
+            if (g_file_test (*signed_file, G_FILE_TEST_EXISTS))
+              {
+                *signature_file = g_strdup (filename);
+                return TRUE;
+              }
+            g_free (*signed_file);
+            *signed_file = NULL;
+            return FALSE; /* signed file does not exist.  */
+          }
     }
-  /* Now, check whether a dettached signature exists for this file */
-  else
-    {
-      g_free (*signed_file);
-      *signed_file = NULL;
-
-      for (i = 0; i < sizeof(sig_extension)/sizeof(sig_extension[0]); i++)
-	{
-	  gchar *sig = g_strconcat (filename, sig_extension[i], NULL);
+  g_free (*signed_file);
+  *signed_file = NULL;
 
-	  if (g_file_test (sig, G_FILE_TEST_EXISTS) &&
-	      ask_use_detached_sig (filename, sig, window))
-	    {
-	      *signed_file = g_strdup (filename);
-	      *signature_file = sig;
-	      return TRUE;
-	    }
-	  else
-	    {
-	      g_free (sig);
-	    }
-	}
-
-      return FALSE;
+  /* Now, check whether a detached signature exists for this file */
+  for (i = 0; i < DIM (sig_extension); i++)
+    {
+      gchar *sig = g_strconcat (filename, sig_extension[i], NULL);
+
+      if (g_file_test (sig, G_FILE_TEST_EXISTS)
+          && ask_use_detached_sig (filename, sig, window))
+        {
+          *signed_file = g_strdup (filename);
+          *signature_file = sig;
+          return TRUE;
+        }
+      g_free (sig);
     }
+
+  return FALSE;
 }
 
 static gboolean

commit af81899cf7b7c61ef4fd40b0b2edca3a3f438c74
Author: Werner Koch <wk at gnupg.org>
Date:   Thu May 8 20:43:46 2014 +0200

    Show the name of the curve and the creation date in the subkey list.
    
    * src/gpa-key-details.c (details_page_fill_key): Add curve info.
    * src/gpasubkeylist.c (SUBKEY_CREATED): Add new column.
    (gpa_subkey_list_new): Abbreviate some column titles.  Print creation
    date.
    (gpa_subkey_list_set_key): Set creation date and curve name.

diff --git a/src/gpa-key-details.c b/src/gpa-key-details.c
index c43c8ca..38d5d3c 100644
--- a/src/gpa-key-details.c
+++ b/src/gpa-key-details.c
@@ -18,7 +18,7 @@
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
-/* 
+/*
    This widget is used to display details of a key.
 
  */
@@ -31,7 +31,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "gpa.h"   
+#include "gpa.h"
 #include "convert.h"
 #include "keytable.h"
 #include "siglist.h"
@@ -42,7 +42,7 @@
 
 

 /* Object's class definition.  */
-struct _GpaKeyDetailsClass 
+struct _GpaKeyDetailsClass
 {
   GtkNotebookClass parent_class;
 };
@@ -93,7 +93,7 @@ static void gpa_key_details_finalize (GObject *object);
 
 
 

-/************************************************************ 
+/************************************************************
  *******************   Implementation   *********************
  ************************************************************/
 
@@ -108,7 +108,7 @@ signatures_uid_changed (GtkComboBox *combo, gpointer user_data)
     {
       /* Note that we need to subtract one, as the first entry (with
          index 0 means) "all user names".  */
-      gpa_siglist_set_signatures 
+      gpa_siglist_set_signatures
         (kdt->signatures_list, kdt->current_key,
          gtk_combo_box_get_active (GTK_COMBO_BOX (combo)) - 1);
     }
@@ -123,7 +123,7 @@ details_page_fill_key (GpaKeyDetails *kdt, gpgme_key_t key)
   gpgme_key_t seckey;
   char *text;
 
-  seckey = gpa_keytable_lookup_key (gpa_keytable_get_secret_instance(), 
+  seckey = gpa_keytable_lookup_key (gpa_keytable_get_secret_instance(),
                                     key->subkeys->fpr);
   if (seckey)
     {
@@ -176,6 +176,13 @@ details_page_fill_key (GpaKeyDetails *kdt, gpgme_key_t key)
   text = g_strdup_printf (_("%s %u bits"),
 			  gpgme_pubkey_algo_name (key->subkeys->pubkey_algo),
 			  key->subkeys->length);
+  if (key->subkeys->curve)
+    {
+      char *text2;
+      text2 = g_strdup_printf ("%s, %s", text, key->subkeys->curve);
+      g_free (text);
+      text = text2;
+    }
   gtk_label_set_text (GTK_LABEL (kdt->detail_key_type), text);
   g_free (text);
 
@@ -204,12 +211,12 @@ details_page_fill_num_keys (GpaKeyDetails *kdt, gint num_key)
     {
       char *text = g_strdup_printf (ngettext("%d key selected",
                                              "%d keys selected",
-                                             num_key), num_key); 
+                                             num_key), num_key);
 
       gtk_label_set_text (GTK_LABEL (kdt->details_num_label), text);
       g_free (text);
     }
-  
+
   gtk_widget_show_all (kdt->details_num_label);
   gtk_widget_hide_all (kdt->details_table);
   gtk_widget_set_no_show_all (kdt->details_num_label, FALSE);
@@ -271,7 +278,7 @@ construct_details_page (GpaKeyDetails *kdt)
   label = gtk_label_new ("");
   kdt->details_num_label = label;
   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
-  
+
   table = gtk_table_new (2, 7, FALSE);
   kdt->details_table = table;
   gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
@@ -279,25 +286,25 @@ construct_details_page (GpaKeyDetails *kdt)
   gtk_table_set_col_spacing (GTK_TABLE (table), 0, 4);
 
   table_row = 0;
-  kdt->detail_public_private = add_details_row 
+  kdt->detail_public_private = add_details_row
     (table, table_row++, "", TRUE);
-  kdt->detail_capabilities = add_details_row 
+  kdt->detail_capabilities = add_details_row
     (table, table_row++, "", TRUE);
-  kdt->detail_name = add_details_row 
+  kdt->detail_name = add_details_row
     (table, table_row++, _("User name:"), TRUE);
-  kdt->detail_key_id = add_details_row 
+  kdt->detail_key_id = add_details_row
     (table, table_row++, _("Key ID:"), TRUE);
-  kdt->detail_fingerprint = add_details_row 
+  kdt->detail_fingerprint = add_details_row
     (table, table_row++, _("Fingerprint:"), TRUE);
-  kdt->detail_expiry = add_details_row 
-    (table, table_row++, _("Expires at:"), FALSE); 
-  kdt->detail_owner_trust = add_details_row 
+  kdt->detail_expiry = add_details_row
+    (table, table_row++, _("Expires at:"), FALSE);
+  kdt->detail_owner_trust = add_details_row
     (table, table_row++, _("Owner Trust:"), FALSE);
-  kdt->detail_key_trust = add_details_row 
+  kdt->detail_key_trust = add_details_row
     (table, table_row++, _("Key validity:"), FALSE);
-  kdt->detail_key_type = add_details_row 
+  kdt->detail_key_type = add_details_row
     (table, table_row++, _("Key type:"), FALSE);
-  kdt->detail_creation = add_details_row 
+  kdt->detail_creation = add_details_row
     (table, table_row++, _("Created at:"), FALSE);
 
   gtk_notebook_append_page (GTK_NOTEBOOK (kdt), scrolled,
@@ -318,9 +325,9 @@ build_signatures_page (GpaKeyDetails *kdt, gpgme_key_t key)
     {
       if (kdt->signatures_uids)
         g_signal_handlers_disconnect_by_func
-          (G_OBJECT (kdt->signatures_uids), 
+          (G_OBJECT (kdt->signatures_uids),
            G_CALLBACK (signatures_uid_changed), kdt);
-      
+
       pnum = gtk_notebook_page_num (GTK_NOTEBOOK (kdt), kdt->signatures_page);
       if (pnum >= 0)
         gtk_notebook_remove_page (GTK_NOTEBOOK (kdt), pnum);
@@ -352,7 +359,7 @@ build_signatures_page (GpaKeyDetails *kdt, gpgme_key_t key)
       kdt->signatures_uids = gtk_combo_box_new_text ();
       gtk_box_pack_start (GTK_BOX (hbox), kdt->signatures_uids, TRUE, TRUE, 0);
       gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-      
+
       /* Connect the signal to update the list of user IDs in the
          signatures page of the notebook.  */
       g_signal_connect (G_OBJECT (kdt->signatures_uids), "changed",
@@ -382,7 +389,7 @@ build_signatures_page (GpaKeyDetails *kdt, gpgme_key_t key)
 
   kdt->signatures_page = vbox;
   gtk_notebook_append_page (GTK_NOTEBOOK (kdt), vbox,
-                            gtk_label_new 
+                            gtk_label_new
                             (kdt->certchain_list? _("Chain"):_("Signatures")));
 
 
@@ -396,7 +403,7 @@ build_signatures_page (GpaKeyDetails *kdt, gpgme_key_t key)
       gpgme_user_id_t uid;
       GtkComboBox *combo;
       int i;
-      
+
       /* Make the combo widget's width shrink as much as
 	 possible. This (hopefully) fixes the previous behaviour
 	 correctly: displaying a key with slightly longer signed UIDs
@@ -413,7 +420,7 @@ build_signatures_page (GpaKeyDetails *kdt, gpgme_key_t key)
 	  gtk_combo_box_append_text (combo, uid_string);
 	  g_free (uid_string);
 	}
-      
+
       gpa_siglist_set_signatures (kdt->signatures_list, key, -1);
     }
   else
@@ -465,10 +472,10 @@ build_subkeys_page (GpaKeyDetails *kdt, gpgme_key_t key)
   g_object_ref (kdt->subkeys_list);
   kdt->subkeys_page = vbox;
   gtk_notebook_append_page (GTK_NOTEBOOK (kdt), kdt->subkeys_page,
-                            gtk_label_new 
+                            gtk_label_new
                             (key->protocol == GPGME_PROTOCOL_OpenPGP
                              ? _("Subkeys") : _("Key")));
-  
+
   /* Fill this page.  */
   gpa_subkey_list_set_key (kdt->subkeys_list, key);
 
@@ -487,12 +494,12 @@ ui_mode_changed (GpaOptions *options, gpointer param)
       build_signatures_page (kdt, NULL);
       build_subkeys_page (kdt, NULL);
     }
-  else 
+  else
     {
       build_signatures_page (kdt, kdt->current_key);
       build_subkeys_page (kdt, kdt->current_key);
     }
-  gtk_notebook_set_show_tabs 
+  gtk_notebook_set_show_tabs
     (GTK_NOTEBOOK (kdt), gtk_notebook_get_n_pages (GTK_NOTEBOOK (kdt)) > 1);
   gtk_widget_show_all (GTK_WIDGET (kdt));
 }
@@ -514,7 +521,7 @@ construct_main_widget (GpaKeyDetails *kdt)
 
 
 

-/************************************************************ 
+/************************************************************
  ******************   Object Management  ********************
  ************************************************************/
 
@@ -524,7 +531,7 @@ gpa_key_details_class_init (void *class_ptr, void *class_data)
   GpaKeyDetailsClass *klass = class_ptr;
 
   parent_class = g_type_class_peek_parent (klass);
-  
+
   G_OBJECT_CLASS (klass)->finalize = gpa_key_details_finalize;
 }
 
@@ -540,7 +547,7 @@ gpa_key_details_init (GTypeInstance *instance, void *class_ptr)
 
 static void
 gpa_key_details_finalize (GObject *object)
-{  
+{
   GpaKeyDetails *kdt = GPA_KEY_DETAILS (object);
 
   if (kdt->current_key)
@@ -573,7 +580,7 @@ GType
 gpa_key_details_get_type (void)
 {
   static GType this_type = 0;
-  
+
   if (!this_type)
     {
       static const GTypeInfo this_info =
@@ -588,23 +595,23 @@ gpa_key_details_get_type (void)
 	  0,    /* n_preallocs */
 	  gpa_key_details_init
 	};
-      
+
       this_type = g_type_register_static (GTK_TYPE_NOTEBOOK,
                                           "GpaKeyDetails",
                                           &this_info, 0);
     }
-  
+
   return this_type;
 }
 
 

-/************************************************************ 
+/************************************************************
  **********************  Public API  ************************
  ************************************************************/
 GtkWidget *
 gpa_key_details_new ()
 {
-  return GTK_WIDGET (g_object_new (GPA_KEY_DETAILS_TYPE, NULL));  
+  return GTK_WIDGET (g_object_new (GPA_KEY_DETAILS_TYPE, NULL));
 }
 
 
@@ -636,8 +643,8 @@ gpa_key_details_update (GtkWidget *keydetails, gpgme_key_t key, int keycount)
     }
   else
     pnum = 0;
-  
-  
+
+
   if (kdt->current_key)
     {
       gpgme_key_unref (kdt->current_key);
@@ -668,7 +675,7 @@ gpa_key_details_update (GtkWidget *keydetails, gpgme_key_t key, int keycount)
       build_signatures_page (kdt, NULL);
       build_subkeys_page (kdt, NULL);
     }
-  gtk_notebook_set_show_tabs 
+  gtk_notebook_set_show_tabs
     (GTK_NOTEBOOK (kdt), gtk_notebook_get_n_pages (GTK_NOTEBOOK (kdt)) > 1);
 
   gtk_widget_show_all (keydetails);
diff --git a/src/gpasubkeylist.c b/src/gpasubkeylist.c
index cdcc057..8e53cac 100644
--- a/src/gpasubkeylist.c
+++ b/src/gpasubkeylist.c
@@ -35,6 +35,7 @@ typedef enum
   SUBKEY_ID,
   SUBKEY_SIZE,
   SUBKEY_ALGO,
+  SUBKEY_CREATED,
   SUBKEY_EXPIRE,
   SUBKEY_CAN_SIGN,
   SUBKEY_CAN_CERTIFY,
@@ -62,6 +63,7 @@ gpa_subkey_list_new (void)
 			      G_TYPE_STRING,
 			      G_TYPE_STRING,
 			      G_TYPE_STRING,
+			      G_TYPE_STRING,
 			      G_TYPE_BOOLEAN,
 			      G_TYPE_BOOLEAN,
 			      G_TYPE_BOOLEAN,
@@ -88,7 +90,7 @@ gpa_subkey_list_new (void)
   gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
 
   renderer = gtk_cell_renderer_text_new ();
-  column = gtk_tree_view_column_new_with_attributes (_("Algorithm"),
+  column = gtk_tree_view_column_new_with_attributes (_("Algo"),
 						     renderer,
 						     "text", SUBKEY_ALGO,
 						     NULL);
@@ -101,7 +103,14 @@ gpa_subkey_list_new (void)
   gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
 
   renderer = gtk_cell_renderer_text_new ();
-  column = gtk_tree_view_column_new_with_attributes (_("Expiry Date"),
+  column = gtk_tree_view_column_new_with_attributes (_("Created"),
+						     renderer,
+						     "text", SUBKEY_CREATED,
+						     NULL);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
+
+  renderer = gtk_cell_renderer_text_new ();
+  column = gtk_tree_view_column_new_with_attributes (_("Expires"),
 						     renderer,
 						     "text", SUBKEY_EXPIRE,
 						     NULL);
@@ -110,38 +119,38 @@ gpa_subkey_list_new (void)
   renderer = gtk_cell_renderer_toggle_new ();
   column = gtk_tree_view_column_new_with_attributes
     (NULL, renderer, "active", SUBKEY_CAN_SIGN, NULL);
-  gpa_set_column_title (column, _("[S]"), _("Can sign"));
+  gpa_set_column_title (column, _("S"), _("Can sign"));
   gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
 
   renderer = gtk_cell_renderer_toggle_new ();
-  column = gtk_tree_view_column_new_with_attributes 
+  column = gtk_tree_view_column_new_with_attributes
     (NULL, renderer, "active", SUBKEY_CAN_CERTIFY, NULL);
-  gpa_set_column_title (column, _("[C]"), _("Can certify"));
+  gpa_set_column_title (column, _("C"), _("Can certify"));
   gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
 
   renderer = gtk_cell_renderer_toggle_new ();
   column = gtk_tree_view_column_new_with_attributes
     (NULL, renderer, "active", SUBKEY_CAN_ENCRYPT, NULL);
-  gpa_set_column_title (column, _("[E]"), _("Can encrypt"));
+  gpa_set_column_title (column, _("E"), _("Can encrypt"));
   gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
 
   renderer = gtk_cell_renderer_toggle_new ();
   column = gtk_tree_view_column_new_with_attributes
     (NULL, renderer, "active", SUBKEY_CAN_AUTHENTICATE, NULL);
-  gpa_set_column_title (column, _("[A]"), _("Can authenticate"));
+  gpa_set_column_title (column, _("A"), _("Can authenticate"));
   gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
 
   renderer = gtk_cell_renderer_toggle_new ();
   column = gtk_tree_view_column_new_with_attributes
     (NULL, renderer, "active", SUBKEY_IS_CARDKEY, NULL);
-  gpa_set_column_title (column, _("[T]"), 
+  gpa_set_column_title (column, _("T"),
                         _("Secret key stored on a smartcard."));
   gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
 
   renderer = gtk_cell_renderer_text_new ();
   column = gtk_tree_view_column_new_with_attributes
     (NULL, renderer, "text", SUBKEY_CARD_NUMBER, NULL);
-  gpa_set_column_title (column, _("Card S/N"), 
+  gpa_set_column_title (column, _("Card S/N"),
                         _("Serial number of the smart card."));
   gtk_tree_view_append_column (GTK_TREE_VIEW (list), column);
 
@@ -183,16 +192,16 @@ gpa_subkey_list_set_key (GtkWidget *list, gpgme_key_t key)
                                         (GTK_TREE_VIEW (list)));
   gpgme_subkey_t subkey, secsubkey;
   gpgme_key_t seckey;
-  gchar *size;
+  gchar *p, *size, *expires;
 
   /* Empty the list */
   gtk_list_store_clear (store);
 
   if (key)
     {
-      seckey = gpa_keytable_lookup_key 
+      seckey = gpa_keytable_lookup_key
         (gpa_keytable_get_secret_instance (), key->subkeys->fpr);
-      
+
       /* Add all the subkeys */
       for (subkey = key->subkeys; subkey; subkey = subkey->next)
 	{
@@ -202,7 +211,7 @@ gpa_subkey_list_set_key (GtkWidget *list, gpgme_key_t key)
             {
               for (secsubkey = seckey->subkeys; secsubkey;
                    secsubkey = secsubkey->next)
-                if (subkey->fpr && secsubkey->fpr 
+                if (subkey->fpr && secsubkey->fpr
                     && g_str_equal (subkey->fpr, secsubkey->fpr))
                   break;
             }
@@ -211,15 +220,27 @@ gpa_subkey_list_set_key (GtkWidget *list, gpgme_key_t key)
 
 	  /* Append */
 	  gtk_list_store_append (store, &iter);
-	  size = g_strdup_printf ("%i bits", subkey->length);
-          gtk_list_store_set 
+          if (subkey->curve)
+            size = g_strdup (subkey->curve);
+          else
+            size = g_strdup_printf ("%i bits", subkey->length);
+
+          /* We only want "never" and not "never expires" but we need
+             to take care of the ">= 2038" string.  */
+          expires = gpa_expiry_date_string (subkey->expires);
+          if (*expires != '>' && (p = strchr (expires, ' ')))
+            *p = 0;
+
+          gtk_list_store_set
             (store, &iter,
              SUBKEY_ID, subkey->keyid+8,
              SUBKEY_SIZE, size,
              SUBKEY_ALGO,
              gpgme_pubkey_algo_name (subkey->pubkey_algo),
-             SUBKEY_EXPIRE, 
-             gpa_expiry_date_string (subkey->expires),
+             SUBKEY_CREATED,
+             gpa_creation_date_string (subkey->timestamp),
+             SUBKEY_EXPIRE,
+             expires,
              SUBKEY_CAN_SIGN, subkey->can_sign,
              SUBKEY_CAN_CERTIFY, subkey->can_certify,
              SUBKEY_CAN_ENCRYPT, subkey->can_encrypt,
@@ -229,6 +250,7 @@ gpa_subkey_list_set_key (GtkWidget *list, gpgme_key_t key)
              SUBKEY_STATUS, subkey_status (subkey),
              -1);
 	  g_free (size);
-	} 
-    }    
+	  g_free (expires);
+	}
+    }
 }

-----------------------------------------------------------------------

Summary of changes:
 src/gpa-key-details.c   |   89 ++++++++++++++++++++++-------------------
 src/gpa.c               |   15 ++++++-
 src/gpabackupop.c       |   59 +++++++++++++++++++---------
 src/gpabackupop.h       |   10 +++--
 src/gpadatebutton.c     |   15 +++++--
 src/gpafilesignop.c     |    2 +-
 src/gpafileverifyop.c   |   65 +++++++++++++++---------------
 src/gpagenkeysimpleop.c |    3 +-
 src/gpakeysignop.c      |   34 +++++++++-------
 src/gpasubkeylist.c     |  100 ++++++++++++++++++++++++++++++++++++++---------
 src/gpgmeedit.c         |    1 +
 src/gpgmetools.c        |   36 +++++++++++------
 src/gpgmetools.h        |    7 ++--
 src/keylist.c           |   11 ++++--
 src/keylist.h           |    9 +++--
 src/keymanager.c        |   74 +++++++++++++++++++++++------------
 src/server.c            |   13 ++++++
 17 files changed, 363 insertions(+), 180 deletions(-)


hooks/post-receive
-- 
The GNU Privacy Assistant
http://git.gnupg.org




More information about the Gnupg-commits mailing list