gpg: Add list-option "show-usage".
[gnupg.git] / g10 / keyedit.c
index 7d54849..77bd37f 100644 (file)
@@ -1,6 +1,7 @@
 /* keyedit.c - keyedit stuff
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
  *               2008, 2009, 2010 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2014 Werner Koch
  *
  * This file is part of GnuPG.
  *
@@ -30,6 +31,7 @@
 # include <readline/readline.h>
 #endif
 
+#define JNLIB_NEED_LOG_LOGV
 #include "gpg.h"
 #include "options.h"
 #include "packet.h"
 #include "status.h"
 #include "i18n.h"
 #include "keyserver-internal.h"
+#include "call-agent.h"
 
 static void show_prefs (PKT_user_id * uid, PKT_signature * selfsig,
                        int verbose);
-static void show_names (KBNODE keyblock, PKT_public_key * pk,
+static void show_names (estream_t fp, KBNODE keyblock, PKT_public_key * pk,
                        unsigned int flag, int with_prefs);
-static void show_key_with_all_names (KBNODE keyblock, int only_marked,
+static void show_key_with_all_names (estream_t fp,
+                                     KBNODE keyblock, int only_marked,
                                     int with_revoker, int with_fpr,
-                                    int with_subkeys, int with_prefs);
+                                    int with_subkeys, int with_prefs,
+                                     int nowarn);
 static void show_key_and_fingerprint (KBNODE keyblock);
-static int menu_adduid (KBNODE keyblock, KBNODE sec_keyblock,
-                       int photo, const char *photo_name);
-static void menu_deluid (KBNODE pub_keyblock, KBNODE sec_keyblock);
+static int menu_adduid (KBNODE keyblock, int photo, const char *photo_name);
+static void menu_deluid (KBNODE pub_keyblock);
 static int menu_delsig (KBNODE pub_keyblock);
 static int menu_clean (KBNODE keyblock, int self_only);
-static void menu_delkey (KBNODE pub_keyblock, KBNODE sec_keyblock);
-static int menu_addrevoker (KBNODE pub_keyblock,
-                           KBNODE sec_keyblock, int sensitive);
-static int menu_expire (KBNODE pub_keyblock, KBNODE sec_keyblock);
-static int menu_backsign (KBNODE pub_keyblock, KBNODE sec_keyblock);
-static int menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock);
-static int menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock);
-static int menu_set_keyserver_url (const char *url,
-                                  KBNODE pub_keyblock, KBNODE sec_keyblock);
-static int menu_set_notation (const char *string,
-                             KBNODE pub_keyblock, KBNODE sec_keyblock);
+static void menu_delkey (KBNODE pub_keyblock);
+static int menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive);
+static int menu_expire (KBNODE pub_keyblock);
+static int menu_backsign (KBNODE pub_keyblock);
+static int menu_set_primary_uid (KBNODE pub_keyblock);
+static int menu_set_preferences (KBNODE pub_keyblock);
+static int menu_set_keyserver_url (const char *url, KBNODE pub_keyblock);
+static int menu_set_notation (const char *string, KBNODE pub_keyblock);
 static int menu_select_uid (KBNODE keyblock, int idx);
 static int menu_select_uid_namehash (KBNODE keyblock, const char *namehash);
 static int menu_select_key (KBNODE keyblock, int idx);
@@ -80,10 +81,12 @@ static int count_selected_uids (KBNODE keyblock);
 static int real_uids_left (KBNODE keyblock);
 static int count_selected_keys (KBNODE keyblock);
 static int menu_revsig (KBNODE keyblock);
-static int menu_revuid (KBNODE keyblock, KBNODE sec_keyblock);
-static int menu_revkey (KBNODE pub_keyblock, KBNODE sec_keyblock);
-static int menu_revsubkey (KBNODE pub_keyblock, KBNODE sec_keyblock);
+static int menu_revuid (KBNODE keyblock);
+static int menu_revkey (KBNODE pub_keyblock);
+static int menu_revsubkey (KBNODE pub_keyblock);
+#ifndef NO_TRUST_MODELS
 static int enable_disable_key (KBNODE keyblock, int disable);
+#endif /*!NO_TRUST_MODELS*/
 static void menu_showphoto (KBNODE keyblock);
 
 static int update_trust = 0;
@@ -110,34 +113,6 @@ struct sign_attrib
 };
 
 
-#ifdef ENABLE_CARD_SUPPORT
-/* Given a node SEC_NODE with a secret key or subkey, locate the
-   corresponding public key from pub_keyblock. */
-static PKT_public_key *
-find_pk_from_sknode (KBNODE pub_keyblock, KBNODE sec_node)
-{
-  KBNODE node = pub_keyblock;
-  PKT_secret_key *sk;
-  PKT_public_key *pk;
-
-  if (sec_node->pkt->pkttype == PKT_SECRET_KEY
-      && node->pkt->pkttype == PKT_PUBLIC_KEY)
-    return node->pkt->pkt.public_key;
-  if (sec_node->pkt->pkttype != PKT_SECRET_SUBKEY)
-    return NULL;
-  sk = sec_node->pkt->pkt.secret_key;
-  for (; node; node = node->next)
-    if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-      {
-       pk = node->pkt->pkt.public_key;
-       if (pk->keyid[0] == sk->keyid[0] && pk->keyid[1] == sk->keyid[1])
-         return pk;
-      }
-
-  return NULL;
-}
-#endif /* ENABLE_CARD_SUPPORT */
-
 
 /* TODO: Fix duplicated code between here and the check-sigs/list-sigs
    code in keylist.c. */
@@ -280,7 +255,7 @@ print_and_check_one_sig (KBNODE keyblock, KBNODE node,
        {
          size_t n;
          char *p = get_user_id (sig->keyid, &n);
-         tty_print_utf8_string2 (p, n,
+         tty_print_utf8_string2 (NULL, p, n,
                                  opt.screen_columns - keystrlen () - 26 -
                                  ((opt.
                                    list_options & LIST_SHOW_SIG_EXPIRE) ? 11
@@ -525,13 +500,16 @@ trustsig_prompt (byte * trust_value, byte * trust_depth, char **regexp)
 
 
 /*
- * Loop over all locusr and and sign the uids after asking.
- * If no user id is marked, all user ids will be signed;
- * if some user_ids are marked those will be signed.
+ * Loop over all LOCUSR and and sign the uids after asking.  If no
+ * user id is marked, all user ids will be signed; if some user_ids
+ * are marked only those will be signed.  If QUICK is true the
+ * function won't ask the user and use sensible defaults.
  */
 static int
-sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
-          int local, int nonrevocable, int trust, int interactive)
+sign_uids (estream_t fp,
+           kbnode_t keyblock, strlist_t locusr, int *ret_modified,
+          int local, int nonrevocable, int trust, int interactive,
+           int quick)
 {
   int rc = 0;
   SK_LIST sk_list = NULL;
@@ -544,22 +522,24 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
 
   /* Are there any non-v3 sigs on this key already? */
   if (PGP2)
-    for (node = keyblock; node; node = node->next)
-      if (node->pkt->pkttype == PKT_SIGNATURE &&
-         node->pkt->pkt.signature->version > 3)
-       {
-         all_v3 = 0;
-         break;
-       }
+    {
+      for (node = keyblock; node; node = node->next)
+        if (node->pkt->pkttype == PKT_SIGNATURE &&
+            node->pkt->pkt.signature->version > 3)
+          {
+            all_v3 = 0;
+            break;
+          }
+    }
 
   /* Build a list of all signators.
-   *    
+   *
    * We use the CERT flag to request the primary which must always
    * be one which is capable of signing keys.  I can't see a reason
    * why to sign keys using a subkey.  Implementation of USAGE_CERT
    * is just a hack in getkey.c and does not mean that a subkey
    * marked as certification capable will be used. */
-  rc = build_sk_list (locusr, &sk_list, 0, PUBKEY_USAGE_CERT);
+  rc = build_sk_list (locusr, &sk_list, PUBKEY_USAGE_CERT);
   if (rc)
     goto leave;
 
@@ -572,18 +552,11 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
       u32 duration = 0, timestamp = 0;
       byte trust_depth = 0, trust_value = 0;
 
-      if (local || nonrevocable || trust ||
-         opt.cert_policy_url || opt.cert_notations)
+      if (local || nonrevocable || trust
+          || opt.cert_policy_url || opt.cert_notations)
        force_v4 = 1;
 
-      /* We have to use a copy of the pk, because make_keysig_packet
-       * may remove the protection from sk and if we did other
-       * changes to the secret key, we would save the unprotected
-       * version.  FIXME: This can be removed because all protection
-       * is now done by gpg-agent.  */
-      if (pk)
-       free_public_key (pk);
-      pk = copy_public_key (NULL, sk_rover->pk);
+      pk = sk_rover->pk;
       keyid_from_pk (pk, sk_keyid);
 
       /* Set mark A for all selected user ids.  */
@@ -594,6 +567,7 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
          else
            node->flag &= ~NODFLG_MARK_A;
        }
+
       /* Reset mark for uids which are already signed.  */
       uidnode = NULL;
       for (node = keyblock; node; node = node->next)
@@ -620,20 +594,20 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
              if (uidnode)
                {
                  int yesreally = 0;
-                 char *user =
-                   utf8_to_native (uidnode->pkt->pkt.user_id->name,
-                                   uidnode->pkt->pkt.user_id->len,
-                                   0);
+                 char *user;
+
+                  user = utf8_to_native (uidnode->pkt->pkt.user_id->name,
+                                         uidnode->pkt->pkt.user_id->len, 0);
 
                  if (uidnode->pkt->pkt.user_id->is_revoked)
                    {
-                     tty_printf (_("User ID \"%s\" is revoked."), user);
+                     tty_fprintf (fp, _("User ID \"%s\" is revoked."), user);
 
                      if (selfsig)
-                       tty_printf ("\n");
-                     else if (opt.expert)
+                       tty_fprintf (fp, "\n");
+                     else if (opt.expert && !quick)
                        {
-                         tty_printf ("\n");
+                         tty_fprintf (fp, "\n");
                          /* No, so remove the mark and continue */
                          if (!cpr_get_answer_is_yes ("sign_uid.revoke_okay",
                                                      _("Are you sure you "
@@ -650,18 +624,18 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
                        {
                          uidnode->flag &= ~NODFLG_MARK_A;
                          uidnode = NULL;
-                         tty_printf (_("  Unable to sign.\n"));
+                         tty_fprintf (fp, _("  Unable to sign.\n"));
                        }
                    }
                  else if (uidnode->pkt->pkt.user_id->is_expired)
                    {
-                     tty_printf (_("User ID \"%s\" is expired."), user);
+                     tty_fprintf (fp, _("User ID \"%s\" is expired."), user);
 
                      if (selfsig)
-                       tty_printf ("\n");
-                     else if (opt.expert)
+                       tty_fprintf (fp, "\n");
+                     else if (opt.expert && !quick)
                        {
-                         tty_printf ("\n");
+                         tty_fprintf (fp, "\n");
                          /* No, so remove the mark and continue */
                          if (!cpr_get_answer_is_yes ("sign_uid.expire_okay",
                                                      _("Are you sure you "
@@ -678,17 +652,17 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
                        {
                          uidnode->flag &= ~NODFLG_MARK_A;
                          uidnode = NULL;
-                         tty_printf (_("  Unable to sign.\n"));
+                         tty_fprintf (fp, _("  Unable to sign.\n"));
                        }
                    }
                  else if (!uidnode->pkt->pkt.user_id->created && !selfsig)
                    {
-                     tty_printf (_("User ID \"%s\" is not self-signed."),
-                                 user);
+                     tty_fprintf (fp, _("User ID \"%s\" is not self-signed."),
+                                   user);
 
-                     if (opt.expert)
+                     if (opt.expert && !quick)
                        {
-                         tty_printf ("\n");
+                         tty_fprintf (fp, "\n");
                          /* No, so remove the mark and continue */
                          if (!cpr_get_answer_is_yes ("sign_uid.nosig_okay",
                                                      _("Are you sure you "
@@ -705,13 +679,14 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
                        {
                          uidnode->flag &= ~NODFLG_MARK_A;
                          uidnode = NULL;
-                         tty_printf (_("  Unable to sign.\n"));
+                         tty_fprintf (fp, _("  Unable to sign.\n"));
                        }
                    }
 
-                 if (uidnode && interactive && !yesreally)
+                 if (uidnode && interactive && !yesreally && !quick)
                    {
-                     tty_printf (_("User ID \"%s\" is signable.  "), user);
+                     tty_fprintf (fp,
+                                   _("User ID \"%s\" is signable.  "), user);
                      if (!cpr_get_answer_is_yes ("sign_uid.sign_okay",
                                                  _("Sign it? (y/N) ")))
                        {
@@ -730,16 +705,18 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
                  && sk_keyid[1] == node->pkt->pkt.signature->keyid[1])
                {
                  char buf[50];
-                 char *user =
-                   utf8_to_native (uidnode->pkt->pkt.user_id->name,
-                                   uidnode->pkt->pkt.user_id->len,
-                                   0);
+                 char *user;
+
+                  user = utf8_to_native (uidnode->pkt->pkt.user_id->name,
+                                         uidnode->pkt->pkt.user_id->len, 0);
 
                  /* It's a v3 self-sig.  Make it into a v4 self-sig? */
-                 if (node->pkt->pkt.signature->version < 4 && selfsig)
+                 if (node->pkt->pkt.signature->version < 4
+                      && selfsig && !quick)
                    {
-                     tty_printf (_("The self-signature on \"%s\"\n"
-                                   "is a PGP 2.x-style signature.\n"), user);
+                     tty_fprintf (fp,
+                                   _("The self-signature on \"%s\"\n"
+                                     "is a PGP 2.x-style signature.\n"), user);
 
                      /* Note that the regular PGP2 warning below
                         still applies if there are no v4 sigs on
@@ -761,10 +738,10 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
                  /* Is the current signature expired? */
                  if (node->pkt->pkt.signature->flags.expired)
                    {
-                     tty_printf (_("Your current signature on \"%s\"\n"
-                                   "has expired.\n"), user);
+                     tty_fprintf (fp, _("Your current signature on \"%s\"\n"
+                                         "has expired.\n"), user);
 
-                     if (cpr_get_answer_is_yes
+                     if (quick || cpr_get_answer_is_yes
                          ("sign_uid.replace_expired_okay",
                           _("Do you want to issue a "
                             "new signature to replace "
@@ -787,10 +764,10 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
                    {
                      /* It's a local sig, and we want to make a
                         exportable sig. */
-                     tty_printf (_("Your current signature on \"%s\"\n"
-                                   "is a local signature.\n"), user);
+                     tty_fprintf (fp, _("Your current signature on \"%s\"\n"
+                                         "is a local signature.\n"), user);
 
-                     if (cpr_get_answer_is_yes
+                     if (quick || cpr_get_answer_is_yes
                          ("sign_uid.local_promote_okay",
                           _("Do you want to promote "
                             "it to a full exportable " "signature? (y/N) ")))
@@ -811,14 +788,15 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
                  /* Fixme: see whether there is a revocation in which
                   * case we should allow to sign it again. */
                  if (!node->pkt->pkt.signature->flags.exportable && local)
-                   tty_printf (_
-                               ("\"%s\" was already locally signed by key %s\n"),
-                               user, keystr_from_pk (pk));
+                   tty_fprintf ( fp,
+                       _("\"%s\" was already locally signed by key %s\n"),
+                       user, keystr_from_pk (pk));
                  else
-                   tty_printf (_("\"%s\" was already signed by key %s\n"),
+                   tty_fprintf (fp,
+                                _("\"%s\" was already signed by key %s\n"),
                                user, keystr_from_pk (pk));
 
-                 if (opt.expert
+                 if (opt.expert && !quick
                      && cpr_get_answer_is_yes ("sign_uid.dupe_okay",
                                                _("Do you want to sign it "
                                                  "again anyway? (y/N) ")))
@@ -842,15 +820,15 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
       /* Check whether any uids are left for signing.  */
       if (!count_uids_with_flag (keyblock, NODFLG_MARK_A))
        {
-         tty_printf (_("Nothing to sign with key %s\n"),
+         tty_fprintf (fp, _("Nothing to sign with key %s\n"),
                      keystr_from_pk (pk));
          continue;
        }
 
       /* Ask whether we really should sign these user id(s). */
-      tty_printf ("\n");
-      show_key_with_all_names (keyblock, 1, 0, 1, 0, 0);
-      tty_printf ("\n");
+      tty_fprintf (fp, "\n");
+      show_key_with_all_names (fp, keyblock, 1, 0, 1, 0, 0, 0);
+      tty_fprintf (fp, "\n");
 
       if (primary_pk->expiredate && !selfsig)
        {
@@ -858,11 +836,11 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
 
          if (primary_pk->expiredate <= now)
            {
-             tty_printf (_("This key has expired!"));
+             tty_fprintf (fp, _("This key has expired!"));
 
-             if (opt.expert)
+             if (opt.expert && !quick)
                {
-                 tty_printf ("  ");
+                 tty_fprintf (fp, "  ");
                  if (!cpr_get_answer_is_yes ("sign_uid.expired_okay",
                                              _("Are you sure you still "
                                                "want to sign it? (y/N) ")))
@@ -870,16 +848,16 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
                }
              else
                {
-                 tty_printf (_("  Unable to sign.\n"));
+                 tty_fprintf (fp, _("  Unable to sign.\n"));
                  continue;
                }
            }
          else
            {
-             tty_printf (_("This key is due to expire on %s.\n"),
-                         expirestr_from_pk (primary_pk));
+             tty_fprintf (fp, _("This key is due to expire on %s.\n"),
+                           expirestr_from_pk (primary_pk));
 
-             if (opt.ask_cert_expire)
+             if (opt.ask_cert_expire && !quick)
                {
                  char *answer = cpr_get ("sign_uid.expire",
                                          _("Do you want your signature to "
@@ -907,7 +885,7 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
          the expiration of the pk */
       if (!duration && !selfsig)
        {
-         if (opt.ask_cert_expire)
+         if (opt.ask_cert_expire && !quick)
            duration = ask_expire_interval (1, opt.def_cert_expire);
          else
            duration = parse_expire_string (opt.def_cert_expire);
@@ -922,11 +900,11 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
       if (PGP2 && all_v3 &&
          (pk->version > 3 || force_v4) && primary_pk->version <= 3)
        {
-         tty_printf (_("You may not make an OpenPGP signature on a "
-                       "PGP 2.x key while in --pgp2 mode.\n"));
-         tty_printf (_("This would make the key unusable in PGP 2.x.\n"));
+         tty_fprintf (fp, _("You may not make an OpenPGP signature on a "
+                             "PGP 2.x key while in --pgp2 mode.\n"));
+         tty_fprintf (fp, _("This would make the key unusable in PGP 2.x.\n"));
 
-         if (opt.expert)
+         if (opt.expert && !quick)
            {
              if (!cpr_get_answer_is_yes ("sign_uid.v4_on_v3_okay",
                                          _("Are you sure you still "
@@ -943,32 +921,34 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
        ;
       else
        {
-         if (opt.batch || !opt.ask_cert_level)
+         if (opt.batch || !opt.ask_cert_level || quick)
            class = 0x10 + opt.def_cert_level;
          else
            {
              char *answer;
 
-             tty_printf (_("How carefully have you verified the key you are "
+             tty_fprintf (fp,
+                           _("How carefully have you verified the key you are "
                            "about to sign actually belongs\nto the person "
                            "named above?  If you don't know what to "
                            "answer, enter \"0\".\n"));
-             tty_printf ("\n");
-             tty_printf (_("   (0) I will not answer.%s\n"),
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp, _("   (0) I will not answer.%s\n"),
                          opt.def_cert_level == 0 ? " (default)" : "");
-             tty_printf (_("   (1) I have not checked at all.%s\n"),
+             tty_fprintf (fp, _("   (1) I have not checked at all.%s\n"),
                          opt.def_cert_level == 1 ? " (default)" : "");
-             tty_printf (_("   (2) I have done casual checking.%s\n"),
+             tty_fprintf (fp, _("   (2) I have done casual checking.%s\n"),
                          opt.def_cert_level == 2 ? " (default)" : "");
-             tty_printf (_("   (3) I have done very careful checking.%s\n"),
+             tty_fprintf (fp,
+                           _("   (3) I have done very careful checking.%s\n"),
                          opt.def_cert_level == 3 ? " (default)" : "");
-             tty_printf ("\n");
+             tty_fprintf (fp, "\n");
 
              while (class == 0)
                {
                  answer = cpr_get ("sign_uid.class",
                                     _("Your selection? "
-                                      "(enter `?' for more information): "));
+                                      "(enter '?' for more information): "));
                  if (answer[0] == '\0')
                    class = 0x10 + opt.def_cert_level;  /* Default */
                  else if (ascii_strcasecmp (answer, "0") == 0)
@@ -980,84 +960,90 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
                  else if (ascii_strcasecmp (answer, "3") == 0)
                    class = 0x13;       /* Positive */
                  else
-                   tty_printf (_("Invalid selection.\n"));
+                   tty_fprintf (fp, _("Invalid selection.\n"));
 
                  xfree (answer);
                }
            }
 
-         if (trust)
+         if (trust && !quick)
            trustsig_prompt (&trust_value, &trust_depth, &trust_regexp);
        }
 
-      p = get_user_id_native (sk_keyid);
-      tty_printf (_("Are you sure that you want to sign this key with your\n"
-                   "key \"%s\" (%s)\n"), p, keystr_from_pk (pk));
-      xfree (p);
+      if (!quick)
+        {
+          p = get_user_id_native (sk_keyid);
+          tty_fprintf (fp,
+                   _("Are you sure that you want to sign this key with your\n"
+                     "key \"%s\" (%s)\n"), p, keystr_from_pk (pk));
+          xfree (p);
+        }
 
       if (selfsig)
        {
-         tty_printf ("\n");
-         tty_printf (_("This will be a self-signature.\n"));
+         tty_fprintf (fp, "\n");
+         tty_fprintf (fp, _("This will be a self-signature.\n"));
 
          if (local)
            {
-             tty_printf ("\n");
-             tty_printf (_("WARNING: the signature will not be marked "
-                           "as non-exportable.\n"));
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp, _("WARNING: the signature will not be marked "
+                                 "as non-exportable.\n"));
            }
 
          if (nonrevocable)
            {
-             tty_printf ("\n");
-             tty_printf (_("WARNING: the signature will not be marked "
-                           "as non-revocable.\n"));
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp, _("WARNING: the signature will not be marked "
+                                 "as non-revocable.\n"));
            }
        }
       else
        {
          if (local)
            {
-             tty_printf ("\n");
-             tty_printf 
-                (_("The signature will be marked as non-exportable.\n"));
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp,
+                 _("The signature will be marked as non-exportable.\n"));
            }
 
          if (nonrevocable)
            {
-             tty_printf ("\n");
-             tty_printf 
-                (_("The signature will be marked as non-revocable.\n"));
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp,
+                 _("The signature will be marked as non-revocable.\n"));
            }
 
          switch (class)
            {
            case 0x11:
-             tty_printf ("\n");
-             tty_printf (_("I have not checked this key at all.\n"));
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp, _("I have not checked this key at all.\n"));
              break;
 
            case 0x12:
-             tty_printf ("\n");
-             tty_printf (_("I have checked this key casually.\n"));
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp, _("I have checked this key casually.\n"));
              break;
 
            case 0x13:
-             tty_printf ("\n");
-             tty_printf (_("I have checked this key very carefully.\n"));
+             tty_fprintf (fp, "\n");
+             tty_fprintf (fp, _("I have checked this key very carefully.\n"));
              break;
            }
        }
 
-      tty_printf ("\n");
+      tty_fprintf (fp, "\n");
 
       if (opt.batch && opt.answer_yes)
        ;
+      else if (quick)
+        ;
       else if (!cpr_get_answer_is_yes ("sign_uid.okay",
                                       _("Really sign? (y/N) ")))
        continue;
 
-      /* Now we can sign the user ids */
+      /* Now we can sign the user ids */
     reloop:  /* (Must use this, because we are modifing the list.)  */
       primary_pk = NULL;
       for (node = keyblock; node; node = node->next)
@@ -1091,7 +1077,8 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
                                         NULL,
                                         pk,
                                         0x13, 0, force_v4 ? 4 : 0, 0, 0,
-                                        keygen_add_std_prefs, primary_pk);
+                                        keygen_add_std_prefs, primary_pk,
+                                         NULL);
              else
                rc = make_keysig_packet (&sig, primary_pk,
                                         node->pkt->pkt.user_id,
@@ -1099,7 +1086,8 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
                                         pk,
                                         class, 0, force_v4 ? 4 : 0,
                                         timestamp, duration,
-                                        sign_mk_attrib, &attrib);
+                                        sign_mk_attrib, &attrib,
+                                         NULL);
              if (rc)
                {
                  log_error (_("signing failed: %s\n"), g10_errstr (rc));
@@ -1123,52 +1111,70 @@ sign_uids (KBNODE keyblock, strlist_t locusr, int *ret_modified,
          delete_kbnode (node);
     } /* End loop over signators.  */
 
-leave:
+ leave:
   release_sk_list (sk_list);
-  if (pk)
-    free_public_key (pk);
   return rc;
 }
 
 
 /*
- * Change the passphrase of the primary and all secondary keys.
- * We use only one passphrase for all keys.
+ * Change the passphrase of the primary and all secondary keys.  Note
+ * that it is common to use only one passphrase for the primary and
+ * all subkeys.  However, this is now (since GnuPG 2.1) all up to the
+ * gpg-agent.  Returns 0 on success or an error code.
  */
-static int
-change_passphrase (KBNODE keyblock, int *r_err)
+static gpg_error_t
+change_passphrase (ctrl_t ctrl, kbnode_t keyblock)
 {
-  int rc = 0;
-  int changed = 0;
-  KBNODE node;
-  PKT_secret_key *sk;
-  char *passphrase = NULL;
-  int no_primary_secrets = 0;
+  gpg_error_t err;
+  kbnode_t node;
+  PKT_public_key *pk;
   int any;
+  u32 keyid[2], subid[2];
+  char *hexgrip = NULL;
+  char *cache_nonce = NULL;
+  char *passwd_nonce = NULL;
 
-  node = find_kbnode (keyblock, PKT_SECRET_KEY);
+  node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
   if (!node)
     {
-      log_error ("Oops; secret key not found anymore!\n");
+      log_error ("Oops; public key missing!\n");
+      err = gpg_error (GPG_ERR_INTERNAL);
       goto leave;
     }
-  sk = node->pkt->pkt.secret_key;
+  pk = node->pkt->pkt.public_key;
+  keyid_from_pk (pk, keyid);
 
+  /* Check whether it is likely that we will be able to change the
+     passphrase for any subkey.  */
   for (any = 0, node = keyblock; node; node = node->next)
     {
-      if (node->pkt->pkttype == PKT_SECRET_KEY
-         || node->pkt->pkttype == PKT_SECRET_SUBKEY)
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY
+         || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
        {
-         PKT_secret_key *tmpsk = node->pkt->pkt.secret_key;
-         if (!(tmpsk->is_protected
-               && (tmpsk->protect.s2k.mode == 1001
-                   || tmpsk->protect.s2k.mode == 1002)))
-           {
-             any = 1;
-             break;
-           }
+          char *serialno;
+
+          pk = node->pkt->pkt.public_key;
+          keyid_from_pk (pk, subid);
+
+          xfree (hexgrip);
+          err = hexkeygrip_from_pk (pk, &hexgrip);
+          if (err)
+            goto leave;
+          err = agent_get_keyinfo (ctrl, hexgrip, &serialno);
+          if (!err && serialno)
+            ; /* Key on card.  */
+          else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
+            ; /* Maybe stub key. */
+          else if (!err)
+            any = 1; /* Key is known.  */
+          else
+            log_error ("key %s: error getting keyinfo from agent: %s\n",
+                       keystr_with_sub (keyid, subid), gpg_strerror (err));
+          xfree (serialno);
        }
     }
+  err = 0;
   if (!any)
     {
       tty_printf (_("Key has only stub or on-card key items - "
@@ -1176,163 +1182,47 @@ change_passphrase (KBNODE keyblock, int *r_err)
       goto leave;
     }
 
-  /* See how to handle this key.  */
-  switch (is_secret_key_protected (sk))
-    {
-    case -1:
-      rc = G10ERR_PUBKEY_ALGO;
-      break;
-    case 0:
-      tty_printf (_("This key is not protected.\n"));
-      break;
-    default:
-      if (sk->protect.s2k.mode == 1001)
-       {
-         tty_printf (_("Secret parts of key are not available.\n"));
-         no_primary_secrets = 1;
-       }
-      else if (sk->protect.s2k.mode == 1002)
-       {
-         tty_printf (_("Secret parts of key are stored on-card.\n"));
-         no_primary_secrets = 1;
-       }
-      else
-       {
-         u32 keyid[2];
-
-         tty_printf (_("Key is protected.\n"));
-
-         /* Clear the passphrase cache so that the user is required
-            to enter the old passphrase.  */
-         keyid_from_sk (sk, keyid);
-         passphrase_clear_cache (keyid, NULL, 0);
-
-         /* rc = check_secret_key( sk, 0 ); */
-         /* if( !rc ) */
-         /*     passphrase = get_last_passphrase(); */
-       }
-      break;
-    }
-
-  /* Unprotect all subkeys (use the supplied passphrase or ask) */
-  for (node = keyblock; !rc && node; node = node->next)
-    {
-      if (node->pkt->pkttype == PKT_SECRET_SUBKEY)
-       {
-         PKT_secret_key *subsk = node->pkt->pkt.secret_key;
-         if (!(subsk->is_protected
-               && (subsk->protect.s2k.mode == 1001
-                   || subsk->protect.s2k.mode == 1002)))
-           {
-             set_next_passphrase (passphrase);
-             /* rc = check_secret_key( subsk, 0 ); */
-             /* if( !rc && !passphrase ) */
-             /*     passphrase = get_last_passphrase(); */
-           }
-       }
-    }
-
-  if (rc)
-    tty_printf (_("Can't edit this key: %s\n"), g10_errstr (rc));
-  else
+  /* Change the passphrase for all keys.  */
+  for (any = 0, node = keyblock; node; node = node->next)
     {
-      DEK *dek = NULL;
-      STRING2KEY *s2k = xmalloc_secure (sizeof *s2k);
-      const char *errtext = NULL;
-
-      tty_printf (_("Enter the new passphrase for this secret key.\n\n"));
-
-      set_next_passphrase (NULL);
-      for (;;)
-       {
-         int canceled;
-
-         s2k->mode = opt.s2k_mode;
-         s2k->hash_algo = S2K_DIGEST_ALGO;
-         dek = passphrase_to_dek (NULL, 0, opt.s2k_cipher_algo,
-                                  s2k, 2, errtext, &canceled);
-         if (!dek && canceled)
-           {
-             rc = GPG_ERR_CANCELED;
-             break;
-           }
-         else if (!dek)
-           {
-             errtext = N_("passphrase not correctly repeated; try again");
-             tty_printf ("%s.\n", _(errtext));
-           }
-         else if (!dek->keylen)
-           {
-             rc = 0;
-             tty_printf (_("You don't want a passphrase -"
-                           " this is probably a *bad* idea!\n\n"));
-             if (cpr_get_answer_is_yes 
-                  ("change_passwd.empty.okay",
-                   _("Do you really want to do this? (y/N) ")))
-               {
-                 changed++;
-                 break;
-               }
-           }
-         else
-           {                   /* okay */
-             rc = 0;
-             if (!no_primary_secrets)
-               {
-                 sk->protect.algo = dek->algo;
-                 sk->protect.s2k = *s2k;
-#warning fixme
-                 rc = 0;
-                 /* rc = protect_secret_key( sk, dek ); */
-               }
-             for (node = keyblock; !rc && node; node = node->next)
-               {
-                 if (node->pkt->pkttype == PKT_SECRET_SUBKEY)
-                   {
-                     PKT_secret_key *subsk = node->pkt->pkt.secret_key;
-                     if (!(subsk->is_protected
-                           && (subsk->protect.s2k.mode == 1001
-                               || subsk->protect.s2k.mode == 1002)))
-                       {
-                         subsk->protect.algo = dek->algo;
-                         subsk->protect.s2k = *s2k;
-#warning fixme
-                         rc = 0;
-                         /* rc = protect_secret_key( subsk, dek ); */
-                       }
-                   }
-               }
-             if (rc)
-               log_error ("protect_secret_key failed: %s\n",
-                          g10_errstr (rc));
-             else
-               {
-                 u32 keyid[2];
-
-                 /* Clear the cahce again so that the user is
-                    required to enter the new passphrase at the
-                    next operation.  */
-                 keyid_from_sk (sk, keyid);
-                 passphrase_clear_cache (keyid, NULL, 0);
-
-                 changed++;
-               }
-             break;
-           }
-       }
-      xfree (s2k);
-      xfree (dek);
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY
+         || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+        {
+          char *desc;
+
+          pk = node->pkt->pkt.public_key;
+          keyid_from_pk (pk, subid);
+
+          xfree (hexgrip);
+          err = hexkeygrip_from_pk (pk, &hexgrip);
+          if (err)
+            goto leave;
+
+          desc = gpg_format_keydesc (pk, FORMAT_KEYDESC_NORMAL, 1);
+          err = agent_passwd (ctrl, hexgrip, desc, &cache_nonce, &passwd_nonce);
+          xfree (desc);
+
+          if (err)
+            log_log ((gpg_err_code (err) == GPG_ERR_CANCELED
+                      || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
+                     ? JNLIB_LOG_INFO : JNLIB_LOG_ERROR,
+                     _("key %s: error changing passphrase: %s\n"),
+                       keystr_with_sub (keyid, subid),
+                       gpg_strerror (err));
+          if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
+            break;
+        }
     }
 
-leave:
-  xfree (passphrase);
-  set_next_passphrase (NULL);
-  if (r_err)
-    *r_err = rc;
-  return changed && !rc;
+ leave:
+  xfree (hexgrip);
+  xfree (cache_nonce);
+  xfree (passwd_nonce);
+  return err;
 }
 
 
+\f
 /*
  * There are some keys out (due to a bug in gnupg), where the sequence
  * of the packets is wrong.  This function fixes that.
@@ -1380,6 +1270,7 @@ fix_keyblock (KBNODE keyblock)
   return fixed;
 }
 
+
 static int
 parse_sign_type (const char *str, int *localsig, int *nonrevokesig,
                 int *trustsig)
@@ -1436,7 +1327,11 @@ enum cmdids
   cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
   cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
   cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
-  cmdEXPIRE, cmdBACKSIGN, cmdENABLEKEY, cmdDISABLEKEY, cmdSHOWPREF,
+  cmdEXPIRE, cmdBACKSIGN,
+#ifndef NO_TRUST_MODELS
+  cmdENABLEKEY, cmdDISABLEKEY,
+#endif /*!NO_TRUST_MODELS*/
+  cmdSHOWPREF,
   cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST,
   cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD, cmdCHECKBKUPKEY,
   cmdCLEAN, cmdMINIMIZE, cmdNOP
@@ -1515,7 +1410,9 @@ static struct
   { "passwd", cmdPASSWD, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
     N_("change the passphrase")},
   { "password", cmdPASSWD, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
+#ifndef NO_TRUST_MODELS
   { "trust", cmdTRUST, KEYEDIT_NOT_SK, N_("change the ownertrust")},
+#endif /*!NO_TRUST_MODELS*/
   { "revsig", cmdREVSIG, KEYEDIT_NOT_SK,
     N_("revoke signatures on the selected user IDs")},
   { "revuid", cmdREVUID, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
@@ -1523,8 +1420,10 @@ static struct
   { "revphoto", cmdREVUID, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
   { "revkey", cmdREVKEY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
     N_("revoke key or selected subkeys")},
+#ifndef NO_TRUST_MODELS
   { "enable", cmdENABLEKEY, KEYEDIT_NOT_SK, N_("enable key")},
   { "disable", cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key")},
+#endif /*!NO_TRUST_MODELS*/
   { "showphoto", cmdSHOWPHOTO, 0, N_("show selected photo IDs")},
   { "clean", cmdCLEAN, KEYEDIT_NOT_SK,
     N_("compact unusable user IDs and remove unusable signatures from key")},
@@ -1587,21 +1486,19 @@ keyedit_completion (const char *text, int start, int end)
 
 
 \f
+/* Main function of the menu driven key editor.  */
 void
-keyedit_menu (const char *username, strlist_t locusr,
+keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
              strlist_t commands, int quiet, int seckey_check)
 {
   enum cmdids cmd = 0;
-  int rc = 0;
+  gpg_error_t err = 0;
   KBNODE keyblock = NULL;
   KEYDB_HANDLE kdbhd = NULL;
-  KBNODE sec_keyblock = NULL;
-  KEYDB_HANDLE sec_kdbhd = NULL;
-  KBNODE cur_keyblock;
+  int have_seckey = 0;
   char *answer = NULL;
   int redisplay = 1;
   int modified = 0;
-  int sec_modified = 0;
   int toggle;
   int have_commands = !!commands;
 
@@ -1627,9 +1524,12 @@ keyedit_menu (const char *username, strlist_t locusr,
 #endif
 
   /* Get the public key */
-  rc = get_pubkey_byname (NULL, NULL, username, &keyblock, &kdbhd, 1, 1);
-  if (rc)
-    goto leave;
+  err = get_pubkey_byname (ctrl, NULL, NULL, username, &keyblock, &kdbhd, 1, 1);
+  if (err)
+    {
+      log_error (_("key \"%s\" not found: %s\n"), username, gpg_strerror (err));
+      goto leave;
+    }
   if (fix_keyblock (keyblock))
     modified++;
   if (collapse_uids (&keyblock))
@@ -1640,53 +1540,19 @@ keyedit_menu (const char *username, strlist_t locusr,
   if (modified)
     merge_keys_and_selfsig (keyblock);
 
+  /* See whether we have a matching secret key.  */
   if (seckey_check)
-    { 
-      /* See whether we have a matching secret key.  */
-      PKT_public_key *pk = keyblock->pkt->pkt.public_key;
-
-      sec_kdbhd = keydb_new (1);
-      {
-       byte afp[MAX_FINGERPRINT_LEN];
-       size_t an;
-
-       fingerprint_from_pk (pk, afp, &an);
-       while (an < MAX_FINGERPRINT_LEN)
-         afp[an++] = 0;
-       rc = keydb_search_fpr (sec_kdbhd, afp);
-      }
-      if (!rc)
-       {
-         rc = keydb_get_keyblock (sec_kdbhd, &sec_keyblock);
-         if (rc)
-           {
-             log_error (_("error reading secret keyblock \"%s\": %s\n"),
-                        username, g10_errstr (rc));
-           }
-         else
-           {
-             merge_keys_and_selfsig (sec_keyblock);
-             if (fix_keyblock (sec_keyblock))
-               sec_modified++;
-           }
-       }
-
-      if (rc)
-       {
-         sec_keyblock = NULL;
-         keydb_release (sec_kdbhd);
-         sec_kdbhd = NULL;
-         rc = 0;
-       }
-
-      if (sec_keyblock && !quiet)
+    {
+      have_seckey = !agent_probe_any_secret_key (ctrl, keyblock);
+      if (have_seckey && !quiet)
        tty_printf (_("Secret key is available.\n"));
     }
 
   toggle = 0;
-  cur_keyblock = keyblock;
+
+  /* Main command loop.  */
   for (;;)
-    {                          /* main loop */
+    {
       int i, arg_number, photo;
       const char *arg_string = "";
       char *p;
@@ -1696,7 +1562,7 @@ keyedit_menu (const char *username, strlist_t locusr,
 
       if (redisplay && !quiet)
        {
-         show_key_with_all_names (cur_keyblock, 0, 1, 0, 1, 0);
+         show_key_with_all_names (NULL, keyblock, 0, 1, 0, 1, 0, 0);
          tty_printf ("\n");
          redisplay = 0;
        }
@@ -1722,7 +1588,7 @@ keyedit_menu (const char *username, strlist_t locusr,
 #ifdef HAVE_LIBREADLINE
              tty_enable_completion (keyedit_completion);
 #endif
-             answer = cpr_get_no_help ("keyedit.prompt", "gpg> ");
+             answer = cpr_get_no_help ("keyedit.prompt", GPG_NAME "> ");
              cpr_kill_prompt ();
              tty_disable_completion ();
            }
@@ -1730,8 +1596,8 @@ keyedit_menu (const char *username, strlist_t locusr,
        }
       while (*answer == '#');
 
-      arg_number = 0; /* Yes, here is the init which egcc complains about */
-      photo = 0;      /* This too */
+      arg_number = 0; /* Here is the init which egcc complains about.  */
+      photo = 0;      /* Same here. */
       if (!*answer)
        cmd = cmdLIST;
       else if (*answer == CONTROL_D)
@@ -1760,8 +1626,7 @@ keyedit_menu (const char *username, strlist_t locusr,
                  size_t a = strlen (answer);
                  if (a >= l)
                    {
-                     if (ascii_strcasecmp (&answer[a - l], cmds[i].name) ==
-                         0)
+                     if (!ascii_strcasecmp (&answer[a - l], cmds[i].name))
                        {
                          answer[a - l] = '\0';
                          break;
@@ -1771,14 +1636,13 @@ keyedit_menu (const char *username, strlist_t locusr,
              else if (!ascii_strcasecmp (answer, cmds[i].name))
                break;
            }
-         if ((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock)
+         if ((cmds[i].flags & KEYEDIT_NEED_SK) && !have_seckey)
            {
              tty_printf (_("Need the secret key to do this.\n"));
              cmd = cmdNOP;
            }
-         else if (((cmds[i].flags & KEYEDIT_NOT_SK) && sec_keyblock
-                   && toggle)
-                  || ((cmds[i].flags & KEYEDIT_ONLY_SK) && sec_keyblock
+         else if (((cmds[i].flags & KEYEDIT_NOT_SK) && have_seckey && toggle)
+                  || ((cmds[i].flags & KEYEDIT_ONLY_SK) && have_seckey
                       && !toggle))
            {
              tty_printf (_("Please use the command \"toggle\" first.\n"));
@@ -1787,26 +1651,27 @@ keyedit_menu (const char *username, strlist_t locusr,
          else
            cmd = cmds[i].id;
        }
+
+      /* Dispatch the command.  */
       switch (cmd)
        {
        case cmdHELP:
          for (i = 0; cmds[i].name; i++)
            {
-             if ((cmds[i].flags & KEYEDIT_NEED_SK) && !sec_keyblock)
-               ;               /* skip if we do not have the secret key */
+             if ((cmds[i].flags & KEYEDIT_NEED_SK) && !have_seckey)
+               ; /* Skip those item if we do not have the secret key.  */
              else if (cmds[i].desc)
                tty_printf ("%-11s %s\n", cmds[i].name, _(cmds[i].desc));
            }
 
          tty_printf ("\n");
          tty_printf
-            (_("* The `sign' command may be prefixed with an `l' for local "
+            (_("* The 'sign' command may be prefixed with an 'l' for local "
                "signatures (lsign),\n"
-               "  a `t' for trust signatures (tsign), an `nr' for "
+               "  a 't' for trust signatures (tsign), an 'nr' for "
                "non-revocable signatures\n"
                "  (nrsign), or any combination thereof (ltsign, "
                "tnrsign, etc.).\n"));
-
          break;
 
        case cmdLIST:
@@ -1819,13 +1684,13 @@ keyedit_menu (const char *username, strlist_t locusr,
 
        case cmdSELUID:
          if (strlen (arg_string) == NAMEHASH_LEN * 2)
-           redisplay = menu_select_uid_namehash (cur_keyblock, arg_string);
+           redisplay = menu_select_uid_namehash (keyblock, arg_string);
          else
            {
              if (*arg_string == '*'
                  && (!arg_string[1] || spacep (arg_string + 1)))
                arg_number = -1;        /* Select all. */
-             redisplay = menu_select_uid (cur_keyblock, arg_number);
+             redisplay = menu_select_uid (keyblock, arg_number);
            }
          break;
 
@@ -1834,23 +1699,20 @@ keyedit_menu (const char *username, strlist_t locusr,
            if (*arg_string == '*'
                && (!arg_string[1] || spacep (arg_string + 1)))
              arg_number = -1;  /* Select all. */
-           if (menu_select_key (cur_keyblock, arg_number))
+           if (menu_select_key (keyblock, arg_number))
              redisplay = 1;
          }
          break;
 
        case cmdCHECK:
-         /* we can only do this with the public key becuase the
-          * check functions can't cope with secret keys and it
-          * is questionable whether this would make sense at all */
          check_all_keysigs (keyblock, count_selected_uids (keyblock));
          break;
 
-       case cmdSIGN:           /* sign (only the public key) */
+       case cmdSIGN:
          {
            int localsig = 0, nonrevokesig = 0, trustsig = 0, interactive = 0;
 
-           if (pk->is_revoked)
+           if (pk->flags.revoked)
              {
                tty_printf (_("Key is revoked."));
 
@@ -1888,43 +1750,43 @@ keyedit_menu (const char *username, strlist_t locusr,
            if (!parse_sign_type
                (answer, &localsig, &nonrevokesig, &trustsig))
              {
-               tty_printf (_("Unknown signature type `%s'\n"), answer);
+               tty_printf (_("Unknown signature type '%s'\n"), answer);
                break;
              }
 
-           sign_uids (keyblock, locusr, &modified,
-                      localsig, nonrevokesig, trustsig, interactive);
+           sign_uids (NULL, keyblock, locusr, &modified,
+                      localsig, nonrevokesig, trustsig, interactive, 0);
          }
          break;
 
        case cmdDEBUG:
-         dump_kbnode (cur_keyblock);
+         dump_kbnode (keyblock);
          break;
 
        case cmdTOGGLE:
+          /* The toggle command is a leftover from old gpg versions
+             where we worked with a secret and a public keyring.  It
+             is not necessary anymore but we keep this command for the
+             sake of scripts using it.  */
          toggle = !toggle;
-         cur_keyblock = toggle ? sec_keyblock : keyblock;
          redisplay = 1;
          break;
 
        case cmdADDPHOTO:
          if (RFC2440 || RFC1991 || PGP2)
            {
-             tty_printf (_
-                         ("This command is not allowed while in %s mode.\n"),
+             tty_printf (_("This command is not allowed while in %s mode.\n"),
                          compliance_option_string ());
              break;
            }
          photo = 1;
          /* fall through */
-
        case cmdADDUID:
-         if (menu_adduid (keyblock, sec_keyblock, photo, arg_string))
+         if (menu_adduid (keyblock, photo, arg_string))
            {
              update_trust = 1;
              redisplay = 1;
-             sec_modified = modified = 1;
-             merge_keys_and_selfsig (sec_keyblock);
+             modified = 1;
              merge_keys_and_selfsig (keyblock);
            }
          break;
@@ -1942,11 +1804,9 @@ keyedit_menu (const char *username, strlist_t locusr,
                       n1 > 1 ? _("Really remove all selected user IDs? (y/N) ")
                       :        _("Really remove this user ID? (y/N) ")))
              {
-               menu_deluid (keyblock, sec_keyblock);
+               menu_deluid (keyblock);
                redisplay = 1;
                modified = 1;
-               if (sec_keyblock)
-                 sec_modified = 1;
              }
          }
          break;
@@ -1959,30 +1819,28 @@ keyedit_menu (const char *username, strlist_t locusr,
              tty_printf (_("You must select at least one user ID.\n"));
            else if (menu_delsig (keyblock))
              {
-               /* no redisplay here, because it may scroll away some
-                * status output of delsig */
+               /* No redisplay here, because it may scroll away some
+                * of the status output of this command.  */
                modified = 1;
              }
          }
          break;
 
        case cmdADDKEY:
-         if (!generate_subkeypair (keyblock))
+         if (!generate_subkeypair (ctrl, keyblock))
            {
              redisplay = 1;
-             sec_modified = modified = 1;
-             merge_keys_and_selfsig (sec_keyblock);
+             modified = 1;
              merge_keys_and_selfsig (keyblock);
            }
          break;
 
 #ifdef ENABLE_CARD_SUPPORT
        case cmdADDCARDKEY:
-         if (card_generate_subkey (keyblock, sec_keyblock))
+         if (!card_generate_subkey (keyblock))
            {
              redisplay = 1;
-             sec_modified = modified = 1;
-             merge_keys_and_selfsig (sec_keyblock);
+             modified = 1;
              merge_keys_and_selfsig (keyblock);
            }
          break;
@@ -1990,20 +1848,20 @@ keyedit_menu (const char *username, strlist_t locusr,
        case cmdKEYTOCARD:
          {
            KBNODE node = NULL;
-           switch (count_selected_keys (sec_keyblock))
+           switch (count_selected_keys (keyblock))
              {
              case 0:
-               if (cpr_get_answer_is_yes 
+               if (cpr_get_answer_is_yes
                     ("keyedit.keytocard.use_primary",
                      /* TRANSLATORS: Please take care: This is about
                         moving the key and not about removing it.  */
                      _("Really move the primary key? (y/N) ")))
-                 node = sec_keyblock;
+                 node = keyblock;
                break;
              case 1:
-               for (node = sec_keyblock; node; node = node->next)
+               for (node = keyblock; node; node = node->next)
                  {
-                   if (node->pkt->pkttype == PKT_SECRET_SUBKEY
+                   if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
                        && node->flag & NODFLG_SELKEY)
                      break;
                  }
@@ -2014,11 +1872,12 @@ keyedit_menu (const char *username, strlist_t locusr,
              }
            if (node)
              {
-               PKT_public_key *xxpk = find_pk_from_sknode (keyblock, node);
+               PKT_public_key *xxpk = node->pkt->pkt.public_key;
                if (card_store_subkey (node, xxpk ? xxpk->pubkey_usage : 0))
                  {
                    redisplay = 1;
-                   sec_modified = 1;
+                   /* Only the secret key has been modified; thus
+                       there is no need to set the modified flag.  */
                  }
              }
          }
@@ -2026,6 +1885,7 @@ keyedit_menu (const char *username, strlist_t locusr,
 
        case cmdBKUPTOCARD:
        case cmdCHECKBKUPKEY:
+          log_debug ("FIXME: This needs to be changed\n");
          {
            /* Ask for a filename, check whether this is really a
               backup key as generated by the card generation, parse
@@ -2052,7 +1912,7 @@ keyedit_menu (const char *username, strlist_t locusr,
              }
            if (!a)
              {
-               tty_printf (_("Can't open `%s': %s\n"),
+               tty_printf (_("Can't open '%s': %s\n"),
                            fname, strerror (errno));
                break;
              }
@@ -2060,17 +1920,16 @@ keyedit_menu (const char *username, strlist_t locusr,
            /* Parse and check that file.  */
            pkt = xmalloc (sizeof *pkt);
            init_packet (pkt);
-           rc = parse_packet (a, pkt);
+           err = parse_packet (a, pkt);
            iobuf_close (a);
-           iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0,
-                        (char *) fname);
-           if (!rc && pkt->pkttype != PKT_SECRET_KEY
+           iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char *) fname);
+           if (!err && pkt->pkttype != PKT_SECRET_KEY
                && pkt->pkttype != PKT_SECRET_SUBKEY)
-             rc = G10ERR_NO_SECKEY;
-           if (rc)
+             err = G10ERR_NO_SECKEY;
+           if (err)
              {
-               tty_printf (_("Error reading backup key from `%s': %s\n"),
-                           fname, g10_errstr (rc));
+               tty_printf (_("Error reading backup key from '%s': %s\n"),
+                           fname, g10_errstr (err));
                free_packet (pkt);
                xfree (pkt);
                break;
@@ -2079,32 +1938,32 @@ keyedit_menu (const char *username, strlist_t locusr,
 
            if (cmd == cmdCHECKBKUPKEY)
              {
-               PKT_secret_key *sk = node->pkt->pkt.secret_key;
-               switch (is_secret_key_protected (sk))
-                 {
-                 case 0:       /* Not protected. */
-                   tty_printf (_("This key is not protected.\n"));
-                   break;
-                 case -1:
-                   log_error (_("unknown key protection algorithm\n"));
-                   break;
-                 default:
-                   if (sk->protect.s2k.mode == 1001)
-                     tty_printf (_("Secret parts of key"
-                                   " are not available.\n"));
-                   if (sk->protect.s2k.mode == 1002)
-                     tty_printf (_("Secret parts of key"
-                                   " are stored on-card.\n"));
+               /* PKT_public_key *sk = node->pkt->pkt.secret_key; */
+               /* switch (is_secret_key_protected (sk)) */
+               /*   { */
+               /*   case 0:    /\* Not protected. *\/ */
+               /*     tty_printf (_("This key is not protected.\n")); */
+               /*     break; */
+               /*   case -1: */
+               /*     log_error (_("unknown key protection algorithm\n")); */
+               /*     break; */
+               /*   default: */
+               /*     if (sk->protect.s2k.mode == 1001) */
+               /*       tty_printf (_("Secret parts of key" */
+               /*                  " are not available.\n")); */
+               /*     if (sk->protect.s2k.mode == 1002) */
+               /*       tty_printf (_("Secret parts of key" */
+               /*                  " are stored on-card.\n")); */
                    /* else */
                    /*   check_secret_key (sk, 0); */
-                 }
+                 /* } */
              }
            else                /* Store it.  */
              {
                if (card_store_subkey (node, 0))
                  {
                    redisplay = 1;
-                   sec_modified = 1;
+                   /* FIXME:sec_modified = 1;*/
                  }
              }
            release_kbnode (node);
@@ -2127,11 +1986,9 @@ keyedit_menu (const char *username, strlist_t locusr,
              ;
            else
              {
-               menu_delkey (keyblock, sec_keyblock);
+               menu_delkey (keyblock);
                redisplay = 1;
                modified = 1;
-               if (sec_keyblock)
-                 sec_modified = 1;
              }
          }
          break;
@@ -2142,11 +1999,10 @@ keyedit_menu (const char *username, strlist_t locusr,
 
            if (ascii_strcasecmp (arg_string, "sensitive") == 0)
              sensitive = 1;
-           if (menu_addrevoker (keyblock, sec_keyblock, sensitive))
+           if (menu_addrevoker (ctrl, keyblock, sensitive))
              {
                redisplay = 1;
-               sec_modified = modified = 1;
-               merge_keys_and_selfsig (sec_keyblock);
+               modified = 1;
                merge_keys_and_selfsig (keyblock);
              }
          }
@@ -2158,12 +2014,12 @@ keyedit_menu (const char *username, strlist_t locusr,
 
            if (!(n1 = count_selected_uids (keyblock)))
              tty_printf (_("You must select at least one user ID.\n"));
-           else if (cpr_get_answer_is_yes 
+           else if (cpr_get_answer_is_yes
                      ("keyedit.revoke.uid.okay",
                       n1 > 1 ? _("Really revoke all selected user IDs? (y/N) ")
                      :        _("Really revoke this user ID? (y/N) ")))
              {
-               if (menu_revuid (keyblock, sec_keyblock))
+               if (menu_revuid (keyblock))
                  {
                    modified = 1;
                    redisplay = 1;
@@ -2182,7 +2038,7 @@ keyedit_menu (const char *username, strlist_t locusr,
                                           _("Do you really want to revoke"
                                             " the entire key? (y/N) ")))
                  {
-                   if (menu_revkey (keyblock, sec_keyblock))
+                   if (menu_revkey (keyblock))
                      modified = 1;
 
                    redisplay = 1;
@@ -2195,7 +2051,7 @@ keyedit_menu (const char *username, strlist_t locusr,
                                            : _("Do you really want to revoke"
                                                " this subkey? (y/N) ")))
              {
-               if (menu_revsubkey (keyblock, sec_keyblock))
+               if (menu_revsubkey (keyblock))
                  modified = 1;
 
                redisplay = 1;
@@ -2207,27 +2063,24 @@ keyedit_menu (const char *username, strlist_t locusr,
          break;
 
        case cmdEXPIRE:
-         if (menu_expire (keyblock, sec_keyblock))
+         if (menu_expire (keyblock))
            {
-             merge_keys_and_selfsig (sec_keyblock);
              merge_keys_and_selfsig (keyblock);
-             sec_modified = 1;
              modified = 1;
              redisplay = 1;
            }
          break;
 
        case cmdBACKSIGN:
-         if (menu_backsign (keyblock, sec_keyblock))
+         if (menu_backsign (keyblock))
            {
-             sec_modified = 1;
              modified = 1;
              redisplay = 1;
            }
          break;
 
        case cmdPRIMARY:
-         if (menu_set_primary_uid (keyblock, sec_keyblock))
+         if (menu_set_primary_uid (keyblock))
            {
              merge_keys_and_selfsig (keyblock);
              modified = 1;
@@ -2236,10 +2089,10 @@ keyedit_menu (const char *username, strlist_t locusr,
          break;
 
        case cmdPASSWD:
-         if (change_passphrase (sec_keyblock, NULL))
-           sec_modified = 1;
+         change_passphrase (ctrl, keyblock);
          break;
 
+#ifndef NO_TRUST_MODELS
        case cmdTRUST:
          if (opt.trust_model == TM_EXTERNAL)
            {
@@ -2248,7 +2101,7 @@ keyedit_menu (const char *username, strlist_t locusr,
              break;
            }
 
-         show_key_with_all_names (keyblock, 0, 0, 0, 1, 0);
+         show_key_with_all_names (NULL, keyblock, 0, 0, 0, 1, 0, 0);
          tty_printf ("\n");
          if (edit_ownertrust (find_kbnode (keyblock,
                                            PKT_PUBLIC_KEY)->pkt->pkt.
@@ -2261,12 +2114,13 @@ keyedit_menu (const char *username, strlist_t locusr,
              update_trust = 1;
            }
          break;
+#endif /*!NO_TRUST_MODELS*/
 
        case cmdPREF:
          {
            int count = count_selected_uids (keyblock);
            assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
-           show_names (keyblock, keyblock->pkt->pkt.public_key,
+           show_names (NULL, keyblock, keyblock->pkt->pkt.public_key,
                        count ? NODFLG_SELUID : 0, 1);
          }
          break;
@@ -2275,7 +2129,7 @@ keyedit_menu (const char *username, strlist_t locusr,
          {
            int count = count_selected_uids (keyblock);
            assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
-           show_names (keyblock, keyblock->pkt->pkt.public_key,
+           show_names (NULL, keyblock, keyblock->pkt->pkt.public_key,
                        count ? NODFLG_SELUID : 0, 2);
          }
          break;
@@ -2298,7 +2152,7 @@ keyedit_menu (const char *username, strlist_t locusr,
                    " for the selected user IDs? (y/N) ")
                  : _("Really update the preferences? (y/N) ")))
              {
-               if (menu_set_preferences (keyblock, sec_keyblock))
+               if (menu_set_preferences (keyblock))
                  {
                    merge_keys_and_selfsig (keyblock);
                    modified = 1;
@@ -2310,7 +2164,7 @@ keyedit_menu (const char *username, strlist_t locusr,
 
        case cmdPREFKS:
          if (menu_set_keyserver_url (*arg_string ? arg_string : NULL,
-                                     keyblock, sec_keyblock))
+                                     keyblock))
            {
              merge_keys_and_selfsig (keyblock);
              modified = 1;
@@ -2320,7 +2174,7 @@ keyedit_menu (const char *username, strlist_t locusr,
 
        case cmdNOTATION:
          if (menu_set_notation (*arg_string ? arg_string : NULL,
-                                keyblock, sec_keyblock))
+                                keyblock))
            {
              merge_keys_and_selfsig (keyblock);
              modified = 1;
@@ -2339,6 +2193,7 @@ keyedit_menu (const char *username, strlist_t locusr,
            }
          break;
 
+#ifndef NO_TRUST_MODELS
        case cmdENABLEKEY:
        case cmdDISABLEKEY:
          if (enable_disable_key (keyblock, cmd == cmdDISABLEKEY))
@@ -2347,6 +2202,7 @@ keyedit_menu (const char *username, strlist_t locusr,
              modified = 1;
            }
          break;
+#endif /*!NO_TRUST_MODELS*/
 
        case cmdSHOWPHOTO:
          menu_showphoto (keyblock);
@@ -2365,7 +2221,7 @@ keyedit_menu (const char *username, strlist_t locusr,
        case cmdQUIT:
          if (have_commands)
            goto leave;
-         if (!modified && !sec_modified)
+         if (!modified)
            goto leave;
          if (!cpr_get_answer_is_yes ("keyedit.save.okay",
                                      _("Save changes? (y/N) ")))
@@ -2378,27 +2234,14 @@ keyedit_menu (const char *username, strlist_t locusr,
            }
          /* fall thru */
        case cmdSAVE:
-         if (modified || sec_modified)
+         if (modified)
            {
-             if (modified)
-               {
-                 rc = keydb_update_keyblock (kdbhd, keyblock);
-                 if (rc)
-                   {
-                     log_error (_("update failed: %s\n"), g10_errstr (rc));
-                     break;
-                   }
-               }
-             if (sec_modified)
-               {
-                 rc = keydb_update_keyblock (sec_kdbhd, sec_keyblock);
-                 if (rc)
-                   {
-                     log_error (_("update secret failed: %s\n"),
-                                g10_errstr (rc));
-                     break;
-                   }
-               }
+              err = keydb_update_keyblock (kdbhd, keyblock);
+              if (err)
+                {
+                  log_error (_("update failed: %s\n"), g10_errstr (err));
+                  break;
+                }
            }
          else
            tty_printf (_("Key not changed so no update needed.\n"));
@@ -2416,11 +2259,10 @@ keyedit_menu (const char *username, strlist_t locusr,
          tty_printf (_("Invalid command  (try \"help\")\n"));
          break;
        }
-    }                          /* end main loop */
+    } /* End of the main command loop.  */
 
-leave:
+ leave:
   release_kbnode (keyblock);
-  release_kbnode (sec_keyblock);
   keydb_release (kdbhd);
   xfree (answer);
 }
@@ -2428,13 +2270,10 @@ leave:
 
 /* Change the passphrase of the secret key identified by USERNAME.  */
 void
-keyedit_passwd (const char *username)
+keyedit_passwd (ctrl_t ctrl, const char *username)
 {
   gpg_error_t err;
   PKT_public_key *pk;
-  unsigned char fpr[MAX_FINGERPRINT_LEN];
-  size_t fprlen;
-  KEYDB_HANDLE kdh = NULL;
   kbnode_t keyblock = NULL;
 
   pk = xtrycalloc (1, sizeof *pk);
@@ -2443,55 +2282,183 @@ keyedit_passwd (const char *username)
       err = gpg_error_from_syserror ();
       goto leave;
     }
-  err = getkey_byname (NULL, pk, username, 1, NULL);
+  err = getkey_byname (NULL, pk, username, 1, &keyblock);
   if (err)
     goto leave;
-  fingerprint_from_pk (pk, fpr, &fprlen);
-  while (fprlen < MAX_FINGERPRINT_LEN)
-    fpr[fprlen++] = 0;
 
-  /* FIXME: Call an agent function instead.  */
+  err = change_passphrase (ctrl, keyblock);
 
-  kdh = keydb_new (1);
-  if (!kdh)
+leave:
+  release_kbnode (keyblock);
+  free_public_key (pk);
+  if (err)
     {
-      err = gpg_error (GPG_ERR_GENERAL);
-      goto leave;
+      log_info ("error changing the passphrase for '%s': %s\n",
+               username, gpg_strerror (err));
+      write_status_error ("keyedit.passwd", err);
     }
+  else
+    write_status_text (STATUS_SUCCESS, "keyedit.passwd");
+}
 
-  err = keydb_search_fpr (kdh, fpr);
-  if (err == -1 || gpg_err_code (err) == GPG_ERR_EOF)
-    err = gpg_error (GPG_ERR_NO_SECKEY);
-  if (err)
-    goto leave;
 
-  err = keydb_get_keyblock (kdh, &keyblock);
-  if (err)
-    goto leave;
+/* Unattended key signing function.  If the key specifified by FPR is
+   availabale and FPR is the primary fingerprint all user ids of the
+   user ids of the key are signed using the default signing key.  If
+   UIDS is an empty list all usable UIDs are signed, if it is not
+   empty, only those user ids matching one of the entries of the loist
+   are signed.  With LOCAL being true kthe signatures are marked as
+   non-exportable.  */
+void
+keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
+                    strlist_t locusr, int local)
+{
+  gpg_error_t err;
+  kbnode_t keyblock = NULL;
+  KEYDB_HANDLE kdbhd = NULL;
+  int modified = 0;
+  KEYDB_SEARCH_DESC desc;
+  PKT_public_key *pk;
+  kbnode_t node;
+  strlist_t sl;
+  int any;
 
-  if (!change_passphrase (keyblock, &err))
-    goto leave;
+#ifdef HAVE_W32_SYSTEM
+  /* See keyedit_menu for why we need this.  */
+  check_trustdb_stale ();
+#endif
 
-  err = keydb_update_keyblock (kdh, keyblock);
+  /* We require a fingerprint because only this uniquely identifies a
+     key and may thus be used to select a key for unattended key
+     signing.  */
+  if (classify_user_id (fpr, &desc, 1)
+      || !(desc.mode == KEYDB_SEARCH_MODE_FPR
+           || desc.mode == KEYDB_SEARCH_MODE_FPR16
+           || desc.mode == KEYDB_SEARCH_MODE_FPR20))
+    {
+      log_error (_("\"%s\" is not a fingerprint\n"), fpr);
+      goto leave;
+    }
+  err = get_pubkey_byname (ctrl, NULL, NULL, fpr, &keyblock, &kdbhd, 1, 1);
   if (err)
-    log_error (_("update secret failed: %s\n"), gpg_strerror (err));
+    {
+      log_error (_("key \"%s\" not found: %s\n"), fpr, gpg_strerror (err));
+      goto leave;
+    }
+  if (fix_keyblock (keyblock))
+    modified++;
+  if (collapse_uids (&keyblock))
+    modified++;
+  reorder_keyblock (keyblock);
 
-leave:
-  release_kbnode (keyblock);
-  if (pk)
-    free_public_key (pk);
-  keydb_release (kdh);
-  if (err)
+  /* Check that the primary fingerprint has been given. */
+  {
+    byte fprbin[MAX_FINGERPRINT_LEN];
+    size_t fprlen;
+
+    fingerprint_from_pk (keyblock->pkt->pkt.public_key, fprbin, &fprlen);
+    if (fprlen == 16 && desc.mode == KEYDB_SEARCH_MODE_FPR16
+        && !memcmp (fprbin, desc.u.fpr, 16))
+      ;
+    else if (fprlen == 16 && desc.mode == KEYDB_SEARCH_MODE_FPR
+             && !memcmp (fprbin, desc.u.fpr, 16)
+             && !desc.u.fpr[16]
+             && !desc.u.fpr[17]
+             && !desc.u.fpr[18]
+             && !desc.u.fpr[19])
+      ;
+    else if (fprlen == 20 && (desc.mode == KEYDB_SEARCH_MODE_FPR20
+                              || desc.mode == KEYDB_SEARCH_MODE_FPR)
+             && !memcmp (fprbin, desc.u.fpr, 20))
+      ;
+    else
+      {
+        log_error (_("\"%s\" is not the primary fingerprint\n"), fpr);
+        goto leave;
+      }
+  }
+
+  /* If we modified the keyblock, make sure the flags are right. */
+  if (modified)
+    merge_keys_and_selfsig (keyblock);
+
+  /* Give some info in verbose.  */
+  if (opt.verbose)
     {
-      log_info ("error changing the passphrase for `%s': %s\n",
-               username, gpg_strerror (err));
-      write_status_error ("keyedit.passwd", err);
+      show_key_with_all_names (es_stdout, keyblock, 0,
+                               1/*with_revoker*/, 1/*with_fingerprint*/,
+                               0, 0, 1);
+      es_fflush (es_stdout);
+    }
+
+  pk = keyblock->pkt->pkt.public_key;
+  if (pk->flags.revoked)
+    {
+      if (!opt.verbose)
+        show_key_with_all_names (es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
+      log_error ("%s%s", _("Key is revoked."), _("  Unable to sign.\n"));
+      goto leave;
+    }
+
+  /* Set the flags according to the UIDS list.  Fixme: We may want to
+     use classify_user_id along with dedicated compare functions so
+     that we match the same way as in the key lookup. */
+  any = 0;
+  menu_select_uid (keyblock, 0);   /* Better clear the flags first. */
+  for (sl=uids; sl; sl = sl->next)
+    {
+      for (node = keyblock; node; node = node->next)
+        {
+          if (node->pkt->pkttype == PKT_USER_ID)
+            {
+              PKT_user_id *uid = node->pkt->pkt.user_id;
+
+              if (!uid->attrib_data
+                  && ascii_memistr (uid->name, uid->len, sl->d))
+                {
+                  node->flag |= NODFLG_SELUID;
+                  any = 1;
+                }
+            }
+        }
+    }
+
+  if (uids && !any)
+    {
+      if (!opt.verbose)
+        show_key_with_all_names (es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
+      es_fflush (es_stdout);
+      log_error ("%s  %s", _("No matching user IDs."), _("Nothing to sign.\n"));
+      goto leave;
+    }
+
+  /* Sign. */
+  sign_uids (es_stdout, keyblock, locusr, &modified, local, 0, 0, 0, 1);
+  es_fflush (es_stdout);
+
+  if (modified)
+    {
+      err = keydb_update_keyblock (kdbhd, keyblock);
+      if (err)
+        {
+          log_error (_("update failed: %s\n"), gpg_strerror (err));
+          goto leave;
+        }
     }
   else
-    write_status_text (STATUS_SUCCESS, "keyedit.passwd");
+    log_info (_("Key not changed so no update needed.\n"));
+
+  if (update_trust)
+    revalidation_mark ();
+
+
+ leave:
+  release_kbnode (keyblock);
+  keydb_release (kdbhd);
 }
 
 
+\f
 static void
 tty_print_notations (int indent, PKT_signature * sig)
 {
@@ -2687,17 +2654,21 @@ show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose)
     }
 }
 
+
 /* This is the version of show_key_with_all_names used when
    opt.with_colons is used.  It prints all available data in a easy to
    parse format and does not translate utf8 */
 static void
-show_key_with_all_names_colon (KBNODE keyblock)
+show_key_with_all_names_colon (estream_t fp, kbnode_t keyblock)
 {
   KBNODE node;
   int i, j, ulti_hack = 0;
   byte pk_version = 0;
   PKT_public_key *primary = NULL;
 
+  if (!fp)
+    fp = es_stdout;
+
   /* the keys */
   for (node = keyblock; node; node = node->next)
     {
@@ -2715,46 +2686,46 @@ show_key_with_all_names_colon (KBNODE keyblock)
 
          keyid_from_pk (pk, keyid);
 
-         fputs (node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub:" : "sub:",
-                stdout);
-         if (!pk->is_valid)
-           putchar ('i');
-         else if (pk->is_revoked)
-           putchar ('r');
+         es_fputs (node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub:" : "sub:",
+                    fp);
+         if (!pk->flags.valid)
+           es_putc ('i', fp);
+         else if (pk->flags.revoked)
+           es_putc ('r', fp);
          else if (pk->has_expired)
-           putchar ('e');
+           es_putc ('e', fp);
          else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks))
            {
              int trust = get_validity_info (pk, NULL);
              if (trust == 'u')
                ulti_hack = 1;
-             putchar (trust);
+             es_putc (trust, fp);
            }
 
-         printf (":%u:%d:%08lX%08lX:%lu:%lu::",
-                 nbits_from_pk (pk),
-                 pk->pubkey_algo,
-                 (ulong) keyid[0], (ulong) keyid[1],
-                 (ulong) pk->timestamp, (ulong) pk->expiredate);
+         es_fprintf (fp, ":%u:%d:%08lX%08lX:%lu:%lu::",
+                      nbits_from_pk (pk),
+                      pk->pubkey_algo,
+                      (ulong) keyid[0], (ulong) keyid[1],
+                      (ulong) pk->timestamp, (ulong) pk->expiredate);
          if (node->pkt->pkttype == PKT_PUBLIC_KEY
              && !(opt.fast_list_mode || opt.no_expensive_trust_checks))
-           putchar (get_ownertrust_info (pk));
-         putchar (':');
-         putchar (':');
-         putchar (':');
+           es_putc (get_ownertrust_info (pk), fp);
+         es_putc (':', fp);
+         es_putc (':', fp);
+         es_putc (':', fp);
          /* Print capabilities.  */
          if ((pk->pubkey_usage & PUBKEY_USAGE_ENC))
-           putchar ('e');
+           es_putc ('e', fp);
          if ((pk->pubkey_usage & PUBKEY_USAGE_SIG))
-           putchar ('s');
+           es_putc ('s', fp);
          if ((pk->pubkey_usage & PUBKEY_USAGE_CERT))
-           putchar ('c');
+           es_putc ('c', fp);
          if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
-           putchar ('a');
-         putchar ('\n');
+           es_putc ('a', fp);
+         es_putc ('\n', fp);
 
-         print_fingerprint (pk, NULL, 0);
-         print_revokers (pk);
+         print_fingerprint (fp, pk, 0);
+         print_revokers (fp, pk);
        }
     }
 
@@ -2769,16 +2740,16 @@ show_key_with_all_names_colon (KBNODE keyblock)
          ++i;
 
          if (uid->attrib_data)
-           printf ("uat:");
+           es_fputs ("uat:", fp);
          else
-           printf ("uid:");
+           es_fputs ("uid:", fp);
 
          if (uid->is_revoked)
-           printf ("r::::::::");
+           es_fputs ("r::::::::", fp);
          else if (uid->is_expired)
-           printf ("e::::::::");
+           es_fputs ("e::::::::", fp);
          else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
-           printf ("::::::::");
+           es_fputs ("::::::::", fp);
          else
            {
              int uid_validity;
@@ -2787,19 +2758,19 @@ show_key_with_all_names_colon (KBNODE keyblock)
                uid_validity = get_validity_info (primary, uid);
              else
                uid_validity = 'u';
-             printf ("%c::::::::", uid_validity);
+             es_fprintf (fp, "%c::::::::", uid_validity);
            }
 
          if (uid->attrib_data)
-           printf ("%u %lu", uid->numattribs, uid->attrib_len);
+           es_fprintf (fp, "%u %lu", uid->numattribs, uid->attrib_len);
          else
-           es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
+           es_write_sanitized (fp, uid->name, uid->len, ":", NULL);
 
-         putchar (':');
+         es_putc (':', fp);
          /* signature class */
-         putchar (':');
+         es_putc (':', fp);
          /* capabilities */
-         putchar (':');
+         es_putc (':', fp);
          /* preferences */
          if (pk_version > 3 || uid->selfsigversion > 3)
            {
@@ -2808,38 +2779,41 @@ show_key_with_all_names_colon (KBNODE keyblock)
              for (j = 0; prefs && prefs[j].type; j++)
                {
                  if (j)
-                   putchar (' ');
-                 printf ("%c%d", prefs[j].type == PREFTYPE_SYM ? 'S' :
-                         prefs[j].type == PREFTYPE_HASH ? 'H' :
-                         prefs[j].type == PREFTYPE_ZIP ? 'Z' : '?',
-                         prefs[j].value);
+                   es_putc (' ', fp);
+                 es_fprintf (fp,
+                              "%c%d", prefs[j].type == PREFTYPE_SYM ? 'S' :
+                              prefs[j].type == PREFTYPE_HASH ? 'H' :
+                              prefs[j].type == PREFTYPE_ZIP ? 'Z' : '?',
+                              prefs[j].value);
                }
              if (uid->flags.mdc)
-               printf (",mdc");
+               es_fputs (",mdc", fp);
              if (!uid->flags.ks_modify)
-               printf (",no-ks-modify");
+               es_fputs (",no-ks-modify", fp);
            }
-         putchar (':');
+         es_putc (':', fp);
          /* flags */
-         printf ("%d,", i);
+         es_fprintf (fp, "%d,", i);
          if (uid->is_primary)
-           putchar ('p');
+           es_putc ('p', fp);
          if (uid->is_revoked)
-           putchar ('r');
+           es_putc ('r', fp);
          if (uid->is_expired)
-           putchar ('e');
+           es_putc ('e', fp);
          if ((node->flag & NODFLG_SELUID))
-           putchar ('s');
+           es_putc ('s', fp);
          if ((node->flag & NODFLG_MARK_A))
-           putchar ('m');
-         putchar (':');
-         putchar ('\n');
+           es_putc ('m', fp);
+         es_putc (':', fp);
+         es_putc ('\n', fp);
        }
     }
 }
 
+
 static void
-show_names (KBNODE keyblock, PKT_public_key * pk, unsigned int flag,
+show_names (estream_t fp,
+            KBNODE keyblock, PKT_public_key * pk, unsigned int flag,
            int with_prefs)
 {
   KBNODE node;
@@ -2854,18 +2828,18 @@ show_names (KBNODE keyblock, PKT_public_key * pk, unsigned int flag,
          if (!flag || (flag && (node->flag & flag)))
            {
              if (!(flag & NODFLG_MARK_A) && pk)
-               tty_printf ("%s ", uid_trust_string_fixed (pk, uid));
+               tty_fprintf (fp, "%s ", uid_trust_string_fixed (pk, uid));
 
              if (flag & NODFLG_MARK_A)
-               tty_printf ("     ");
+               tty_fprintf (fp, "     ");
              else if (node->flag & NODFLG_SELUID)
-               tty_printf ("(%d)* ", i);
+               tty_fprintf (fp, "(%d)* ", i);
              else if (uid->is_primary)
-               tty_printf ("(%d). ", i);
+               tty_fprintf (fp, "(%d). ", i);
              else
-               tty_printf ("(%d)  ", i);
-             tty_print_utf8_string (uid->name, uid->len);
-             tty_printf ("\n");
+               tty_fprintf (fp, "(%d)  ", i);
+             tty_print_utf8_string2 (fp, uid->name, uid->len, 0);
+             tty_fprintf (fp, "\n");
              if (with_prefs && pk)
                {
                  if (pk->version > 3 || uid->selfsigversion > 3)
@@ -2888,8 +2862,8 @@ show_names (KBNODE keyblock, PKT_public_key * pk, unsigned int flag,
                      show_prefs (uid, selfsig, with_prefs == 2);
                    }
                  else
-                   tty_printf (_("There are no preferences on a"
-                                 " PGP 2.x-style user ID.\n"));
+                   tty_fprintf (fp, _("There are no preferences on a"
+                                       " PGP 2.x-style user ID.\n"));
                }
            }
        }
@@ -2898,22 +2872,26 @@ show_names (KBNODE keyblock, PKT_public_key * pk, unsigned int flag,
 
 
 /*
- * Display the key a the user ids, if only_marked is true, do only
- * so for user ids with mark A flag set and dont display the index number
+ * Display the key a the user ids, if only_marked is true, do only so
+ * for user ids with mark A flag set and do not display the index
+ * number.  If FP is not NULL print to the given stream and not to the
+ * tty (ignored in with-colons mode).
  */
 static void
-show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
-                        int with_fpr, int with_subkeys, int with_prefs)
+show_key_with_all_names (estream_t fp,
+                         KBNODE keyblock, int only_marked, int with_revoker,
+                        int with_fpr, int with_subkeys, int with_prefs,
+                         int nowarn)
 {
   KBNODE node;
   int i;
   int do_warn = 0;
-  byte pk_version = 0;
   PKT_public_key *primary = NULL;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
 
   if (opt.with_colons)
     {
-      show_key_with_all_names_colon (keyblock);
+      show_key_with_all_names_colon (fp, keyblock);
       return;
     }
 
@@ -2925,7 +2903,8 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
              && !is_deleted_kbnode (node)))
        {
          PKT_public_key *pk = node->pkt->pkt.public_key;
-         const char *otrust = "err", *trust = "err";
+         const char *otrust = "err";
+         const char *trust = "err";
 
          if (node->pkt->pkttype == PKT_PUBLIC_KEY)
            {
@@ -2944,16 +2923,17 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
                  do_warn = 1;
                }
 
-             pk_version = pk->version;
              primary = pk;
            }
 
-         if (pk->is_revoked)
+         if (pk->flags.revoked)
            {
              char *user = get_user_id_string_native (pk->revoked.keyid);
-             const char *algo = gcry_pk_algo_name (pk->revoked.algo);
-             tty_printf (_("This key was revoked on %s by %s key %s\n"),
-                         revokestr_from_pk (pk), algo ? algo : "?", user);
+              tty_fprintf (fp,
+                           _("The following key was revoked on"
+                            " %s by %s key %s\n"),
+                         revokestr_from_pk (pk),
+                          gcry_pk_algo_name (pk->revoked.algo), user);
              xfree (user);
            }
 
@@ -2973,44 +2953,82 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
                                            MAX_FINGERPRINT_LEN, r_keyid);
 
                    user = get_user_id_string_native (r_keyid);
-                   tty_printf (_("This key may be revoked by %s key %s"),
-                               algo ? algo : "?", user);
+                   tty_fprintf (fp,
+                                 _("This key may be revoked by %s key %s"),
+                                 algo ? algo : "?", user);
 
                    if (pk->revkey[i].class & 0x40)
                      {
-                       tty_printf (" ");
-                       tty_printf (_("(sensitive)"));
+                       tty_fprintf (fp, " ");
+                       tty_fprintf (fp, _("(sensitive)"));
                      }
 
-                   tty_printf ("\n");
+                   tty_fprintf (fp, "\n");
                    xfree (user);
                  }
            }
 
          keyid_from_pk (pk, NULL);
-         tty_printf ("%s%c %4u%c/%s  ",
-                     node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" : "sub",
+         tty_fprintf (fp, "%s%c %s/%s",
+                     node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" :
+                     node->pkt->pkttype == PKT_PUBLIC_SUBKEY ? "sub" :
+                     node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb",
                      (node->flag & NODFLG_SELKEY) ? '*' : ' ',
-                     nbits_from_pk (pk),
-                     pubkey_letter (pk->pubkey_algo), keystr (pk->keyid));
-
-         tty_printf (_("created: %s"), datestr_from_pk (pk));
-         tty_printf ("  ");
-         if (pk->is_revoked)
-           tty_printf (_("revoked: %s"), revokestr_from_pk (pk));
+                      pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+                     keystr (pk->keyid));
+
+          if (opt.legacy_list_mode)
+            tty_fprintf (fp, "  ");
+          else
+            tty_fprintf (fp, "\n     ");
+
+          tty_fprintf (fp, _("created: %s"), datestr_from_pk (pk));
+         tty_fprintf (fp, "  ");
+         if (pk->flags.revoked)
+           tty_fprintf (fp, _("revoked: %s"), revokestr_from_pk (pk));
          else if (pk->has_expired)
-           tty_printf (_("expired: %s"), expirestr_from_pk (pk));
+           tty_fprintf (fp, _("expired: %s"), expirestr_from_pk (pk));
          else
-           tty_printf (_("expires: %s"), expirestr_from_pk (pk));
-         tty_printf ("  ");
-         tty_printf (_("usage: %s"), usagestr_from_pk (pk));
-         tty_printf ("\n");
+           tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
+         tty_fprintf (fp, "  ");
+         tty_fprintf (fp, _("usage: %s"), usagestr_from_pk (pk, 1));
+         tty_fprintf (fp, "\n");
+
+         if (pk->seckey_info
+              && pk->seckey_info->is_protected
+              && pk->seckey_info->s2k.mode == 1002)
+           {
+             tty_fprintf (fp, "%*s%s", opt.legacy_list_mode? 21:5, "",
+                           _("card-no: "));
+             if (pk->seckey_info->ivlen == 16
+                 && !memcmp (pk->seckey_info->iv,
+                              "\xD2\x76\x00\x01\x24\x01", 6))
+               {
+                  /* This is an OpenPGP card. */
+                 for (i = 8; i < 14; i++)
+                   {
+                     if (i == 10)
+                       tty_fprintf (fp, " ");
+                     tty_fprintf (fp, "%02X", pk->seckey_info->iv[i]);
+                   }
+               }
+             else
+               {
+                  /* Unknown card: Print all. */
+                 for (i = 0; i < pk->seckey_info->ivlen; i++)
+                   tty_fprintf (fp, "%02X", pk->seckey_info->iv[i]);
+               }
+             tty_fprintf (fp, "\n");
+           }
 
-         if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+         if (node->pkt->pkttype == PKT_PUBLIC_KEY
+              || node->pkt->pkttype == PKT_SECRET_KEY)
            {
              if (opt.trust_model != TM_ALWAYS)
                {
-                 tty_printf ("%*s", (int) keystrlen () + 13, "");
+                 tty_fprintf (fp, "%*s",
+                               opt.legacy_list_mode?
+                               ((int) keystrlen () + 13):5, "");
                  /* Ownertrust is only meaningful for the PGP or
                     classic trust models */
                  if (opt.trust_model == TM_PGP
@@ -3019,71 +3037,38 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
                      int width = 14 - strlen (otrust);
                      if (width <= 0)
                        width = 1;
-                     tty_printf (_("trust: %s"), otrust);
-                     tty_printf ("%*s", width, "");
+                     tty_fprintf (fp, _("trust: %s"), otrust);
+                     tty_fprintf (fp, "%*s", width, "");
                    }
 
-                 tty_printf (_("validity: %s"), trust);
-                 tty_printf ("\n");
+                 tty_fprintf (fp, _("validity: %s"), trust);
+                 tty_fprintf (fp, "\n");
                }
              if (node->pkt->pkttype == PKT_PUBLIC_KEY
                  && (get_ownertrust (pk) & TRUST_FLAG_DISABLED))
                {
-                 tty_printf ("*** ");
-                 tty_printf (_("This key has been disabled"));
-                 tty_printf ("\n");
+                 tty_fprintf (fp, "*** ");
+                 tty_fprintf (fp, _("This key has been disabled"));
+                 tty_fprintf (fp, "\n");
                }
            }
 
-         if (node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr)
+         if ((node->pkt->pkttype == PKT_PUBLIC_KEY
+               || node->pkt->pkttype == PKT_SECRET_KEY) && with_fpr)
            {
-             print_fingerprint (pk, NULL, 2);
-             tty_printf ("\n");
-           }
-       }
-      else if (node->pkt->pkttype == PKT_SECRET_KEY
-              || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY))
-       {
-         PKT_secret_key *sk = node->pkt->pkt.secret_key;
-         tty_printf ("%s%c %4u%c/%s  ",
-                     node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb",
-                     (node->flag & NODFLG_SELKEY) ? '*' : ' ',
-                     nbits_from_sk (sk),
-                     pubkey_letter (sk->pubkey_algo), keystr_from_sk (sk));
-         tty_printf (_("created: %s"), datestr_from_sk (sk));
-         tty_printf ("  ");
-         tty_printf (_("expires: %s"), expirestr_from_sk (sk));
-         tty_printf ("\n");
-         if (sk->is_protected && sk->protect.s2k.mode == 1002)
-           {
-             tty_printf ("                     ");
-             tty_printf (_("card-no: "));
-             if (sk->protect.ivlen == 16
-                 && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
-               {               /* This is an OpenPGP card. */
-                 for (i = 8; i < 14; i++)
-                   {
-                     if (i == 10)
-                       tty_printf (" ");
-                     tty_printf ("%02X", sk->protect.iv[i]);
-                   }
-               }
-             else
-               {               /* Something is wrong: Print all. */
-                 for (i = 0; i < sk->protect.ivlen; i++)
-                   tty_printf ("%02X", sk->protect.iv[i]);
-               }
-             tty_printf ("\n");
+              print_fingerprint (fp, pk, 2);
+             tty_fprintf (fp, "\n");
            }
        }
     }
 
-  show_names (keyblock, primary, only_marked ? NODFLG_MARK_A : 0, with_prefs);
+  show_names (fp,
+              keyblock, primary, only_marked ? NODFLG_MARK_A : 0, with_prefs);
 
-  if (do_warn)
-    tty_printf (_("Please note that the shown key validity"
-                 " is not necessarily correct\n"
-                 "unless you restart the program.\n"));
+  if (do_warn && !nowarn)
+    tty_fprintf (fp, _("Please note that the shown key validity"
+                       " is not necessarily correct\n"
+                       "unless you restart the program.\n"));
 }
 
 
@@ -3096,39 +3081,29 @@ show_basic_key_info (KBNODE keyblock)
 {
   KBNODE node;
   int i;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
 
   /* The primary key */
   for (node = keyblock; node; node = node->next)
     {
-      if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY
+          || node->pkt->pkttype == PKT_SECRET_KEY)
        {
          PKT_public_key *pk = node->pkt->pkt.public_key;
 
          /* Note, we use the same format string as in other show
             functions to make the translation job easier. */
-         tty_printf ("%s  %4u%c/%s  ",
-                     node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" : "sub",
-                     nbits_from_pk (pk),
-                     pubkey_letter (pk->pubkey_algo), keystr_from_pk (pk));
+         tty_printf ("%s  %s/%s  ",
+                     node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" :
+                     node->pkt->pkttype == PKT_PUBLIC_SUBKEY ? "sub" :
+                     node->pkt->pkttype == PKT_SECRET_KEY ? "sec" :"ssb",
+                      pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+                     keystr_from_pk (pk));
          tty_printf (_("created: %s"), datestr_from_pk (pk));
          tty_printf ("  ");
          tty_printf (_("expires: %s"), expirestr_from_pk (pk));
          tty_printf ("\n");
-         print_fingerprint (pk, NULL, 3);
-         tty_printf ("\n");
-       }
-      else if (node->pkt->pkttype == PKT_SECRET_KEY)
-       {
-         PKT_secret_key *sk = node->pkt->pkt.secret_key;
-         tty_printf ("%s  %4u%c/%s",
-                     node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb",
-                     nbits_from_sk (sk),
-                     pubkey_letter (sk->pubkey_algo), keystr_from_sk (sk));
-         tty_printf (_("created: %s"), datestr_from_sk (sk));
-         tty_printf ("  ");
-         tty_printf (_("expires: %s"), expirestr_from_sk (sk));
-         tty_printf ("\n");
-         print_fingerprint (NULL, sk, 3);
+         print_fingerprint (NULL, pk, 3);
          tty_printf ("\n");
        }
     }
@@ -3157,16 +3132,17 @@ show_key_and_fingerprint (KBNODE keyblock)
 {
   KBNODE node;
   PKT_public_key *pk = NULL;
+  char pkstrbuf[PUBKEY_STRING_SIZE];
 
   for (node = keyblock; node; node = node->next)
     {
       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
        {
          pk = node->pkt->pkt.public_key;
-         tty_printf ("pub   %4u%c/%s %s ",
-                     nbits_from_pk (pk),
-                     pubkey_letter (pk->pubkey_algo),
-                     keystr_from_pk (pk), datestr_from_pk (pk));
+         tty_printf ("pub   %s/%s %s ",
+                      pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
+                      keystr_from_pk(pk),
+                      datestr_from_pk (pk));
        }
       else if (node->pkt->pkttype == PKT_USER_ID)
        {
@@ -3177,7 +3153,7 @@ show_key_and_fingerprint (KBNODE keyblock)
     }
   tty_printf ("\n");
   if (pk)
-    print_fingerprint (pk, NULL, 2);
+    print_fingerprint (NULL, pk, 2);
 }
 
 
@@ -3217,22 +3193,19 @@ no_primary_warning (KBNODE keyblock)
 
 
 /*
- * Ask for a new user id, do the selfsignature and put it into
- * both keyblocks.
+ * Ask for a new user id, add the self-signature and update the keyblock.
  * Return true if there is a new user id
  */
 static int
-menu_adduid (KBNODE pub_keyblock, KBNODE sec_keyblock,
-            int photo, const char *photo_name)
+menu_adduid (KBNODE pub_keyblock, int photo, const char *photo_name)
 {
   PKT_user_id *uid;
   PKT_public_key *pk = NULL;
-  PKT_secret_key *sk = NULL;
   PKT_signature *sig = NULL;
   PACKET *pkt;
   KBNODE node;
-  KBNODE pub_where = NULL, sec_where = NULL;
-  int rc;
+  KBNODE pub_where = NULL;
+  gpg_error_t err;
 
   for (node = pub_keyblock; node; pub_where = node, node = node->next)
     {
@@ -3241,18 +3214,9 @@ menu_adduid (KBNODE pub_keyblock, KBNODE sec_keyblock,
       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
        break;
     }
-  if (!node)                   /* no subkey */
+  if (!node) /* No subkey.  */
     pub_where = NULL;
-  for (node = sec_keyblock; node; sec_where = node, node = node->next)
-    {
-      if (node->pkt->pkttype == PKT_SECRET_KEY)
-       sk = copy_secret_key (NULL, node->pkt->pkt.secret_key);
-      else if (node->pkt->pkttype == PKT_SECRET_SUBKEY)
-       break;
-    }
-  if (!node)                   /* no subkey */
-    sec_where = NULL;
-  assert (pk && sk);
+  assert (pk);
 
   if (photo)
     {
@@ -3299,33 +3263,16 @@ menu_adduid (KBNODE pub_keyblock, KBNODE sec_keyblock,
   if (!uid)
     return 0;
 
-  rc = make_keysig_packet (&sig, pk, uid, NULL, sk, 0x13, 0, 0, 0, 0,
-                          keygen_add_std_prefs, pk);
-  free_secret_key (sk);
-  if (rc)
+  err = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x13, 0, 0, 0, 0,
+                            keygen_add_std_prefs, pk, NULL);
+  if (err)
     {
-      log_error ("signing failed: %s\n", g10_errstr (rc));
+      log_error ("signing failed: %s\n", g10_errstr (err));
       free_user_id (uid);
       return 0;
     }
 
-  /* insert/append to secret keyblock */
-  pkt = xmalloc_clear (sizeof *pkt);
-  pkt->pkttype = PKT_USER_ID;
-  pkt->pkt.user_id = scopy_user_id (uid);
-  node = new_kbnode (pkt);
-  if (sec_where)
-    insert_kbnode (sec_where, node, 0);
-  else
-    add_kbnode (sec_keyblock, node);
-  pkt = xmalloc_clear (sizeof *pkt);
-  pkt->pkttype = PKT_SIGNATURE;
-  pkt->pkt.signature = copy_signature (NULL, sig);
-  if (sec_where)
-    insert_kbnode (node, new_kbnode (pkt), 0);
-  else
-    add_kbnode (sec_keyblock, new_kbnode (pkt));
-  /* insert/append to public keyblock */
+  /* Insert/append to public keyblock */
   pkt = xmalloc_clear (sizeof *pkt);
   pkt->pkttype = PKT_USER_ID;
   pkt->pkt.user_id = uid;
@@ -3345,11 +3292,11 @@ menu_adduid (KBNODE pub_keyblock, KBNODE sec_keyblock,
 }
 
 
-/****************
- * Remove all selected userids from the keyrings
+/*
+ * Remove all selected userids from the keyring
  */
 static void
-menu_deluid (KBNODE pub_keyblock, KBNODE sec_keyblock)
+menu_deluid (KBNODE pub_keyblock)
 {
   KBNODE node;
   int selected = 0;
@@ -3366,30 +3313,6 @@ menu_deluid (KBNODE pub_keyblock, KBNODE sec_keyblock)
              if (!node->pkt->pkt.user_id->is_revoked)
                update_trust = 1;
              delete_kbnode (node);
-             if (sec_keyblock)
-               {
-                 KBNODE snode;
-                 int s_selected = 0;
-                 PKT_user_id *uid = node->pkt->pkt.user_id;
-                 for (snode = sec_keyblock; snode; snode = snode->next)
-                   {
-                     if (snode->pkt->pkttype == PKT_USER_ID)
-                       {
-                         PKT_user_id *suid = snode->pkt->pkt.user_id;
-
-                         s_selected =
-                           (uid->len == suid->len
-                            && !memcmp (uid->name, suid->name, uid->len));
-                         if (s_selected)
-                           delete_kbnode (snode);
-                       }
-                     else if (s_selected
-                              && snode->pkt->pkttype == PKT_SIGNATURE)
-                       delete_kbnode (snode);
-                     else if (snode->pkt->pkttype == PKT_SECRET_SUBKEY)
-                       s_selected = 0;
-                   }
-               }
            }
        }
       else if (selected && node->pkt->pkttype == PKT_SIGNATURE)
@@ -3398,8 +3321,6 @@ menu_deluid (KBNODE pub_keyblock, KBNODE sec_keyblock)
        selected = 0;
     }
   commit_kbnode (&pub_keyblock);
-  if (sec_keyblock)
-    commit_kbnode (&sec_keyblock);
 }
 
 
@@ -3436,21 +3357,21 @@ menu_delsig (KBNODE pub_keyblock)
 
          if (valid)
            {
-             okay = cpr_get_answer_yes_no_quit 
+             okay = cpr_get_answer_yes_no_quit
                 ("keyedit.delsig.valid",
                  _("Delete this good signature? (y/N/q)"));
-              
+
              /* Only update trust if we delete a good signature.
                 The other two cases do not affect trust. */
              if (okay)
                update_trust = 1;
            }
          else if (inv_sig || other_err)
-           okay = cpr_get_answer_yes_no_quit 
+           okay = cpr_get_answer_yes_no_quit
               ("keyedit.delsig.invalid",
                _("Delete this invalid signature? (y/N/q)"));
          else if (no_key)
-           okay = cpr_get_answer_yes_no_quit 
+           okay = cpr_get_answer_yes_no_quit
               ("keyedit.delsig.unknown",
                _("Delete this unknown signature? (y/N/q)"));
 
@@ -3543,11 +3464,12 @@ menu_clean (KBNODE keyblock, int self_only)
   return modified;
 }
 
-/****************
+
+/*
  * Remove some of the secondary keys
  */
 static void
-menu_delkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
+menu_delkey (KBNODE pub_keyblock)
 {
   KBNODE node;
   int selected = 0;
@@ -3558,34 +3480,7 @@ menu_delkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
        {
          selected = node->flag & NODFLG_SELKEY;
          if (selected)
-           {
-             delete_kbnode (node);
-             if (sec_keyblock)
-               {
-                 KBNODE snode;
-                 int s_selected = 0;
-                 u32 ki[2];
-
-                 keyid_from_pk (node->pkt->pkt.public_key, ki);
-                 for (snode = sec_keyblock; snode; snode = snode->next)
-                   {
-                     if (snode->pkt->pkttype == PKT_SECRET_SUBKEY)
-                       {
-                         u32 ki2[2];
-
-                         keyid_from_sk (snode->pkt->pkt.secret_key, ki2);
-                         s_selected = (ki[0] == ki2[0] && ki[1] == ki2[1]);
-                         if (s_selected)
-                           delete_kbnode (snode);
-                       }
-                     else if (s_selected
-                              && snode->pkt->pkttype == PKT_SIGNATURE)
-                       delete_kbnode (snode);
-                     else
-                       s_selected = 0;
-                   }
-               }
-           }
+            delete_kbnode (node);
        }
       else if (selected && node->pkt->pkttype == PKT_SIGNATURE)
        delete_kbnode (node);
@@ -3593,25 +3488,22 @@ menu_delkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
        selected = 0;
     }
   commit_kbnode (&pub_keyblock);
-  if (sec_keyblock)
-    commit_kbnode (&sec_keyblock);
 
   /* No need to set update_trust here since signing keys are no
      longer used to certify other keys, so there is no change in
-     trust when revoking/removing them */
+     trust when revoking/removing them.   */
 }
 
 
-/****************
- * Ask for a new revoker, do the selfsignature and put it into
- * both keyblocks.
- * Return true if there is a new revoker
+/*
+ * Ask for a new revoker, create the self-signature and put it into
+ * the keyblock.  Returns true if there is a new revoker.
  */
 static int
-menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive)
+menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive)
 {
-  PKT_public_key *pk = NULL, *revoker_pk = NULL;
-  PKT_secret_key *sk = NULL;
+  PKT_public_key *pk = NULL;
+  PKT_public_key *revoker_pk = NULL;
   PKT_signature *sig = NULL;
   PACKET *pkt;
   struct revocation_key revkey;
@@ -3619,7 +3511,6 @@ menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive)
   int rc;
 
   assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
-  assert (sec_keyblock->pkt->pkttype == PKT_SECRET_KEY);
 
   pk = pub_keyblock->pkt->pkt.public_key;
 
@@ -3649,23 +3540,19 @@ menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive)
        }
     }
 
-  sk = copy_secret_key (NULL, sec_keyblock->pkt->pkt.secret_key);
-
   for (;;)
     {
       char *answer;
 
-      if (revoker_pk)
-       free_public_key (revoker_pk);
-
+      free_public_key (revoker_pk);
       revoker_pk = xmalloc_clear (sizeof (*revoker_pk));
 
       tty_printf ("\n");
 
-      answer = cpr_get_utf8 ("keyedit.add_revoker",
-                            _
-                            ("Enter the user ID of the designated revoker: "));
-      if (answer[0] == '\0' || answer[0] == '\004')
+      answer = cpr_get_utf8
+        ("keyedit.add_revoker",
+         _("Enter the user ID of the designated revoker: "));
+      if (answer[0] == '\0' || answer[0] == CONTROL_D)
        {
          xfree (answer);
          goto fail;
@@ -3673,10 +3560,9 @@ menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive)
 
       /* Note that I'm requesting CERT here, which usually implies
          primary keys only, but some casual testing shows that PGP and
-         GnuPG both can handle a designated revokation from a
-         subkey. */
+         GnuPG both can handle a designated revocation from a subkey. */
       revoker_pk->req_usage = PUBKEY_USAGE_CERT;
-      rc = get_pubkey_byname (NULL, revoker_pk, answer, NULL, NULL, 1, 1);
+      rc = get_pubkey_byname (ctrl, NULL, revoker_pk, answer, NULL, NULL, 1, 1);
       if (rc)
        {
          log_error (_("key \"%s\" not found: %s\n"), answer,
@@ -3743,7 +3629,7 @@ menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive)
        }
 
       print_pubkey_info (NULL, revoker_pk);
-      print_fingerprint (revoker_pk, NULL, 2);
+      print_fingerprint (NULL, revoker_pk, 2);
       tty_printf ("\n");
 
       tty_printf (_("WARNING: appointing a key as a designated revoker "
@@ -3763,24 +3649,15 @@ menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive)
 
   /* The 1F signature must be at least v4 to carry the revocation key
      subpacket. */
-  rc = make_keysig_packet (&sig, pk, NULL, NULL, sk, 0x1F, 0, 4, 0, 0,
-                          keygen_add_revkey, &revkey);
+  rc = make_keysig_packet (&sig, pk, NULL, NULL, pk, 0x1F, 0, 4, 0, 0,
+                          keygen_add_revkey, &revkey, NULL);
   if (rc)
     {
       log_error ("signing failed: %s\n", g10_errstr (rc));
       goto fail;
     }
 
-  free_secret_key (sk);
-  sk = NULL;
-
-  /* insert into secret keyblock */
-  pkt = xmalloc_clear (sizeof *pkt);
-  pkt->pkttype = PKT_SIGNATURE;
-  pkt->pkt.signature = copy_signature (NULL, sig);
-  insert_kbnode (sec_keyblock, new_kbnode (pkt), PKT_SIGNATURE);
-
-  /* insert into public keyblock */
+  /* Insert into public keyblock.  */
   pkt = xmalloc_clear (sizeof *pkt);
   pkt->pkttype = PKT_SIGNATURE;
   pkt->pkt.signature = sig;
@@ -3789,35 +3666,25 @@ menu_addrevoker (KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive)
   return 1;
 
 fail:
-  if (sk)
-    free_secret_key (sk);
   if (sig)
     free_seckey_enc (sig);
-  if (revoker_pk)
-    free_public_key (revoker_pk);
+  free_public_key (revoker_pk);
 
   return 0;
 }
 
 
 static int
-menu_expire (KBNODE pub_keyblock, KBNODE sec_keyblock)
+menu_expire (KBNODE pub_keyblock)
 {
   int n1, signumber, rc;
   u32 expiredate;
   int mainkey = 0;
-  PKT_secret_key *sk;          /* copy of the main sk */
   PKT_public_key *main_pk, *sub_pk;
   PKT_user_id *uid;
   KBNODE node;
   u32 keyid[2];
 
-  if (count_selected_keys (sec_keyblock))
-    {
-      tty_printf (_("Please remove selections from the secret keys.\n"));
-      return 0;
-    }
-
   n1 = count_selected_keys (pub_keyblock);
   if (n1 > 1)
     {
@@ -3834,10 +3701,8 @@ menu_expire (KBNODE pub_keyblock, KBNODE sec_keyblock)
     }
 
   expiredate = ask_expiredate ();
-  node = find_kbnode (sec_keyblock, PKT_SECRET_KEY);
-  sk = copy_secret_key (NULL, node->pkt->pkt.secret_key);
 
-  /* Now we can actually change the self signature(s) */
+  /* Now we can actually change the self-signature(s) */
   main_pk = sub_pk = NULL;
   uid = NULL;
   signumber = 0;
@@ -3867,94 +3732,64 @@ menu_expire (KBNODE pub_keyblock, KBNODE sec_keyblock)
                  || (!mainkey && sig->sig_class == 0x18))
              && sig->flags.chosen_selfsig)
            {
-             /* this is a selfsignature which is to be replaced */
+             /* This is a self-signature which is to be replaced.  */
              PKT_signature *newsig;
              PACKET *newpkt;
-             KBNODE sn;
-             int signumber2 = 0;
 
              signumber++;
 
              if ((mainkey && main_pk->version < 4)
                  || (!mainkey && sub_pk->version < 4))
                {
-                 log_info 
+                 log_info
                     (_("You can't change the expiration date of a v3 key\n"));
-                 free_secret_key (sk);
                  return 0;
                }
 
-             /* find the corresponding secret self-signature */
-             for (sn = sec_keyblock; sn; sn = sn->next)
-               {
-                 if (sn->pkt->pkttype == PKT_SIGNATURE)
-                   {
-                     PKT_signature *b = sn->pkt->pkt.signature;
-                     if (keyid[0] == b->keyid[0] && keyid[1] == b->keyid[1]
-                         && sig->sig_class == b->sig_class
-                         && ++signumber2 == signumber)
-                       break;
-                   }
-               }
-             if (!sn)
-               log_info (_("No corresponding signature in secret ring\n"));
-
              if (mainkey)
                rc = update_keysig_packet (&newsig, sig, main_pk, uid, NULL,
-                                          sk, keygen_add_key_expire,
+                                          main_pk, keygen_add_key_expire,
                                           main_pk);
              else
                rc =
                  update_keysig_packet (&newsig, sig, main_pk, NULL, sub_pk,
-                                       sk, keygen_add_key_expire, sub_pk);
+                                       main_pk, keygen_add_key_expire, sub_pk);
              if (rc)
                {
                  log_error ("make_keysig_packet failed: %s\n",
                             g10_errstr (rc));
-                 free_secret_key (sk);
                  return 0;
                }
-             /* replace the packet */
+
+             /* Replace the packet.  */
              newpkt = xmalloc_clear (sizeof *newpkt);
              newpkt->pkttype = PKT_SIGNATURE;
              newpkt->pkt.signature = newsig;
              free_packet (node->pkt);
              xfree (node->pkt);
              node->pkt = newpkt;
-             if (sn)
-               {
-                 newpkt = xmalloc_clear (sizeof *newpkt);
-                 newpkt->pkttype = PKT_SIGNATURE;
-                 newpkt->pkt.signature = copy_signature (NULL, newsig);
-                 free_packet (sn->pkt);
-                 xfree (sn->pkt);
-                 sn->pkt = newpkt;
-               }
              sub_pk = NULL;
            }
        }
     }
 
-  free_secret_key (sk);
   update_trust = 1;
   return 1;
 }
 
+
 static int
-menu_backsign (KBNODE pub_keyblock, KBNODE sec_keyblock)
+menu_backsign (KBNODE pub_keyblock)
 {
   int rc, modified = 0;
   PKT_public_key *main_pk;
-  PKT_secret_key *main_sk, *sub_sk = NULL;
   KBNODE node;
   u32 timestamp;
 
   assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
-  assert (sec_keyblock->pkt->pkttype == PKT_SECRET_KEY);
 
   merge_keys_and_selfsig (pub_keyblock);
   main_pk = pub_keyblock->pkt->pkt.public_key;
-  main_sk = copy_secret_key (NULL, sec_keyblock->pkt->pkt.secret_key);
   keyid_from_pk (main_pk, NULL);
 
   /* We use the same timestamp for all backsigs so that we don't
@@ -3964,21 +3799,15 @@ menu_backsign (KBNODE pub_keyblock, KBNODE sec_keyblock)
   for (node = pub_keyblock; node; node = node->next)
     {
       PKT_public_key *sub_pk = NULL;
-      KBNODE node2, sig_pk = NULL, sig_sk = NULL;
-      char *passphrase;
-
-      if (sub_sk)
-       {
-         free_secret_key (sub_sk);
-         sub_sk = NULL;
-       }
+      KBNODE node2, sig_pk = NULL /*,sig_sk = NULL*/;
+      /* char *passphrase; */
 
       /* Find a signing subkey with no backsig */
       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
        {
          if (node->pkt->pkt.public_key->pubkey_usage & PUBKEY_USAGE_SIG)
            {
-             if (node->pkt->pkt.public_key->backsig)
+             if (node->pkt->pkt.public_key->flags.backsig)
                tty_printf (_
                            ("signing subkey %s is already cross-certified\n"),
                            keystr_from_pk (node->pkt->pkt.public_key));
@@ -4008,64 +3837,28 @@ menu_backsign (KBNODE pub_keyblock, KBNODE sec_keyblock)
        continue;
 
       /* Find the secret subkey that matches the public subkey */
-      for (node2 = sec_keyblock; node2; node2 = node2->next)
-       if (node2->pkt->pkttype == PKT_SECRET_SUBKEY
-           && !cmp_public_secret_key (sub_pk, node2->pkt->pkt.secret_key))
-         {
-           sub_sk = copy_secret_key (NULL, node2->pkt->pkt.secret_key);
-           break;
-         }
-
-      if (!sub_sk)
-       {
-         tty_printf (_("no secret subkey for public subkey %s - ignoring\n"),
-                     keystr_from_pk (sub_pk));
-         continue;
-       }
+      log_debug ("FIXME: Check whether a secret subkey is available.\n");
+      /* if (!sub_sk) */
+      /*   { */
+      /*     tty_printf (_("no secret subkey for public subkey %s - ignoring\n"), */
+      /*             keystr_from_pk (sub_pk)); */
+      /*     continue; */
+      /*   } */
 
-      /* Now finally find the matching selfsig on the secret subkey.
-         We can't use chosen_selfsig here (it's not set for secret
-         keys), so we just pick the selfsig with the right class.
-         This is what menu_expire does as well. */
-      for (node2 = node2->next;
-          node2 && node2->pkt->pkttype != PKT_SECRET_SUBKEY;
-          node2 = node2->next)
-       if (node2->pkt->pkttype == PKT_SIGNATURE
-           && node2->pkt->pkt.signature->version >= 4
-           && node2->pkt->pkt.signature->keyid[0] ==
-           sig_pk->pkt->pkt.signature->keyid[0]
-           && node2->pkt->pkt.signature->keyid[1] ==
-           sig_pk->pkt->pkt.signature->keyid[1]
-           && node2->pkt->pkt.signature->sig_class ==
-           sig_pk->pkt->pkt.signature->sig_class)
-         {
-           sig_sk = node2;
-           break;
-         }
-
-      /* Now we can get to work.  We have a main key and secret part,
-         a signing subkey with signature and secret part possibly with
-         signature. */
 
-      passphrase = get_last_passphrase ();
-      set_next_passphrase (passphrase);
-      xfree (passphrase);
+      /* Now we can get to work.  */
 
-      rc = make_backsig (sig_pk->pkt->pkt.signature, main_pk, sub_pk, sub_sk,
-                        timestamp);
-      if (rc == 0)
+      rc = make_backsig (sig_pk->pkt->pkt.signature, main_pk, sub_pk, sub_pk,
+                        timestamp, NULL);
+      if (!rc)
        {
          PKT_signature *newsig;
          PACKET *newpkt;
 
-         passphrase = get_last_passphrase ();
-         set_next_passphrase (passphrase);
-         xfree (passphrase);
-
-         rc =
-           update_keysig_packet (&newsig, sig_pk->pkt->pkt.signature,
-                                 main_pk, NULL, sub_pk, main_sk, NULL, NULL);
-         if (rc == 0)
+         rc = update_keysig_packet (&newsig, sig_pk->pkt->pkt.signature,
+                                     main_pk, NULL, sub_pk, main_pk,
+                                     NULL, NULL);
+         if (!rc)
            {
              /* Put the new sig into place on the pubkey */
              newpkt = xmalloc_clear (sizeof (*newpkt));
@@ -4075,17 +3868,6 @@ menu_backsign (KBNODE pub_keyblock, KBNODE sec_keyblock)
              xfree (sig_pk->pkt);
              sig_pk->pkt = newpkt;
 
-             if (sig_sk)
-               {
-                 /* Put the new sig into place on the seckey */
-                 newpkt = xmalloc_clear (sizeof (*newpkt));
-                 newpkt->pkttype = PKT_SIGNATURE;
-                 newpkt->pkt.signature = copy_signature (NULL, newsig);
-                 free_packet (sig_sk->pkt);
-                 xfree (sig_sk->pkt);
-                 sig_sk->pkt = newpkt;
-               }
-
              modified = 1;
            }
          else
@@ -4102,12 +3884,6 @@ menu_backsign (KBNODE pub_keyblock, KBNODE sec_keyblock)
        }
     }
 
-  set_next_passphrase (NULL);
-
-  free_secret_key (main_sk);
-  if (sub_sk)
-    free_secret_key (sub_sk);
-
   return modified;
 }
 
@@ -4142,9 +3918,8 @@ change_primary_uid_cb (PKT_signature * sig, void *opaque)
  * sufficient to updated a signature during import.
  */
 static int
-menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock)
+menu_set_primary_uid (KBNODE pub_keyblock)
 {
-  PKT_secret_key *sk;          /* copy of the main sk */
   PKT_public_key *main_pk;
   PKT_user_id *uid;
   KBNODE node;
@@ -4159,10 +3934,6 @@ menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock)
       return 0;
     }
 
-  node = find_kbnode (sec_keyblock, PKT_SECRET_KEY);
-  sk = copy_secret_key (NULL, node->pkt->pkt.secret_key);
-
-  /* Now we can actually change the self signature(s) */
   main_pk = NULL;
   uid = NULL;
   selected = 0;
@@ -4175,7 +3946,7 @@ menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock)
   for (node = pub_keyblock; node; node = node->next)
     {
       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-       break;                  /* ready */
+       break; /* No more user ids expected - ready.  */
 
       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
        {
@@ -4200,9 +3971,8 @@ menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock)
                  char *user =
                    utf8_to_native (uid->name, strlen (uid->name), 0);
 
-                 log_info (_
-                           ("skipping v3 self-signature on user ID \"%s\"\n"),
-                           user);
+                 log_info (_("skipping v3 self-signature on user ID \"%s\"\n"),
+                            user);
                  xfree (user);
                }
              else
@@ -4224,7 +3994,7 @@ menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock)
                  const byte *p;
                  int action;
 
-                 /* see whether this signature has the primary UID flag */
+                 /* See whether this signature has the primary UID flag.  */
                  p = parse_sig_subpkt (sig->hashed,
                                        SIGSUBPKT_PRIMARY_UID, NULL);
                  if (!p)
@@ -4239,14 +4009,13 @@ menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock)
                    {
                      int rc = update_keysig_packet (&newsig, sig,
                                                     main_pk, uid, NULL,
-                                                    sk,
+                                                    main_pk,
                                                     change_primary_uid_cb,
                                                     action > 0 ? "x" : NULL);
                      if (rc)
                        {
                          log_error ("update_keysig_packet failed: %s\n",
                                     g10_errstr (rc));
-                         free_secret_key (sk);
                          return 0;
                        }
                      /* replace the packet */
@@ -4263,18 +4032,16 @@ menu_set_primary_uid (KBNODE pub_keyblock, KBNODE sec_keyblock)
        }
     }
 
-  free_secret_key (sk);
   return modified;
 }
 
 
-/* 
+/*
  * Set preferences to new values for the selected user IDs
  */
 static int
-menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock)
+menu_set_preferences (KBNODE pub_keyblock)
 {
-  PKT_secret_key *sk;          /* copy of the main sk */
   PKT_public_key *main_pk;
   PKT_user_id *uid;
   KBNODE node;
@@ -4286,9 +4053,6 @@ menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock)
 
   select_all = !count_selected_uids (pub_keyblock);
 
-  node = find_kbnode (sec_keyblock, PKT_SECRET_KEY);
-  sk = copy_secret_key (NULL, node->pkt->pkt.secret_key);
-
   /* Now we can actually change the self signature(s) */
   main_pk = NULL;
   uid = NULL;
@@ -4296,7 +4060,7 @@ menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock)
   for (node = pub_keyblock; node; node = node->next)
     {
       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-       break;                  /* ready */
+       break; /* No more user-ids expected - ready.  */
 
       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
        {
@@ -4321,28 +4085,26 @@ menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock)
                  char *user =
                    utf8_to_native (uid->name, strlen (uid->name), 0);
 
-                 log_info (_
-                           ("skipping v3 self-signature on user ID \"%s\"\n"),
+                 log_info (_("skipping v3 self-signature on user ID \"%s\"\n"),
                            user);
                  xfree (user);
                }
              else
                {
-                 /* This is a selfsignature which is to be replaced 
+                 /* This is a selfsignature which is to be replaced
                   * We have to ignore v3 signatures because they are
-                  * not able to carry the preferences */
+                  * not able to carry the preferences */
                  PKT_signature *newsig;
                  PACKET *newpkt;
                  int rc;
 
                  rc = update_keysig_packet (&newsig, sig,
-                                            main_pk, uid, NULL,
-                                            sk, keygen_upd_std_prefs, NULL);
+                                            main_pk, uid, NULL, main_pk,
+                                             keygen_upd_std_prefs, NULL);
                  if (rc)
                    {
                      log_error ("update_keysig_packet failed: %s\n",
                                 g10_errstr (rc));
-                     free_secret_key (sk);
                      return 0;
                    }
                  /* replace the packet */
@@ -4358,16 +4120,13 @@ menu_set_preferences (KBNODE pub_keyblock, KBNODE sec_keyblock)
        }
     }
 
-  free_secret_key (sk);
   return modified;
 }
 
 
 static int
-menu_set_keyserver_url (const char *url,
-                       KBNODE pub_keyblock, KBNODE sec_keyblock)
+menu_set_keyserver_url (const char *url, KBNODE pub_keyblock)
 {
-  PKT_secret_key *sk;          /* copy of the main sk */
   PKT_public_key *main_pk;
   PKT_user_id *uid;
   KBNODE node;
@@ -4384,7 +4143,7 @@ menu_set_keyserver_url (const char *url,
     {
       answer = cpr_get_utf8 ("keyedit.add_keyserver",
                             _("Enter your preferred keyserver URL: "));
-      if (answer[0] == '\0' || answer[0] == '\004')
+      if (answer[0] == '\0' || answer[0] == CONTROL_D)
        {
          xfree (answer);
          return 0;
@@ -4410,9 +4169,6 @@ menu_set_keyserver_url (const char *url,
 
   select_all = !count_selected_uids (pub_keyblock);
 
-  node = find_kbnode (sec_keyblock, PKT_SECRET_KEY);
-  sk = copy_secret_key (NULL, node->pkt->pkt.secret_key);
-
   /* Now we can actually change the self signature(s) */
   main_pk = NULL;
   uid = NULL;
@@ -4420,7 +4176,7 @@ menu_set_keyserver_url (const char *url,
   for (node = pub_keyblock; node; node = node->next)
     {
       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-       break;                  /* ready */
+       break; /* ready */
 
       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
        {
@@ -4455,21 +4211,18 @@ menu_set_keyserver_url (const char *url,
                  const byte *p;
                  size_t plen;
 
-                 p =
-                   parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &plen);
+                 p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &plen);
                  if (p && plen)
                    {
                      tty_printf ("Current preferred keyserver for user"
                                  " ID \"%s\": ", user);
                      tty_print_utf8_string (p, plen);
                      tty_printf ("\n");
-                     if (!cpr_get_answer_is_yes ("keyedit.confirm_keyserver",
-                                                 uri ?
-                                                 _
-                                                 ("Are you sure you want to replace it? (y/N) ")
-                                                 :
-                                                 _
-                                                 ("Are you sure you want to delete it? (y/N) ")))
+                     if (!cpr_get_answer_is_yes
+                          ("keyedit.confirm_keyserver",
+                           uri
+                           ? _("Are you sure you want to replace it? (y/N) ")
+                           : _("Are you sure you want to delete it? (y/N) ")))
                        continue;
                    }
                  else if (uri == NULL)
@@ -4481,13 +4234,12 @@ menu_set_keyserver_url (const char *url,
 
                  rc = update_keysig_packet (&newsig, sig,
                                             main_pk, uid, NULL,
-                                            sk,
+                                            main_pk,
                                             keygen_add_keyserver_url, uri);
                  if (rc)
                    {
                      log_error ("update_keysig_packet failed: %s\n",
                                 g10_errstr (rc));
-                     free_secret_key (sk);
                      xfree (uri);
                      return 0;
                    }
@@ -4507,15 +4259,12 @@ menu_set_keyserver_url (const char *url,
     }
 
   xfree (uri);
-  free_secret_key (sk);
   return modified;
 }
 
 static int
-menu_set_notation (const char *string, KBNODE pub_keyblock,
-                  KBNODE sec_keyblock)
+menu_set_notation (const char *string, KBNODE pub_keyblock)
 {
-  PKT_secret_key *sk;          /* copy of the main sk */
   PKT_public_key *main_pk;
   PKT_user_id *uid;
   KBNODE node;
@@ -4533,16 +4282,16 @@ menu_set_notation (const char *string, KBNODE pub_keyblock,
     {
       answer = cpr_get_utf8 ("keyedit.add_notation",
                             _("Enter the notation: "));
-      if (answer[0] == '\0' || answer[0] == '\004')
+      if (answer[0] == '\0' || answer[0] == CONTROL_D)
        {
          xfree (answer);
          return 0;
        }
     }
 
-  if (ascii_strcasecmp (answer, "none") == 0
-      || ascii_strcasecmp (answer, "-") == 0)
-    notation = NULL;           /* delete them all */
+  if (!ascii_strcasecmp (answer, "none")
+      || !ascii_strcasecmp (answer, "-"))
+    notation = NULL; /* Delete them all.  */
   else
     {
       notation = string_to_notation (answer, 0);
@@ -4557,9 +4306,6 @@ menu_set_notation (const char *string, KBNODE pub_keyblock,
 
   select_all = !count_selected_uids (pub_keyblock);
 
-  node = find_kbnode (sec_keyblock, PKT_SECRET_KEY);
-  sk = copy_secret_key (NULL, node->pkt->pkt.secret_key);
-
   /* Now we can actually change the self signature(s) */
   main_pk = NULL;
   uid = NULL;
@@ -4567,7 +4313,7 @@ menu_set_notation (const char *string, KBNODE pub_keyblock,
   for (node = pub_keyblock; node; node = node->next)
     {
       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-       break;                  /* ready */
+       break; /* ready */
 
       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
        {
@@ -4668,7 +4414,7 @@ menu_set_notation (const char *string, KBNODE pub_keyblock,
                        tty_printf ("Adding notation: %s=%s\n",
                                    notation->name, notation->value);
 
-                     /* We tried to delete, but had no matches */
+                     /* We tried to delete, but had no matches */
                      if (notation->flags.ignore && !deleting)
                        continue;
                    }
@@ -4687,13 +4433,12 @@ menu_set_notation (const char *string, KBNODE pub_keyblock,
 
                  rc = update_keysig_packet (&newsig, sig,
                                             main_pk, uid, NULL,
-                                            sk,
+                                            main_pk,
                                             keygen_add_notations, notation);
                  if (rc)
                    {
                      log_error ("update_keysig_packet failed: %s\n",
                                 g10_errstr (rc));
-                     free_secret_key (sk);
                      free_notation (notation);
                      xfree (user);
                      return 0;
@@ -4722,7 +4467,6 @@ menu_set_notation (const char *string, KBNODE pub_keyblock,
     }
 
   free_notation (notation);
-  free_secret_key (sk);
   return modified;
 }
 
@@ -4823,7 +4567,8 @@ menu_select_uid_namehash (KBNODE keyblock, const char *namehash)
   return 1;
 }
 
-/****************
+
+/*
  * Select secondary keys
  * Returns: True if the selection changed.
  */
@@ -4892,6 +4637,7 @@ count_uids_with_flag (KBNODE keyblock, unsigned flag)
   return i;
 }
 
+
 static int
 count_keys_with_flag (KBNODE keyblock, unsigned flag)
 {
@@ -4905,6 +4651,7 @@ count_keys_with_flag (KBNODE keyblock, unsigned flag)
   return i;
 }
 
+
 static int
 count_uids (KBNODE keyblock)
 {
@@ -4918,7 +4665,7 @@ count_uids (KBNODE keyblock)
 }
 
 
-/****************
+/*
  * Returns true if there is at least one selected user id
  */
 static int
@@ -4927,13 +4674,15 @@ count_selected_uids (KBNODE keyblock)
   return count_uids_with_flag (keyblock, NODFLG_SELUID);
 }
 
+
 static int
 count_selected_keys (KBNODE keyblock)
 {
   return count_keys_with_flag (keyblock, NODFLG_SELKEY);
 }
 
-/* returns how many real (i.e. not attribute) uids are unmarked */
+
+/* Returns how many real (i.e. not attribute) uids are unmarked.  */
 static int
 real_uids_left (KBNODE keyblock)
 {
@@ -4948,6 +4697,7 @@ real_uids_left (KBNODE keyblock)
   return real;
 }
 
+
 /*
  * Ask whether the signature should be revoked.  If the user commits this,
  * flag bit MARK_A is set on the signature and the user ID.
@@ -4999,14 +4749,14 @@ ask_revoke_sig (KBNODE keyblock, KBNODE node)
       tty_printf (_("This signature expired on %s.\n"),
                  expirestr_from_sig (sig));
       /* Use a different question so we can have different help text */
-      doit = cpr_get_answer_is_yes ("ask_revoke_sig.expired",
-                                   _
-                                   ("Are you sure you still want to revoke it? (y/N) "));
+      doit = cpr_get_answer_is_yes
+        ("ask_revoke_sig.expired",
+         _("Are you sure you still want to revoke it? (y/N) "));
     }
   else
-    doit = cpr_get_answer_is_yes ("ask_revoke_sig.one",
-                                 _
-                                 ("Create a revocation certificate for this signature? (y/N) "));
+    doit = cpr_get_answer_is_yes
+      ("ask_revoke_sig.one",
+       _("Create a revocation certificate for this signature? (y/N) "));
 
   if (doit)
     {
@@ -5015,7 +4765,8 @@ ask_revoke_sig (KBNODE keyblock, KBNODE node)
     }
 }
 
-/****************
+
+/*
  * Display all user ids of the current public key together with signatures
  * done by one of our keys.  Then walk over all this sigs and ask the user
  * whether he wants to revoke this signature.
@@ -5047,7 +4798,7 @@ menu_revsig (KBNODE keyblock)
        }
       else if (!skip && node->pkt->pkttype == PKT_SIGNATURE
               && ((sig = node->pkt->pkt.signature),
-                  !seckey_available (sig->keyid)))
+                  have_secret_key_with_kid (sig->keyid)))
        {
          if ((sig->sig_class & ~3) == 0x10)
            {
@@ -5086,7 +4837,7 @@ menu_revsig (KBNODE keyblock)
        }
       else if (!skip && node->pkt->pkttype == PKT_SIGNATURE
               && ((sig = node->pkt->pkt.signature),
-                  !seckey_available (sig->keyid)))
+                  have_secret_key_with_kid (sig->keyid)))
        {
          if ((sig->sig_class & ~3) == 0x10)
            {
@@ -5147,9 +4898,9 @@ menu_revsig (KBNODE keyblock)
   if (!any)
     return 0;                  /* none selected */
 
-  if (!cpr_get_answer_is_yes ("ask_revoke_sig.okay",
-                             _
-                             ("Really create the revocation certificates? (y/N) ")))
+  if (!cpr_get_answer_is_yes
+      ("ask_revoke_sig.okay",
+       _("Really create the revocation certificates? (y/N) ")))
     return 0;                  /* forget it */
 
   reason = ask_revocation_reason (0, 1, 0);
@@ -5166,7 +4917,7 @@ reloop:                   /* (must use this, because we are modifing the list) */
       KBNODE unode;
       PACKET *pkt;
       struct sign_attrib attrib;
-      PKT_secret_key *sk;
+      PKT_public_key *signerkey;
 
       if (!(node->flag & NODFLG_MARK_A)
          || node->pkt->pkttype != PKT_SIGNATURE)
@@ -5179,17 +4930,18 @@ reloop:                 /* (must use this, because we are modifing the list) */
       attrib.non_exportable = !node->pkt->pkt.signature->flags.exportable;
 
       node->flag &= ~NODFLG_MARK_A;
-      sk = xmalloc_secure_clear (sizeof *sk);
-      if (get_seckey (sk, node->pkt->pkt.signature->keyid))
+      signerkey = xmalloc_secure_clear (sizeof *signerkey);
+      if (get_seckey (signerkey, node->pkt->pkt.signature->keyid))
        {
          log_info (_("no secret key\n"));
+          free_public_key (signerkey);
          continue;
        }
       rc = make_keysig_packet (&sig, primary_pk,
                               unode->pkt->pkt.user_id,
-                              NULL,
-                              sk, 0x30, 0, 0, 0, 0, sign_mk_attrib, &attrib);
-      free_secret_key (sk);
+                              NULL, signerkey, 0x30, 0, 0, 0, 0,
+                               sign_mk_attrib, &attrib, NULL);
+      free_public_key (signerkey);
       if (rc)
        {
          log_error (_("signing failed: %s\n"), g10_errstr (rc));
@@ -5213,14 +4965,13 @@ reloop:                 /* (must use this, because we are modifing the list) */
   return changed;
 }
 
+
 /* Revoke a user ID (i.e. revoke a user ID selfsig).  Return true if
-   keyblock changed. */
+   keyblock changed.  */
 static int
-menu_revuid (KBNODE pub_keyblock, KBNODE sec_keyblock)
+menu_revuid (KBNODE pub_keyblock)
 {
   PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
-  PKT_secret_key *sk = copy_secret_key (NULL,
-                                       sec_keyblock->pkt->pkt.secret_key);
   KBNODE node;
   int changed = 0;
   int rc;
@@ -5241,7 +4992,7 @@ menu_revuid (KBNODE pub_keyblock, KBNODE sec_keyblock)
          goto leave;
       }
 
-reloop:                        /* (better this way because we are modifing the keyring) */
+ reloop: /* (better this way because we are modifing the keyring) */
   for (node = pub_keyblock; node; node = node->next)
     if (node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
       {
@@ -5279,9 +5030,9 @@ reloop:                   /* (better this way because we are modifing the keyring) */
 
            node->flag &= ~NODFLG_SELUID;
 
-           rc = make_keysig_packet (&sig, pk, uid, NULL, sk, 0x30, 0,
+           rc = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x30, 0,
                                     (reason == NULL) ? 3 : 0, timestamp, 0,
-                                    sign_mk_attrib, &attrib);
+                                    sign_mk_attrib, &attrib, NULL);
            if (rc)
              {
                log_error (_("signing failed: %s\n"), g10_errstr (rc));
@@ -5294,12 +5045,14 @@ reloop:                 /* (better this way because we are modifing the keyring) */
                pkt->pkt.signature = sig;
                insert_kbnode (node, new_kbnode (pkt), 0);
 
+#ifndef NO_TRUST_MODELS
                /* If the trustdb has an entry for this key+uid then the
                   trustdb needs an update. */
                if (!update_trust
                    && (get_validity (pk, uid) & TRUST_MASK) >=
                    TRUST_UNDEFINED)
                  update_trust = 1;
+#endif /*!NO_TRUST_MODELS*/
 
                changed = 1;
                node->pkt->pkt.user_id->is_revoked = 1;
@@ -5313,25 +5066,24 @@ reloop:                 /* (better this way because we are modifing the keyring) */
     commit_kbnode (&pub_keyblock);
 
 leave:
-  free_secret_key (sk);
   release_revocation_reason_info (reason);
   return changed;
 }
 
-/****************
+
+/*
  * Revoke the whole key.
  */
 static int
-menu_revkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
+menu_revkey (KBNODE pub_keyblock)
 {
   PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
-  PKT_secret_key *sk;
   int rc, changed = 0;
   struct revocation_reason_info *reason;
   PACKET *pkt;
   PKT_signature *sig;
 
-  if (pk->is_revoked)
+  if (pk->flags.revoked)
     {
       tty_printf (_("Key %s is already revoked.\n"), keystr_from_pk (pk));
       return 0;
@@ -5342,11 +5094,9 @@ menu_revkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
   if (!reason)
     return 0;
 
-  sk = copy_secret_key (NULL, sec_keyblock->pkt->pkt.secret_key);
-  rc = make_keysig_packet (&sig, pk, NULL, NULL, sk,
+  rc = make_keysig_packet (&sig, pk, NULL, NULL, pk,
                           0x20, 0, opt.force_v4_certs ? 4 : 0, 0, 0,
-                          revocation_reason_build_cb, reason);
-  free_secret_key (sk);
+                          revocation_reason_build_cb, reason, NULL);
   if (rc)
     {
       log_error (_("signing failed: %s\n"), g10_errstr (rc));
@@ -5363,13 +5113,14 @@ menu_revkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
 
   update_trust = 1;
 
-scram:
+ scram:
   release_revocation_reason_info (reason);
   return changed;
 }
 
+
 static int
-menu_revsubkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
+menu_revsubkey (KBNODE pub_keyblock)
 {
   PKT_public_key *mainpk;
   KBNODE node;
@@ -5379,11 +5130,9 @@ menu_revsubkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
 
   reason = ask_revocation_reason (1, 0, 0);
   if (!reason)
-    {                          /* user decided to cancel */
-      return 0;
-    }
+      return 0; /* User decided to cancel.  */
 
-reloop:                        /* (better this way because we are modifing the keyring) */
+ reloop: /* (better this way because we are modifing the keyring) */
   mainpk = pub_keyblock->pkt->pkt.public_key;
   for (node = pub_keyblock; node; node = node->next)
     {
@@ -5392,11 +5141,10 @@ reloop:                 /* (better this way because we are modifing the keyring) */
        {
          PACKET *pkt;
          PKT_signature *sig;
-         PKT_secret_key *sk;
          PKT_public_key *subpk = node->pkt->pkt.public_key;
          struct sign_attrib attrib;
 
-         if (subpk->is_revoked)
+         if (subpk->flags.revoked)
            {
              tty_printf (_("Subkey %s is already revoked.\n"),
                          keystr_from_pk (subpk));
@@ -5407,10 +5155,9 @@ reloop:                  /* (better this way because we are modifing the keyring) */
          attrib.reason = reason;
 
          node->flag &= ~NODFLG_SELKEY;
-         sk = copy_secret_key (NULL, sec_keyblock->pkt->pkt.secret_key);
-         rc = make_keysig_packet (&sig, mainpk, NULL, subpk, sk,
-                                  0x28, 0, 0, 0, 0, sign_mk_attrib, &attrib);
-         free_secret_key (sk);
+         rc = make_keysig_packet (&sig, mainpk, NULL, subpk, mainpk,
+                                  0x28, 0, 0, 0, 0, sign_mk_attrib, &attrib,
+                                   NULL);
          if (rc)
            {
              log_error (_("signing failed: %s\n"), g10_errstr (rc));
@@ -5427,7 +5174,6 @@ reloop:                   /* (better this way because we are modifing the keyring) */
        }
     }
   commit_kbnode (&pub_keyblock);
-  /*commit_kbnode( &sec_keyblock ); */
 
   /* No need to set update_trust here since signing keys no longer
      are used to certify other keys, so there is no change in trust
@@ -5437,10 +5183,12 @@ reloop:                 /* (better this way because we are modifing the keyring) */
   return changed;
 }
 
+
 /* Note that update_ownertrust is going to mark the trustdb dirty when
    enabling or disabling a key.  This is arguably sub-optimal as
    disabled keys are still counted in the web of trust, but perhaps
    not worth adding extra complexity to change. -ds */
+#ifndef NO_TRUST_MODELS
 static int
 enable_disable_key (KBNODE keyblock, int disable)
 {
@@ -5457,6 +5205,7 @@ enable_disable_key (KBNODE keyblock, int disable)
   update_ownertrust (pk, newtrust);
   return 0;
 }
+#endif /*!NO_TRUST_MODELS*/
 
 
 static void
@@ -5497,7 +5246,7 @@ menu_showphoto (KBNODE keyblock)
                                    "key %s (uid %d)\n"),
                                  image_type_to_string (type, 1),
                                  (ulong) size, keystr_from_pk (pk), count);
-                     show_photos (&uid->attribs[i], 1, pk, NULL, uid);
+                     show_photos (&uid->attribs[i], 1, pk, uid);
                    }
                }
            }